3 * Copyright (C) James R. Leu 2000
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
10 #include "ldp_struct.h"
11 #include "ldp_label_mapping.h"
14 #include "ldp_global.h"
15 #include "ldp_inlabel.h"
16 #include "ldp_outlabel.h"
17 #include "ldp_session.h"
18 #include "mpls_refcnt.h"
19 #include "mpls_mm_impl.h"
20 #include "mpls_tree_impl.h"
21 #include "mpls_trace_impl.h"
26 #include "mpls_mpls_impl.h"
29 static ldp_fec
*_ldp_attr_get_fec(ldp_global
* g
, ldp_attr
* a
, mpls_bool flag
);
30 static ldp_fs
*_ldp_fec_add_fs_ds(ldp_fec
* fec
, ldp_session
* s
);
31 static ldp_fs
*_ldp_fec_add_fs_us(ldp_fec
* fec
, ldp_session
* s
);
32 static ldp_fs
*_ldp_fec_find_fs_us(ldp_fec
* fec
, ldp_session
* s
,
34 static ldp_fs
*_ldp_fec_find_fs_ds(ldp_fec
* fec
, ldp_session
* s
,
36 static void _ldp_fec_del_fs_us(ldp_fec
* fec
, ldp_fs
* fs
);
37 static void _ldp_fec_del_fs_ds(ldp_fec
* fec
, ldp_fs
* fs
);
38 static ldp_fs
*_ldp_fs_create(ldp_session
* s
);
39 static void _ldp_fs_delete(ldp_fs
* fs
);
40 static ldp_attr
*_ldp_fs_find_attr(ldp_fs
* fs
, ldp_attr
* a
);
41 static mpls_return_enum
_ldp_fs_add_attr(ldp_fs
* fs
, ldp_attr
* a
);
42 static mpls_bool
_ldp_fs_del_attr(ldp_fs
* fs
, ldp_attr
* a
);
43 static uint32_t _ldp_attr_get_next_index();
45 static uint32_t _ldp_attr_next_index
= 1;
47 int ldp_attr_num_us2ds(ldp_attr
* ds
)
49 ldp_attr
*attr
= NULL
;
52 attr
= MPLS_LIST_HEAD(&ds
->us_attr_root
);
55 attr
= MPLS_LIST_NEXT(&ds
->us_attr_root
, attr
, _ds_attr
);
60 mpls_bool
ldp_attr_us_partof_ds(ldp_attr
* us
, ldp_attr
* ds
)
62 if (us
->ds_attr
== ds
) {
63 return MPLS_BOOL_TRUE
;
65 return MPLS_BOOL_FALSE
;
68 void ldp_attr_del_us2ds(ldp_attr
* us
, ldp_attr
* ds
)
73 if (ldp_attr_us_partof_ds(us
, ds
) == MPLS_BOOL_TRUE
) {
75 MPLS_REFCNT_RELEASE(ds
, ldp_attr_delete
);
76 MPLS_LIST_REMOVE(&ds
->us_attr_root
, us
, _ds_attr
);
77 MPLS_REFCNT_RELEASE(us
, ldp_attr_delete
);
83 void ldp_attr_add_fec(ldp_attr
*a
, ldp_fec
*fec
) {
84 MPLS_ASSERT(a
&& fec
);
85 MPLS_REFCNT_HOLD(fec
);
89 void ldp_attr_del_fec(ldp_attr
*a
) {
92 MPLS_REFCNT_RELEASE(a
->fec
, ldp_fec_delete
);
97 void ldp_attr_add_us2ds(ldp_attr
* us
, ldp_attr
* ds
)
103 if (ldp_attr_us_partof_ds(us
, ds
) == MPLS_BOOL_TRUE
) {
106 MPLS_REFCNT_HOLD(us
);
107 MPLS_LIST_ADD_TAIL(&ds
->us_attr_root
, us
, _ds_attr
, ldp_attr
);
108 MPLS_REFCNT_HOLD(ds
);
112 void ldp_attr_action_callback(mpls_timer_handle timer
, void *extra
,
117 ldp_attr
*ldp_attr_find_downstream_state_any(ldp_global
* g
, mpls_fec
* f
,
120 ldp_fec
*fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
);
121 ldp_attr
*attr
= NULL
;
128 fs
= MPLS_LIST_HEAD(&fnode
->fs_root_ds
);
130 attr
= MPLS_LIST_HEAD(&fs
->attr_root
);
131 while (attr
!= NULL
) {
132 if (attr
->state
== state
) {
135 attr
= MPLS_LIST_NEXT(&fs
->attr_root
, attr
, _fs
);
137 fs
= MPLS_LIST_NEXT(&fnode
->fs_root_ds
, fs
, _fec
);
142 ldp_attr
*ldp_attr_find_upstream_state_any(ldp_global
* g
, mpls_fec
* f
,
145 ldp_fec
*fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
);
146 ldp_attr
*attr
= NULL
;
153 fs
= MPLS_LIST_HEAD(&fnode
->fs_root_us
);
155 attr
= MPLS_LIST_HEAD(&fs
->attr_root
);
156 while (attr
!= NULL
) {
157 if (attr
->state
== state
) {
160 attr
= MPLS_LIST_NEXT(&fs
->attr_root
, attr
, _fs
);
162 fs
= MPLS_LIST_NEXT(&fnode
->fs_root_us
, fs
, _fec
);
167 ldp_attr
*ldp_attr_find_downstream_state(ldp_global
* g
, ldp_session
* s
,
168 mpls_fec
* f
, ldp_lsp_state state
)
170 ldp_attr_list
*ds_list
= ldp_attr_find_downstream_all(g
, s
, f
);
172 if (ds_list
!= NULL
) {
173 ldp_attr
*ds_attr
= MPLS_LIST_HEAD(ds_list
);
175 while (ds_attr
!= NULL
) {
176 if (ds_attr
->state
== state
) {
179 ds_attr
= MPLS_LIST_NEXT(ds_list
, ds_attr
, _fs
);
185 ldp_attr
*ldp_attr_find_upstream_state(ldp_global
* g
, ldp_session
* s
,
186 mpls_fec
* f
, ldp_lsp_state state
)
188 ldp_attr_list
*us_list
= ldp_attr_find_upstream_all(g
, s
, f
);
190 if (us_list
!= NULL
) {
191 ldp_attr
*us_attr
= MPLS_LIST_HEAD(us_list
);
193 while (us_attr
!= NULL
) {
194 if (us_attr
->state
== state
) {
197 us_attr
= MPLS_LIST_NEXT(us_list
, us_attr
, _fs
);
203 void ldp_attr_remove_complete(ldp_global
* g
, ldp_attr
* attr
,
206 ldp_session
*session
= attr
->session
;
207 ldp_outlabel
*out
= NULL
;
208 ldp_inlabel
*in
= NULL
;
209 ldp_attr
*us_temp
= NULL
;
213 switch (attr
->state
) {
214 case LDP_LSP_STATE_MAP_RECV
:
215 if (attr
->ingress
== MPLS_BOOL_TRUE
) {
216 out
= attr
->outlabel
;
217 MPLS_ASSERT(out
!= NULL
);
218 while ((in
= MPLS_LIST_HEAD(&out
->inlabel_root
)) != NULL
) {
219 ldp_inlabel_del_outlabel(g
, in
);
222 if (out
->merge_count
> 0) {
223 for (i
= 0; i
< attr
->fecTlv
.numberFecElements
; i
++) {
224 fec_tlv2mpls_fec(&attr
->fecTlv
, i
, &fec
);
229 memcpy(&ftn
.fec
, &fec
, sizeof(mpls_fec
));
230 ftn
.outsegment_index
= out
->info
.handle
;
231 lsr_cfg_ftn_set2(g
->lsr_handle
, &ftn
, LSR_CFG_DEL
);
234 mpls_mpls_fec2out_del(g
->mpls_handle
, &fec
, &out
->info
);
238 MPLS_ASSERT(out
->merge_count
== 0);
239 ldp_attr_del_outlabel(attr
);
240 ldp_session_del_outlabel(session
, out
);
241 _ldp_global_del_outlabel(g
, out
);
243 while ((us_temp
= MPLS_LIST_HEAD(&attr
->us_attr_root
)) != NULL
) {
244 ldp_attr_del_us2ds(us_temp
, attr
);
246 ldp_attr_delete_downstream(g
, session
, attr
);
248 case LDP_LSP_STATE_MAP_SENT
:
253 if (in
->reuse_count
== 1) {
254 ldp_inlabel_del_outlabel(g
, in
);
258 ldp_attr_del_inlabel(attr
);
259 ldp_attr_delete_upstream(g
, session
, attr
);
260 ldp_attr_del_us2ds(attr
, attr
->ds_attr
);
261 ldp_session_del_inlabel(session
, in
);
263 if (in
->reuse_count
== 0) {
264 _ldp_global_del_inlabel(g
, in
);
267 case LDP_LSP_STATE_ABORT_SENT
:
268 case LDP_LSP_STATE_NOTIF_SENT
:
269 case LDP_LSP_STATE_REQ_RECV
:
270 case LDP_LSP_STATE_WITH_SENT
:
271 case LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT
:
273 ldp_attr_del_us2ds(attr
, attr
->ds_attr
);
274 ldp_attr_delete_upstream(g
, session
, attr
);
277 case LDP_LSP_STATE_ABORT_RECV
:
278 case LDP_LSP_STATE_NOTIF_RECV
:
279 case LDP_LSP_STATE_REQ_SENT
:
280 case LDP_LSP_STATE_WITH_RECV
:
281 case LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV
:
283 while ((us_temp
= MPLS_LIST_HEAD(&attr
->us_attr_root
)) != NULL
) {
284 ldp_attr_del_us2ds(us_temp
, attr
);
286 ldp_attr_delete_downstream(g
, session
, attr
);
292 ldp_attr
*ldp_attr_create(mpls_fec
* fec
)
294 ldp_attr
*a
= (ldp_attr
*) mpls_malloc(sizeof(ldp_attr
));
297 memset(a
, 0, sizeof(ldp_attr
));
298 MPLS_LIST_ELEM_INIT(a
, _session
);
299 MPLS_LIST_ELEM_INIT(a
, _global
);
300 MPLS_LIST_ELEM_INIT(a
, _fs
);
301 MPLS_LIST_INIT(&a
->us_attr_root
, ldp_attr
);
302 MPLS_REFCNT_INIT(a
, 0);
303 a
->index
= _ldp_attr_get_next_index();
304 a
->in_tree
= MPLS_BOOL_FALSE
;
305 a
->ingress
= MPLS_BOOL_FALSE
;
306 a
->filtered
= MPLS_BOOL_FALSE
;
309 mpls_fec2fec_tlv(fec
, &a
->fecTlv
, 0);
310 a
->fecTlv
.numberFecElements
= 1;
317 void ldp_attr_delete(ldp_attr
* a
)
319 LDP_PRINT(g
->user_data
,"attr delete\n");
320 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_FALSE
);
324 void ldp_attr2ldp_attr(ldp_attr
* a
, ldp_attr
* b
, uint32_t flag
)
326 if (a
->fecTlvExists
&& flag
& LDP_ATTR_FEC
) {
327 memcpy(&b
->fecTlv
, &a
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
330 if (a
->genLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
331 memcpy(&b
->genLblTlv
, &a
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
332 b
->genLblTlvExists
= 1;
333 } else if (a
->atmLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
334 memcpy(&b
->atmLblTlv
, &a
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
335 b
->atmLblTlvExists
= 1;
336 } else if (a
->frLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
337 memcpy(&b
->frLblTlv
, &a
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
338 b
->frLblTlvExists
= 1;
340 if (a
->hopCountTlvExists
&& flag
& LDP_ATTR_HOPCOUNT
) {
341 memcpy(&b
->hopCountTlv
, &a
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
342 b
->hopCountTlvExists
= 1;
344 if (a
->pathVecTlvExists
&& flag
& LDP_ATTR_PATH
) {
345 memcpy(&b
->pathVecTlv
, &a
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
346 b
->pathVecTlvExists
= 1;
348 if (a
->lblMsgIdTlvExists
&& flag
& LDP_ATTR_MSGID
) {
349 memcpy(&b
->lblMsgIdTlv
, &a
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
350 b
->lblMsgIdTlvExists
= 1;
352 if (a
->lspidTlvExists
&& flag
& LDP_ATTR_LSPID
) {
353 memcpy(&b
->lspidTlv
, &a
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
354 b
->lspidTlvExists
= 1;
356 if (a
->trafficTlvExists
&& flag
& LDP_ATTR_TRAFFIC
) {
357 memcpy(&b
->trafficTlv
, &a
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
358 b
->trafficTlvExists
= 1;
362 mpls_return_enum
ldp_attr_add_inlabel(ldp_attr
* a
, ldp_inlabel
* i
)
367 _ldp_inlabel_add_attr(i
, a
);
373 mpls_return_enum
ldp_attr_del_inlabel(ldp_attr
* a
)
375 if (a
&& a
->inlabel
) {
376 _ldp_inlabel_del_attr(a
->inlabel
, a
);
377 MPLS_REFCNT_RELEASE(a
->inlabel
, ldp_inlabel_delete
);
384 mpls_return_enum
ldp_attr_add_outlabel(ldp_attr
* a
, ldp_outlabel
* o
)
389 _ldp_outlabel_add_attr(o
, a
);
395 mpls_return_enum
ldp_attr_del_outlabel(ldp_attr
* a
)
397 if (a
&& a
->outlabel
) {
398 _ldp_outlabel_del_attr(a
->outlabel
);
399 MPLS_REFCNT_RELEASE(a
->outlabel
, ldp_outlabel_delete
);
406 mpls_return_enum
ldp_attr_add_session(ldp_attr
* a
, ldp_session
* s
)
411 _ldp_session_add_attr(s
, a
);
417 mpls_return_enum
ldp_attr_del_session(ldp_attr
* a
)
419 if (a
&& a
->session
) {
420 _ldp_session_del_attr(a
->session
, a
);
421 MPLS_REFCNT_RELEASE(a
->session
, ldp_session_delete
);
428 mpls_bool
ldp_attr_is_equal(ldp_attr
* a
, ldp_attr
* b
, uint32_t flag
)
430 if (flag
& LDP_ATTR_LABEL
) {
431 if (a
->genLblTlvExists
&& b
->genLblTlvExists
) {
432 if (a
->genLblTlv
.label
!= b
->genLblTlv
.label
) {
433 return MPLS_BOOL_FALSE
;
435 } else if (a
->atmLblTlvExists
&& b
->atmLblTlvExists
) {
436 if (a
->atmLblTlv
.flags
.flags
.vpi
!= b
->atmLblTlv
.flags
.flags
.vpi
||
437 a
->atmLblTlv
.vci
!= b
->atmLblTlv
.vci
) {
438 return MPLS_BOOL_FALSE
;
440 } else if (a
->frLblTlvExists
&& b
->frLblTlvExists
) {
441 if (a
->frLblTlv
.flags
.flags
.len
!= b
->frLblTlv
.flags
.flags
.len
||
442 a
->frLblTlv
.flags
.flags
.dlci
!= b
->frLblTlv
.flags
.flags
.dlci
) {
443 return MPLS_BOOL_FALSE
;
446 return MPLS_BOOL_FALSE
;
449 if (flag
& LDP_ATTR_HOPCOUNT
) {
450 if (a
->hopCountTlvExists
&& b
->hopCountTlvExists
) {
451 if (a
->hopCountTlv
.hcValue
!= b
->hopCountTlv
.hcValue
) {
452 return MPLS_BOOL_FALSE
;
455 if (a
->hopCountTlvExists
!= b
->hopCountTlvExists
) {
456 return MPLS_BOOL_FALSE
;
460 if (flag
& LDP_ATTR_PATH
) {
463 if (a
->pathVecTlvExists
&& b
->pathVecTlvExists
) {
464 for (i
= 0; i
< MPLS_MAXHOPSNUMBER
; i
++) {
465 if (a
->pathVecTlv
.lsrId
[i
] != b
->pathVecTlv
.lsrId
[i
]) {
466 return MPLS_BOOL_FALSE
;
470 if (a
->hopCountTlvExists
!= b
->hopCountTlvExists
) {
471 return MPLS_BOOL_FALSE
;
475 if (flag
& LDP_ATTR_FEC
) {
478 if (a
->fecTlvExists
&& b
->fecTlvExists
) {
479 if (a
->fecTlv
.numberFecElements
!= b
->fecTlv
.numberFecElements
) {
480 return MPLS_BOOL_FALSE
;
482 for (i
= 0; i
< a
->fecTlv
.numberFecElements
; i
++) {
483 if (a
->fecTlv
.fecElemTypes
[i
] != b
->fecTlv
.fecElemTypes
[i
]) {
484 return MPLS_BOOL_FALSE
;
486 switch (a
->fecTlv
.fecElemTypes
[i
]) {
489 /* nothing of interest to compare */
491 case MPLS_PREFIX_FEC
:
492 case MPLS_HOSTADR_FEC
:
493 if (a
->fecTlv
.fecElArray
[i
].addressEl
.addressFam
!=
494 b
->fecTlv
.fecElArray
[i
].addressEl
.addressFam
||
495 a
->fecTlv
.fecElArray
[i
].addressEl
.preLen
!=
496 b
->fecTlv
.fecElArray
[i
].addressEl
.preLen
||
497 a
->fecTlv
.fecElArray
[i
].addressEl
.address
!=
498 b
->fecTlv
.fecElArray
[i
].addressEl
.address
) {
499 return MPLS_BOOL_FALSE
;
507 return MPLS_BOOL_FALSE
;
510 if (flag
& LDP_ATTR_MSGID
) {
511 if (a
->lblMsgIdTlvExists
&& b
->lblMsgIdTlvExists
) {
512 if (a
->lblMsgIdTlv
.msgId
!= b
->lblMsgIdTlv
.msgId
) {
513 return MPLS_BOOL_FALSE
;
516 return MPLS_BOOL_FALSE
;
519 if (flag
& LDP_ATTR_LSPID
) {
520 if (a
->lspidTlvExists
&& b
->lspidTlvExists
) {
521 if (a
->lspidTlv
.localCrlspId
!= b
->lspidTlv
.localCrlspId
||
522 a
->lspidTlv
.routerId
!= b
->lspidTlv
.routerId
) {
523 return MPLS_BOOL_FALSE
;
526 return MPLS_BOOL_FALSE
;
529 if (flag
& LDP_ATTR_TRAFFIC
) {
531 return MPLS_BOOL_TRUE
;
534 mpls_return_enum
ldp_attr_insert_upstream(ldp_global
* g
, ldp_session
* s
,
537 ldp_fec
*fnode
= NULL
;
539 mpls_return_enum retval
;
541 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_FALSE
);
543 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_TRUE
)) == NULL
) {
544 /* we couldn't get/add a node from/to the tree! */
548 /* find the upstream fs for this session */
549 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_TRUE
)) == NULL
) {
550 /* this session isn't in the list and cannot be added */
554 ldp_attr_add_session(a
, s
);
555 ldp_attr_add_fec(a
, fnode
);
557 retval
= _ldp_fs_add_attr(fs
, a
);
558 _ldp_global_add_attr(g
, a
);
559 a
->in_tree
= MPLS_BOOL_TRUE
;
563 mpls_return_enum
ldp_attr_insert_downstream(ldp_global
* g
, ldp_session
* s
,
566 ldp_fec
*fnode
= NULL
;
568 mpls_return_enum retval
;
570 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_FALSE
);
572 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_TRUE
)) == NULL
) {
573 /* we couldn't get/add a node from/to the tree! */
577 /* find the downstream fs for this session */
578 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_TRUE
)) == NULL
) {
579 /* this session isn't in the list and cannot be added */
583 ldp_attr_add_session(a
, s
);
584 ldp_attr_add_fec(a
, fnode
);
586 retval
= _ldp_fs_add_attr(fs
, a
);
587 _ldp_global_add_attr(g
, a
);
588 a
->in_tree
= MPLS_BOOL_TRUE
;
592 ldp_attr_list
*ldp_attr_find_upstream_all(ldp_global
* g
, ldp_session
* s
,
595 ldp_fec
*fnode
= NULL
;
598 MPLS_ASSERT(s
&& f
&& g
);
600 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
601 /* we couldn't get the node from the tree! */
605 /* find the upstream fs for this session */
606 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
607 /* this session isn't in the list */
610 return &fs
->attr_root
;
613 ldp_attr_list
*ldp_attr_find_downstream_all(ldp_global
* g
, ldp_session
* s
,
616 ldp_fec
*fnode
= NULL
;
619 MPLS_ASSERT(s
&& f
&& g
);
621 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
622 /* we couldn't get the node from the tree! */
626 /* find the downstream fs for this session */
627 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
628 /* this session isn't in the list */
631 return &fs
->attr_root
;
634 void ldp_attr_delete_upstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
636 ldp_fec
*fnode
= NULL
;
639 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
641 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
)) == NULL
) {
642 /* we couldn't get the node from the tree! */
646 /* find the upstream fs for this session */
647 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
648 /* this session isn't in the list */
652 ldp_attr_del_session(a
);
655 if (_ldp_fs_del_attr(fs
, a
) == MPLS_BOOL_TRUE
) {
656 _ldp_fec_del_fs_us(fnode
, fs
);
658 a
->in_tree
= MPLS_BOOL_FALSE
;
659 _ldp_global_del_attr(g
, a
);
662 void ldp_attr_delete_downstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
664 ldp_fec
*fnode
= NULL
;
667 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
669 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
)) == NULL
) {
670 /* we couldn't get the node from the tree! */
674 /* find the downstream fs for this session */
675 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
676 /* this session isn't in the list */
680 ldp_attr_del_session(a
);
683 if (_ldp_fs_del_attr(fs
, a
) == MPLS_BOOL_TRUE
) {
684 _ldp_fec_del_fs_ds(fnode
, fs
);
686 a
->in_tree
= MPLS_BOOL_FALSE
;
687 _ldp_global_del_attr(g
, a
);
690 void ldp_attr2mpls_label_struct(ldp_attr
* a
, mpls_label_struct
* l
)
692 if (a
->genLblTlvExists
) {
693 l
->type
= MPLS_LABEL_TYPE_GENERIC
;
694 l
->u
.gen
= a
->genLblTlv
.label
;
695 } else if (a
->atmLblTlvExists
) {
696 l
->type
= MPLS_LABEL_TYPE_ATM
;
697 l
->u
.atm
.vpi
= a
->atmLblTlv
.flags
.flags
.vpi
;
698 l
->u
.atm
.vci
= a
->atmLblTlv
.vci
;
699 } else if (a
->frLblTlvExists
) {
700 l
->type
= MPLS_LABEL_TYPE_FR
;
701 l
->u
.fr
.len
= a
->frLblTlv
.flags
.flags
.len
;
702 l
->u
.fr
.dlci
= a
->frLblTlv
.flags
.flags
.dlci
;
708 void mpls_label_struct2ldp_attr(mpls_label_struct
* l
, ldp_attr
* a
)
711 case MPLS_LABEL_TYPE_GENERIC
:
712 a
->genLblTlvExists
= 1;
713 a
->atmLblTlvExists
= 0;
714 a
->frLblTlvExists
= 0;
715 a
->genLblTlv
.label
= l
->u
.gen
;
717 case MPLS_LABEL_TYPE_ATM
:
718 a
->genLblTlvExists
= 0;
719 a
->atmLblTlvExists
= 1;
720 a
->frLblTlvExists
= 0;
721 a
->atmLblTlv
.flags
.flags
.vpi
= l
->u
.atm
.vpi
;
722 a
->atmLblTlv
.vci
= l
->u
.atm
.vci
;
723 case MPLS_LABEL_TYPE_FR
:
724 a
->genLblTlvExists
= 0;
725 a
->atmLblTlvExists
= 0;
726 a
->frLblTlvExists
= 1;
727 a
->frLblTlv
.flags
.flags
.len
= l
->u
.fr
.len
;
728 a
->frLblTlv
.flags
.flags
.dlci
= l
->u
.fr
.dlci
;
735 void ldp_attr2ldp_attr(ldp_attr
* src
, ldp_attr
* dst
, u_int32 flag
)
737 if (flag
& LDP_ATTR_FEC
) {
738 memcpy(&dst
->fecTlv
, &src
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
739 dst
->fecTlvExists
= src
->fecTlvExists
;
741 if (flag
& LDP_ATTR_LABEL
) {
742 memcpy(&dst
->genLblTlv
, &src
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
743 memcpy(&dst
->atmLblTlv
, &src
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
744 memcpy(&dst
->frLblTlv
, &src
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
745 dst
->genLblTlvExists
= src
->genLblTlvExists
746 dst
->atmLblTlvExists
= src
->atmLblTlvExists
747 dst
->frLblTlvExists
= src
->frLblTlvExists
}
748 if (flag
& LDP_ATTR_HOPCOUNT
) {
749 memcpy(&dst
->hopCountTlv
, &src
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
750 dst
->hopCountTlvExists
= src
->hopCountTlvExists
;
752 if (flag
& LDP_ATTR_PATH
) {
753 memcpy(&dst
->pathVecTlv
, &src
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
754 dst
->pathVecTlvExists
= src
->pathVecTlvExists
;
756 if (flag
& LDP_ATTR_MSGID
) {
757 memcpy(&dst
->lblMsgIdTlv
, &src
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
758 dst
->lblMsgIdTlvExists
= src
->lblMsgIdTlvExists
;
760 if (flag
& LDP_ATTR_LSPID
) {
761 memcpy(&dst
->lspidTlv
, &src
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
762 dst
->lspidTlvExists
= src
->lspidTlvExists
;
764 if (flag
& LDP_ATTR_TRAFFIC
) {
765 memcpy(&dst
->trafficTlv
, &src
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
766 dst
->trafficTlvExists
= src
->trafficTlvExists
;
771 ldp_fec
*_ldp_attr_get_fec2(ldp_global
* g
, mpls_fec
* f
, mpls_bool flag
)
773 ldp_fec
*fnode
= NULL
;
778 case MPLS_FEC_PREFIX
:
779 key
= f
->u
.prefix
.network
.u
.ipv4
;
780 len
= f
->u
.prefix
.length
;
783 key
= f
->u
.host
.u
.ipv4
;
789 if (mpls_tree_get(g
->fec_tree
, key
, len
, (void **)&fnode
) ==
790 MPLS_FAILURE
|| fnode
== NULL
) {
792 if (flag
== MPLS_BOOL_FALSE
) {
796 /* this FEC doesn't exist in the tree yet, create one ... */
797 fnode
= ldp_fec_create();
798 mpls_fec2ldp_fec(f
, fnode
);
799 if (f
->nh
.type
& MPLS_NH_IP
) {
800 fnode
->nh
.addr
= NULL
;
801 mpls_tree_get(g
->addr_tree
, f
->nh
.ip
.u
.ipv4
, 32, (void**)&fnode
->nh
.addr
);
802 if (fnode
->nh
.addr
) {
803 fnode
->nh
.type
|= MPLS_NH_IP
;
806 if (f
->nh
.type
& MPLS_NH_IF
) {
807 fnode
->nh
.iff
= ldp_global_find_if_handle(g
, f
->nh
.if_handle
);
809 fnode
->nh
.type
|= MPLS_NH_IF
;
812 if (f
->nh
.type
& MPLS_NH_OUTSEGMENT
) {
813 fnode
->nh
.outlabel
= ldp_global_find_outlabel_handle(g
,
814 f
->nh
.outsegment_handle
);
815 if (fnode
->nh
.outlabel
) {
816 fnode
->nh
.type
|= MPLS_NH_OUTSEGMENT
;
819 MPLS_REFCNT_HOLD(fnode
);
821 /* ... add it to the tree ... */
822 if (mpls_tree_insert(g
->fec_tree
,key
,len
,(void *)fnode
) == MPLS_FAILURE
) {
823 /* insert failed, by releasing our refcnt it will be deleted */
824 MPLS_REFCNT_RELEASE(fnode
, ldp_fec_delete
);
831 static ldp_fec
*_ldp_attr_get_fec(ldp_global
* g
, ldp_attr
* a
, mpls_bool flag
)
835 /* get FEC from attr */
836 fec_tlv2mpls_fec(&a
->fecTlv
, 0, &fec
);
837 return _ldp_attr_get_fec2(g
, &fec
, flag
);
840 static ldp_fs
*_ldp_fec_add_fs_ds(ldp_fec
* fec
, ldp_session
* s
)
842 ldp_fs
*fs
= _ldp_fec_find_fs_ds(fec
, s
, MPLS_BOOL_FALSE
);
845 fs
= _ldp_fs_create(s
);
849 MPLS_LIST_ADD_HEAD(&fec
->fs_root_ds
, fs
, _fec
, ldp_fs
);
854 static ldp_fs
*_ldp_fec_add_fs_us(ldp_fec
* fec
, ldp_session
* s
)
856 ldp_fs
*fs
= _ldp_fec_find_fs_us(fec
, s
, MPLS_BOOL_FALSE
);
859 fs
= _ldp_fs_create(s
);
863 MPLS_LIST_ADD_HEAD(&fec
->fs_root_us
, fs
, _fec
, ldp_fs
);
868 static ldp_fs
*_ldp_fec_find_fs_us(ldp_fec
* fec
, ldp_session
* s
,
871 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_us
);
874 if (fs
->session
->index
== s
->index
) {
877 fs
= MPLS_LIST_NEXT(&fec
->fs_root_us
, fs
, _fec
);
879 if (flag
== MPLS_BOOL_FALSE
) {
882 return _ldp_fec_add_fs_us(fec
, s
);
885 static ldp_fs
*_ldp_fec_find_fs_ds(ldp_fec
* fec
, ldp_session
* s
,
888 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_ds
);
891 if (fs
->session
->index
== s
->index
) {
894 fs
= MPLS_LIST_NEXT(&fec
->fs_root_ds
, fs
, _fec
);
896 if (flag
== MPLS_BOOL_FALSE
) {
899 return _ldp_fec_add_fs_ds(fec
, s
);
902 static void _ldp_fec_del_fs_us(ldp_fec
* fec
, ldp_fs
* fs
)
907 MPLS_LIST_REMOVE(&fec
->fs_root_us
, fs
, _fec
);
911 static void _ldp_fec_del_fs_ds(ldp_fec
* fec
, ldp_fs
* fs
)
916 MPLS_LIST_REMOVE(&fec
->fs_root_ds
, fs
, _fec
);
920 static ldp_fs
*_ldp_fs_create(ldp_session
* s
)
922 ldp_fs
*fs
= (ldp_fs
*) mpls_malloc(sizeof(ldp_fs
));
925 memset(fs
, 0, sizeof(ldp_fs
));
926 MPLS_LIST_INIT(&fs
->attr_root
, ldp_attr
);
927 MPLS_LIST_ELEM_INIT(fs
, _fec
);
936 static void _ldp_fs_delete(ldp_fs
* fs
)
938 LDP_PRINT(g
->user_data
,"fs delete\n");
939 if (fs
->session
!= NULL
) {
940 MPLS_REFCNT_RELEASE(fs
->session
, ldp_session_delete
);
945 static ldp_attr
*_ldp_fs_find_attr(ldp_fs
* fs
, ldp_attr
* a
)
947 ldp_attr
*ptr
= MPLS_LIST_HEAD(&fs
->attr_root
);
949 while (ptr
!= NULL
) {
950 if (ldp_attr_is_equal(a
, ptr
, LDP_ATTR_LABEL
| LDP_ATTR_FEC
) == MPLS_BOOL_TRUE
) {
953 ptr
= MPLS_LIST_NEXT(&fs
->attr_root
, ptr
, _fs
);
958 static mpls_return_enum
_ldp_fs_add_attr(ldp_fs
* fs
, ldp_attr
* a
)
960 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
962 MPLS_ASSERT(ptr
== NULL
);
964 MPLS_LIST_ADD_HEAD(&fs
->attr_root
, a
, _fs
, ldp_attr
);
968 static mpls_bool
_ldp_fs_del_attr(ldp_fs
* fs
, ldp_attr
* a
)
970 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
973 MPLS_LIST_REMOVE(&fs
->attr_root
, ptr
, _fs
);
974 MPLS_REFCNT_RELEASE(ptr
, ldp_attr_delete
);
976 if (MPLS_LIST_HEAD(&fs
->attr_root
) == NULL
)
977 return MPLS_BOOL_TRUE
;
978 return MPLS_BOOL_FALSE
;
981 static uint32_t _ldp_attr_get_next_index()
983 uint32_t retval
= _ldp_attr_next_index
;
985 _ldp_attr_next_index
++;
986 if (retval
> _ldp_attr_next_index
) {
987 _ldp_attr_next_index
= 1;