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"
16 #include "ldp_global.h"
17 #include "ldp_inlabel.h"
18 #include "ldp_outlabel.h"
19 #include "ldp_session.h"
20 #include "mpls_refcnt.h"
21 #include "mpls_mm_impl.h"
22 #include "mpls_tree_impl.h"
23 #include "mpls_trace_impl.h"
28 #include "mpls_mpls_impl.h"
31 static ldp_fec
*_ldp_attr_get_fec2(ldp_global
* g
, mpls_fec
* f
, mpls_bool flag
);
32 static ldp_fec
*_ldp_attr_get_fec(ldp_global
* g
, ldp_attr
* a
, mpls_bool flag
);
33 static ldp_fs
*_ldp_fec_add_fs_ds(ldp_fec
* fec
, ldp_session
* s
);
34 static ldp_fs
*_ldp_fec_add_fs_us(ldp_fec
* fec
, ldp_session
* s
);
35 static ldp_fs
*_ldp_fec_find_fs_us(ldp_fec
* fec
, ldp_session
* s
,
37 static ldp_fs
*_ldp_fec_find_fs_ds(ldp_fec
* fec
, ldp_session
* s
,
39 static void _ldp_fec_del_fs_us(ldp_fec
* fec
, ldp_fs
* fs
);
40 static void _ldp_fec_del_fs_ds(ldp_fec
* fec
, ldp_fs
* fs
);
41 static ldp_fs
*_ldp_fs_create(ldp_session
* s
);
42 static void _ldp_fs_delete(ldp_fs
* fs
);
43 static ldp_attr
*_ldp_fs_find_attr(ldp_fs
* fs
, ldp_attr
* a
);
44 static mpls_return_enum
_ldp_fs_add_attr(ldp_fs
* fs
, ldp_attr
* a
);
45 static mpls_bool
_ldp_fs_del_attr(ldp_fs
* fs
, ldp_attr
* a
);
46 static uint32_t _ldp_attr_get_next_index();
48 static uint32_t _ldp_attr_next_index
= 1;
50 int ldp_attr_num_us2ds(ldp_attr
* ds
)
52 ldp_attr
*attr
= NULL
;
55 attr
= MPLS_LIST_HEAD(&ds
->us_attr_root
);
58 attr
= MPLS_LIST_NEXT(&ds
->us_attr_root
, attr
, _ds_attr
);
63 mpls_bool
ldp_attr_us_partof_ds(ldp_attr
* us
, ldp_attr
* ds
)
65 if (us
->ds_attr
== ds
) {
66 return MPLS_BOOL_TRUE
;
68 return MPLS_BOOL_FALSE
;
71 void ldp_attr_del_us2ds(ldp_attr
* us
, ldp_attr
* ds
)
76 if (ldp_attr_us_partof_ds(us
, ds
) == MPLS_BOOL_TRUE
) {
78 MPLS_REFCNT_RELEASE(ds
, ldp_attr_delete
);
79 MPLS_LIST_REMOVE(&ds
->us_attr_root
, us
, _ds_attr
);
80 MPLS_REFCNT_RELEASE(us
, ldp_attr_delete
);
86 void ldp_attr_add_fec(ldp_attr
*a
, ldp_fec
*fec
) {
87 MPLS_ASSERT(a
&& fec
);
88 MPLS_REFCNT_HOLD(fec
);
92 void ldp_attr_del_fec(ldp_attr
*a
) {
95 MPLS_REFCNT_RELEASE(a
->fec
, ldp_fec_delete
);
100 void ldp_attr_add_us2ds(ldp_attr
* us
, ldp_attr
* ds
)
106 if (ldp_attr_us_partof_ds(us
, ds
) == MPLS_BOOL_TRUE
) {
109 MPLS_REFCNT_HOLD(us
);
110 MPLS_LIST_ADD_TAIL(&ds
->us_attr_root
, us
, _ds_attr
, ldp_attr
);
111 MPLS_REFCNT_HOLD(ds
);
115 void ldp_attr_action_callback(mpls_timer_handle timer
, void *extra
,
120 ldp_attr
*ldp_attr_find_downstream_state_any2(ldp_global
* g
, ldp_fec
* f
,
123 ldp_attr
*attr
= NULL
;
126 fs
= MPLS_LIST_HEAD(&f
->fs_root_ds
);
128 attr
= MPLS_LIST_HEAD(&fs
->attr_root
);
129 while (attr
!= NULL
) {
130 if (attr
->state
== state
) {
133 attr
= MPLS_LIST_NEXT(&fs
->attr_root
, attr
, _fs
);
135 fs
= MPLS_LIST_NEXT(&f
->fs_root_ds
, fs
, _fec
);
140 ldp_attr
*ldp_attr_find_downstream_state_any(ldp_global
* g
, mpls_fec
* f
,
143 ldp_fec
*fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
);
149 return ldp_attr_find_downstream_state_any2(g
, fnode
, state
);
152 ldp_attr
*ldp_attr_find_upstream_state_any2(ldp_global
* g
, ldp_fec
* f
,
155 ldp_attr
*attr
= NULL
;
158 fs
= MPLS_LIST_HEAD(&f
->fs_root_us
);
160 attr
= MPLS_LIST_HEAD(&fs
->attr_root
);
161 while (attr
!= NULL
) {
162 if (attr
->state
== state
) {
165 attr
= MPLS_LIST_NEXT(&fs
->attr_root
, attr
, _fs
);
167 fs
= MPLS_LIST_NEXT(&f
->fs_root_us
, fs
, _fec
);
172 ldp_attr
*ldp_attr_find_upstream_state_any(ldp_global
* g
, mpls_fec
* f
,
175 ldp_fec
*fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
);
181 return ldp_attr_find_upstream_state_any2(g
, fnode
, state
);
184 static ldp_attr
*_ldp_attr_find_downstream_state(ldp_attr_list
*ds_list
,
187 if (ds_list
!= NULL
) {
188 ldp_attr
*ds_attr
= MPLS_LIST_HEAD(ds_list
);
190 while (ds_attr
!= NULL
) {
191 if (ds_attr
->state
== state
) {
194 ds_attr
= MPLS_LIST_NEXT(ds_list
, ds_attr
, _fs
);
200 ldp_attr
*ldp_attr_find_downstream_state2(ldp_global
* g
, ldp_session
* s
,
201 ldp_fec
* f
, ldp_lsp_state state
)
203 ldp_attr_list
*ds_list
= ldp_attr_find_downstream_all2(g
, s
, f
);
204 return _ldp_attr_find_downstream_state(ds_list
, state
);
207 ldp_attr
*ldp_attr_find_downstream_state(ldp_global
* g
, ldp_session
* s
,
208 mpls_fec
* f
, ldp_lsp_state state
)
210 ldp_attr_list
*ds_list
= ldp_attr_find_downstream_all(g
, s
, f
);
211 return _ldp_attr_find_downstream_state(ds_list
, state
);
214 static ldp_attr
*_ldp_attr_find_upstream_state(ldp_attr_list
*us_list
,
217 if (us_list
!= NULL
) {
218 ldp_attr
*us_attr
= MPLS_LIST_HEAD(us_list
);
220 while (us_attr
!= NULL
) {
221 if (us_attr
->state
== state
) {
224 us_attr
= MPLS_LIST_NEXT(us_list
, us_attr
, _fs
);
230 ldp_attr
*ldp_attr_find_upstream_state2(ldp_global
* g
, ldp_session
* s
,
231 ldp_fec
* f
, ldp_lsp_state state
)
233 ldp_attr_list
*us_list
= ldp_attr_find_upstream_all2(g
, s
, f
);
234 return _ldp_attr_find_upstream_state(us_list
, state
);
237 ldp_attr
*ldp_attr_find_upstream_state(ldp_global
* g
, ldp_session
* s
,
238 mpls_fec
* f
, ldp_lsp_state state
)
240 ldp_attr_list
*us_list
= ldp_attr_find_upstream_all(g
, s
, f
);
241 return _ldp_attr_find_upstream_state(us_list
, state
);
244 void ldp_attr_remove_complete(ldp_global
* g
, ldp_attr
* attr
,
247 ldp_session
*session
= attr
->session
;
248 ldp_outlabel
*out
= NULL
;
249 ldp_inlabel
*in
= NULL
;
250 ldp_attr
*us_temp
= NULL
;
254 switch (attr
->state
) {
255 case LDP_LSP_STATE_MAP_RECV
:
256 if (attr
->ingress
== MPLS_BOOL_TRUE
) {
257 out
= attr
->outlabel
;
258 MPLS_ASSERT(out
!= NULL
);
259 while ((in
= MPLS_LIST_HEAD(&out
->inlabel_root
)) != NULL
) {
260 ldp_inlabel_del_outlabel(g
, in
);
263 if (out
->merge_count
> 0) {
264 for (i
= 0; i
< attr
->fecTlv
.numberFecElements
; i
++) {
265 fec_tlv2mpls_fec(&attr
->fecTlv
, i
, &fec
);
270 memcpy(&ftn
.fec
, &fec
, sizeof(mpls_fec
));
271 ftn
.outsegment_index
= out
->info
.handle
;
272 lsr_cfg_ftn_set2(g
->lsr_handle
, &ftn
, LSR_CFG_DEL
);
275 mpls_mpls_fec2out_del(g
->mpls_handle
, &fec
, &out
->info
);
279 MPLS_ASSERT(out
->merge_count
== 0);
280 ldp_attr_del_outlabel(attr
);
281 ldp_session_del_outlabel(session
, out
);
282 _ldp_global_del_outlabel(g
, out
);
284 while ((us_temp
= MPLS_LIST_HEAD(&attr
->us_attr_root
)) != NULL
) {
285 ldp_attr_del_us2ds(us_temp
, attr
);
287 ldp_attr_delete_downstream(g
, session
, attr
);
289 case LDP_LSP_STATE_MAP_SENT
:
294 if (in
->reuse_count
== 1) {
295 ldp_inlabel_del_outlabel(g
, in
);
299 ldp_attr_del_inlabel(attr
);
300 ldp_attr_delete_upstream(g
, session
, attr
);
301 ldp_attr_del_us2ds(attr
, attr
->ds_attr
);
302 ldp_session_del_inlabel(session
, in
);
304 if (in
->reuse_count
== 0) {
305 _ldp_global_del_inlabel(g
, in
);
308 case LDP_LSP_STATE_ABORT_SENT
:
309 case LDP_LSP_STATE_NOTIF_SENT
:
310 case LDP_LSP_STATE_REQ_RECV
:
311 case LDP_LSP_STATE_WITH_SENT
:
312 case LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT
:
314 ldp_attr_del_us2ds(attr
, attr
->ds_attr
);
315 ldp_attr_delete_upstream(g
, session
, attr
);
318 case LDP_LSP_STATE_ABORT_RECV
:
319 case LDP_LSP_STATE_NOTIF_RECV
:
320 case LDP_LSP_STATE_REQ_SENT
:
321 case LDP_LSP_STATE_WITH_RECV
:
322 case LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV
:
324 while ((us_temp
= MPLS_LIST_HEAD(&attr
->us_attr_root
)) != NULL
) {
325 ldp_attr_del_us2ds(us_temp
, attr
);
327 ldp_attr_delete_downstream(g
, session
, attr
);
333 ldp_attr
*ldp_attr_create(mpls_fec
* fec
)
335 ldp_attr
*a
= (ldp_attr
*) mpls_malloc(sizeof(ldp_attr
));
338 memset(a
, 0, sizeof(ldp_attr
));
339 MPLS_LIST_ELEM_INIT(a
, _session
);
340 MPLS_LIST_ELEM_INIT(a
, _global
);
341 MPLS_LIST_ELEM_INIT(a
, _fs
);
342 MPLS_LIST_INIT(&a
->us_attr_root
, ldp_attr
);
343 MPLS_REFCNT_INIT(a
, 0);
344 a
->index
= _ldp_attr_get_next_index();
345 a
->in_tree
= MPLS_BOOL_FALSE
;
346 a
->ingress
= MPLS_BOOL_FALSE
;
347 a
->filtered
= MPLS_BOOL_FALSE
;
350 mpls_fec2fec_tlv(fec
, &a
->fecTlv
, 0);
351 a
->fecTlv
.numberFecElements
= 1;
358 void ldp_attr_delete(ldp_attr
* a
)
360 LDP_PRINT(g
->user_data
,"attr delete\n");
361 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_FALSE
);
365 void ldp_attr2ldp_attr(ldp_attr
* a
, ldp_attr
* b
, uint32_t flag
)
367 if (a
->fecTlvExists
&& flag
& LDP_ATTR_FEC
) {
368 memcpy(&b
->fecTlv
, &a
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
371 if (a
->genLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
372 memcpy(&b
->genLblTlv
, &a
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
373 b
->genLblTlvExists
= 1;
374 } else if (a
->atmLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
375 memcpy(&b
->atmLblTlv
, &a
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
376 b
->atmLblTlvExists
= 1;
377 } else if (a
->frLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
378 memcpy(&b
->frLblTlv
, &a
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
379 b
->frLblTlvExists
= 1;
381 if (a
->hopCountTlvExists
&& flag
& LDP_ATTR_HOPCOUNT
) {
382 memcpy(&b
->hopCountTlv
, &a
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
383 b
->hopCountTlvExists
= 1;
385 if (a
->pathVecTlvExists
&& flag
& LDP_ATTR_PATH
) {
386 memcpy(&b
->pathVecTlv
, &a
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
387 b
->pathVecTlvExists
= 1;
389 if (a
->lblMsgIdTlvExists
&& flag
& LDP_ATTR_MSGID
) {
390 memcpy(&b
->lblMsgIdTlv
, &a
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
391 b
->lblMsgIdTlvExists
= 1;
393 if (a
->lspidTlvExists
&& flag
& LDP_ATTR_LSPID
) {
394 memcpy(&b
->lspidTlv
, &a
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
395 b
->lspidTlvExists
= 1;
397 if (a
->trafficTlvExists
&& flag
& LDP_ATTR_TRAFFIC
) {
398 memcpy(&b
->trafficTlv
, &a
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
399 b
->trafficTlvExists
= 1;
403 mpls_return_enum
ldp_attr_add_inlabel(ldp_attr
* a
, ldp_inlabel
* i
)
408 _ldp_inlabel_add_attr(i
, a
);
414 mpls_return_enum
ldp_attr_del_inlabel(ldp_attr
* a
)
416 if (a
&& a
->inlabel
) {
417 _ldp_inlabel_del_attr(a
->inlabel
, a
);
418 MPLS_REFCNT_RELEASE(a
->inlabel
, ldp_inlabel_delete
);
425 mpls_return_enum
ldp_attr_add_outlabel(ldp_attr
* a
, ldp_outlabel
* o
)
430 _ldp_outlabel_add_attr(o
, a
);
436 mpls_return_enum
ldp_attr_del_outlabel(ldp_attr
* a
)
438 if (a
&& a
->outlabel
) {
439 _ldp_outlabel_del_attr(a
->outlabel
);
440 MPLS_REFCNT_RELEASE(a
->outlabel
, ldp_outlabel_delete
);
447 mpls_return_enum
ldp_attr_add_session(ldp_attr
* a
, ldp_session
* s
)
452 _ldp_session_add_attr(s
, a
);
458 mpls_return_enum
ldp_attr_del_session(ldp_attr
* a
)
460 if (a
&& a
->session
) {
461 _ldp_session_del_attr(a
->session
, a
);
462 MPLS_REFCNT_RELEASE(a
->session
, ldp_session_delete
);
469 mpls_bool
ldp_attr_is_equal(ldp_attr
* a
, ldp_attr
* b
, uint32_t flag
)
471 if (flag
& LDP_ATTR_LABEL
) {
472 if (a
->genLblTlvExists
&& b
->genLblTlvExists
) {
473 if (a
->genLblTlv
.label
!= b
->genLblTlv
.label
) {
474 return MPLS_BOOL_FALSE
;
476 } else if (a
->atmLblTlvExists
&& b
->atmLblTlvExists
) {
477 if (a
->atmLblTlv
.flags
.flags
.vpi
!= b
->atmLblTlv
.flags
.flags
.vpi
||
478 a
->atmLblTlv
.vci
!= b
->atmLblTlv
.vci
) {
479 return MPLS_BOOL_FALSE
;
481 } else if (a
->frLblTlvExists
&& b
->frLblTlvExists
) {
482 if (a
->frLblTlv
.flags
.flags
.len
!= b
->frLblTlv
.flags
.flags
.len
||
483 a
->frLblTlv
.flags
.flags
.dlci
!= b
->frLblTlv
.flags
.flags
.dlci
) {
484 return MPLS_BOOL_FALSE
;
487 return MPLS_BOOL_FALSE
;
490 if (flag
& LDP_ATTR_HOPCOUNT
) {
491 if (a
->hopCountTlvExists
&& b
->hopCountTlvExists
) {
492 if (a
->hopCountTlv
.hcValue
!= b
->hopCountTlv
.hcValue
) {
493 return MPLS_BOOL_FALSE
;
496 if (a
->hopCountTlvExists
!= b
->hopCountTlvExists
) {
497 return MPLS_BOOL_FALSE
;
501 if (flag
& LDP_ATTR_PATH
) {
504 if (a
->pathVecTlvExists
&& b
->pathVecTlvExists
) {
505 for (i
= 0; i
< MPLS_MAXHOPSNUMBER
; i
++) {
506 if (a
->pathVecTlv
.lsrId
[i
] != b
->pathVecTlv
.lsrId
[i
]) {
507 return MPLS_BOOL_FALSE
;
511 if (a
->hopCountTlvExists
!= b
->hopCountTlvExists
) {
512 return MPLS_BOOL_FALSE
;
516 if (flag
& LDP_ATTR_FEC
) {
519 if (a
->fecTlvExists
&& b
->fecTlvExists
) {
520 if (a
->fecTlv
.numberFecElements
!= b
->fecTlv
.numberFecElements
) {
521 return MPLS_BOOL_FALSE
;
523 for (i
= 0; i
< a
->fecTlv
.numberFecElements
; i
++) {
524 if (a
->fecTlv
.fecElemTypes
[i
] != b
->fecTlv
.fecElemTypes
[i
]) {
525 return MPLS_BOOL_FALSE
;
527 switch (a
->fecTlv
.fecElemTypes
[i
]) {
530 /* nothing of interest to compare */
532 case MPLS_PREFIX_FEC
:
533 case MPLS_HOSTADR_FEC
:
534 if (a
->fecTlv
.fecElArray
[i
].addressEl
.addressFam
!=
535 b
->fecTlv
.fecElArray
[i
].addressEl
.addressFam
||
536 a
->fecTlv
.fecElArray
[i
].addressEl
.preLen
!=
537 b
->fecTlv
.fecElArray
[i
].addressEl
.preLen
||
538 a
->fecTlv
.fecElArray
[i
].addressEl
.address
!=
539 b
->fecTlv
.fecElArray
[i
].addressEl
.address
) {
540 return MPLS_BOOL_FALSE
;
548 return MPLS_BOOL_FALSE
;
551 if (flag
& LDP_ATTR_MSGID
) {
552 if (a
->lblMsgIdTlvExists
&& b
->lblMsgIdTlvExists
) {
553 if (a
->lblMsgIdTlv
.msgId
!= b
->lblMsgIdTlv
.msgId
) {
554 return MPLS_BOOL_FALSE
;
557 return MPLS_BOOL_FALSE
;
560 if (flag
& LDP_ATTR_LSPID
) {
561 if (a
->lspidTlvExists
&& b
->lspidTlvExists
) {
562 if (a
->lspidTlv
.localCrlspId
!= b
->lspidTlv
.localCrlspId
||
563 a
->lspidTlv
.routerId
!= b
->lspidTlv
.routerId
) {
564 return MPLS_BOOL_FALSE
;
567 return MPLS_BOOL_FALSE
;
570 if (flag
& LDP_ATTR_TRAFFIC
) {
572 return MPLS_BOOL_TRUE
;
575 mpls_return_enum
ldp_attr_insert_upstream2(ldp_global
* g
, ldp_session
* s
,
576 ldp_attr
* a
, ldp_fec
*f
)
579 mpls_return_enum retval
;
581 MPLS_ASSERT(g
&& s
&& a
&& (a
->in_tree
== MPLS_BOOL_FALSE
) && f
);
583 /* find the upstream fs for this session */
584 if ((fs
= _ldp_fec_find_fs_us(f
, s
, MPLS_BOOL_TRUE
)) == NULL
) {
585 /* this session isn't in the list and cannot be added */
589 ldp_attr_add_session(a
, s
);
590 ldp_attr_add_fec(a
, f
);
592 retval
= _ldp_fs_add_attr(fs
, a
);
593 _ldp_global_add_attr(g
, a
);
594 a
->in_tree
= MPLS_BOOL_TRUE
;
598 mpls_return_enum
ldp_attr_insert_upstream(ldp_global
* g
, ldp_session
* s
,
601 ldp_fec
*fnode
= NULL
;
603 MPLS_ASSERT(g
&& s
&& a
&& (a
->in_tree
== MPLS_BOOL_FALSE
));
605 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_TRUE
)) == NULL
) {
606 /* we couldn't get/add a node from/to the tree! */
610 return ldp_attr_insert_upstream2(g
, s
, a
, fnode
);
613 mpls_return_enum
ldp_attr_insert_downstream2(ldp_global
* g
, ldp_session
* s
,
614 ldp_attr
* a
, ldp_fec
*f
)
617 mpls_return_enum retval
;
619 MPLS_ASSERT(g
&& s
&& a
&& (a
->in_tree
== MPLS_BOOL_FALSE
) && f
);
621 /* find the downstream fs for this session */
622 if ((fs
= _ldp_fec_find_fs_ds(f
, s
, MPLS_BOOL_TRUE
)) == NULL
) {
623 /* this session isn't in the list and cannot be added */
627 ldp_attr_add_session(a
, s
);
628 ldp_attr_add_fec(a
, f
);
630 retval
= _ldp_fs_add_attr(fs
, a
);
631 _ldp_global_add_attr(g
, a
);
632 a
->in_tree
= MPLS_BOOL_TRUE
;
636 mpls_return_enum
ldp_attr_insert_downstream(ldp_global
* g
, ldp_session
* s
,
639 ldp_fec
*fnode
= NULL
;
641 MPLS_ASSERT(g
&& s
&& a
&& (a
->in_tree
== MPLS_BOOL_FALSE
));
643 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_TRUE
)) == NULL
) {
644 /* we couldn't get/add a node from/to the tree! */
648 return ldp_attr_insert_downstream2(g
, s
, a
, fnode
);
651 ldp_attr_list
*ldp_attr_find_upstream_all2(ldp_global
* g
, ldp_session
* s
,
656 MPLS_ASSERT(s
&& f
&& g
);
658 /* find the upstream fs for this session */
659 if ((fs
= _ldp_fec_find_fs_us(f
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
660 /* this session isn't in the list */
663 return &fs
->attr_root
;
666 ldp_attr_list
*ldp_attr_find_upstream_all(ldp_global
* g
, ldp_session
* s
,
669 ldp_fec
*fnode
= NULL
;
671 MPLS_ASSERT(s
&& f
&& g
);
673 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
674 /* we couldn't get the node from the tree! */
678 return ldp_attr_find_upstream_all2(g
, s
, fnode
);
681 ldp_attr_list
*ldp_attr_find_downstream_all2(ldp_global
* g
, ldp_session
* s
,
686 MPLS_ASSERT(s
&& f
&& g
);
688 /* find the downstream fs for this session */
689 if ((fs
= _ldp_fec_find_fs_ds(f
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
690 /* this session isn't in the list */
693 return &fs
->attr_root
;
696 ldp_attr_list
*ldp_attr_find_downstream_all(ldp_global
* g
, ldp_session
* s
,
699 ldp_fec
*fnode
= NULL
;
701 MPLS_ASSERT(s
&& f
&& g
);
703 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
704 /* we couldn't get the node from the tree! */
708 return ldp_attr_find_downstream_all2(g
, s
, fnode
);
711 void ldp_attr_delete_upstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
713 ldp_fec
*fnode
= NULL
;
716 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
718 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
)) == NULL
) {
719 /* we couldn't get the node from the tree! */
723 /* find the upstream fs for this session */
724 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
725 /* this session isn't in the list */
729 ldp_attr_del_session(a
);
732 if (_ldp_fs_del_attr(fs
, a
) == MPLS_BOOL_TRUE
) {
733 _ldp_fec_del_fs_us(fnode
, fs
);
735 a
->in_tree
= MPLS_BOOL_FALSE
;
736 _ldp_global_del_attr(g
, a
);
738 if (ldp_fec_empty(fnode
)) {
740 while ((nh
= MPLS_LIST_HEAD(&fnode
->nh_root
))) {
741 ldp_fec_del_nexthop(fnode
, nh
);
743 ldp_fec_remove(g
, &fnode
->info
);
744 _ldp_global_del_fec(g
, fnode
);
748 void ldp_attr_delete_downstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
750 ldp_fec
*fnode
= NULL
;
753 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
755 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
)) == NULL
) {
756 /* we couldn't get the node from the tree! */
760 /* find the downstream fs for this session */
761 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
762 /* this session isn't in the list */
766 ldp_attr_del_session(a
);
769 if (_ldp_fs_del_attr(fs
, a
) == MPLS_BOOL_TRUE
) {
770 _ldp_fec_del_fs_ds(fnode
, fs
);
772 a
->in_tree
= MPLS_BOOL_FALSE
;
773 _ldp_global_del_attr(g
, a
);
775 if (ldp_fec_empty(fnode
)) {
777 while ((nh
= MPLS_LIST_HEAD(&fnode
->nh_root
))) {
778 ldp_fec_del_nexthop(fnode
, nh
);
780 ldp_fec_remove(g
, &fnode
->info
);
781 _ldp_global_del_fec(g
, fnode
);
785 void ldp_attr2mpls_label_struct(ldp_attr
* a
, mpls_label_struct
* l
)
787 if (a
->genLblTlvExists
) {
788 l
->type
= MPLS_LABEL_TYPE_GENERIC
;
789 l
->u
.gen
= a
->genLblTlv
.label
;
790 } else if (a
->atmLblTlvExists
) {
791 l
->type
= MPLS_LABEL_TYPE_ATM
;
792 l
->u
.atm
.vpi
= a
->atmLblTlv
.flags
.flags
.vpi
;
793 l
->u
.atm
.vci
= a
->atmLblTlv
.vci
;
794 } else if (a
->frLblTlvExists
) {
795 l
->type
= MPLS_LABEL_TYPE_FR
;
796 l
->u
.fr
.len
= a
->frLblTlv
.flags
.flags
.len
;
797 l
->u
.fr
.dlci
= a
->frLblTlv
.flags
.flags
.dlci
;
803 void mpls_label_struct2ldp_attr(mpls_label_struct
* l
, ldp_attr
* a
)
806 case MPLS_LABEL_TYPE_GENERIC
:
807 a
->genLblTlvExists
= 1;
808 a
->atmLblTlvExists
= 0;
809 a
->frLblTlvExists
= 0;
810 a
->genLblTlv
.label
= l
->u
.gen
;
812 case MPLS_LABEL_TYPE_ATM
:
813 a
->genLblTlvExists
= 0;
814 a
->atmLblTlvExists
= 1;
815 a
->frLblTlvExists
= 0;
816 a
->atmLblTlv
.flags
.flags
.vpi
= l
->u
.atm
.vpi
;
817 a
->atmLblTlv
.vci
= l
->u
.atm
.vci
;
818 case MPLS_LABEL_TYPE_FR
:
819 a
->genLblTlvExists
= 0;
820 a
->atmLblTlvExists
= 0;
821 a
->frLblTlvExists
= 1;
822 a
->frLblTlv
.flags
.flags
.len
= l
->u
.fr
.len
;
823 a
->frLblTlv
.flags
.flags
.dlci
= l
->u
.fr
.dlci
;
830 void ldp_attr2ldp_attr(ldp_attr
* src
, ldp_attr
* dst
, u_int32 flag
)
832 if (flag
& LDP_ATTR_FEC
) {
833 memcpy(&dst
->fecTlv
, &src
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
834 dst
->fecTlvExists
= src
->fecTlvExists
;
836 if (flag
& LDP_ATTR_LABEL
) {
837 memcpy(&dst
->genLblTlv
, &src
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
838 memcpy(&dst
->atmLblTlv
, &src
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
839 memcpy(&dst
->frLblTlv
, &src
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
840 dst
->genLblTlvExists
= src
->genLblTlvExists
841 dst
->atmLblTlvExists
= src
->atmLblTlvExists
842 dst
->frLblTlvExists
= src
->frLblTlvExists
}
843 if (flag
& LDP_ATTR_HOPCOUNT
) {
844 memcpy(&dst
->hopCountTlv
, &src
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
845 dst
->hopCountTlvExists
= src
->hopCountTlvExists
;
847 if (flag
& LDP_ATTR_PATH
) {
848 memcpy(&dst
->pathVecTlv
, &src
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
849 dst
->pathVecTlvExists
= src
->pathVecTlvExists
;
851 if (flag
& LDP_ATTR_MSGID
) {
852 memcpy(&dst
->lblMsgIdTlv
, &src
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
853 dst
->lblMsgIdTlvExists
= src
->lblMsgIdTlvExists
;
855 if (flag
& LDP_ATTR_LSPID
) {
856 memcpy(&dst
->lspidTlv
, &src
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
857 dst
->lspidTlvExists
= src
->lspidTlvExists
;
859 if (flag
& LDP_ATTR_TRAFFIC
) {
860 memcpy(&dst
->trafficTlv
, &src
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
861 dst
->trafficTlvExists
= src
->trafficTlvExists
;
866 ldp_fec
*_ldp_attr_get_fec2(ldp_global
* g
, mpls_fec
* f
, mpls_bool flag
)
868 ldp_fec
*fnode
= NULL
;
870 if (!(fnode
= ldp_fec_find(g
,f
))) {
871 if (flag
== MPLS_BOOL_FALSE
) {
875 /* this FEC doesn't exist in the tree yet, create one ... */
876 if (!(fnode
= ldp_fec_insert(g
, f
))) {
880 _ldp_global_add_fec(g
, fnode
);
885 static ldp_fec
*_ldp_attr_get_fec(ldp_global
* g
, ldp_attr
* a
, mpls_bool flag
)
889 /* get FEC from attr */
890 fec_tlv2mpls_fec(&a
->fecTlv
, 0, &fec
);
891 return _ldp_attr_get_fec2(g
, &fec
, flag
);
894 static ldp_fs
*_ldp_fec_add_fs_ds(ldp_fec
* fec
, ldp_session
* s
)
896 ldp_fs
*fs
= _ldp_fec_find_fs_ds(fec
, s
, MPLS_BOOL_FALSE
);
899 fs
= _ldp_fs_create(s
);
903 MPLS_LIST_ADD_HEAD(&fec
->fs_root_ds
, fs
, _fec
, ldp_fs
);
908 static ldp_fs
*_ldp_fec_add_fs_us(ldp_fec
* fec
, ldp_session
* s
)
910 ldp_fs
*fs
= _ldp_fec_find_fs_us(fec
, s
, MPLS_BOOL_FALSE
);
913 fs
= _ldp_fs_create(s
);
917 MPLS_LIST_ADD_HEAD(&fec
->fs_root_us
, fs
, _fec
, ldp_fs
);
922 static ldp_fs
*_ldp_fec_find_fs_us(ldp_fec
* fec
, ldp_session
* s
,
925 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_us
);
928 if (fs
->session
->index
== s
->index
) {
931 fs
= MPLS_LIST_NEXT(&fec
->fs_root_us
, fs
, _fec
);
933 if (flag
== MPLS_BOOL_FALSE
) {
936 return _ldp_fec_add_fs_us(fec
, s
);
939 static ldp_fs
*_ldp_fec_find_fs_ds(ldp_fec
* fec
, ldp_session
* s
,
942 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_ds
);
945 if (fs
->session
->index
== s
->index
) {
948 fs
= MPLS_LIST_NEXT(&fec
->fs_root_ds
, fs
, _fec
);
950 if (flag
== MPLS_BOOL_FALSE
) {
953 return _ldp_fec_add_fs_ds(fec
, s
);
956 static void _ldp_fec_del_fs_us(ldp_fec
* fec
, ldp_fs
* fs
)
961 MPLS_LIST_REMOVE(&fec
->fs_root_us
, fs
, _fec
);
965 static void _ldp_fec_del_fs_ds(ldp_fec
* fec
, ldp_fs
* fs
)
970 MPLS_LIST_REMOVE(&fec
->fs_root_ds
, fs
, _fec
);
974 static ldp_fs
*_ldp_fs_create(ldp_session
* s
)
976 ldp_fs
*fs
= (ldp_fs
*) mpls_malloc(sizeof(ldp_fs
));
979 memset(fs
, 0, sizeof(ldp_fs
));
980 MPLS_LIST_INIT(&fs
->attr_root
, ldp_attr
);
981 MPLS_LIST_ELEM_INIT(fs
, _fec
);
990 static void _ldp_fs_delete(ldp_fs
* fs
)
992 LDP_PRINT(g
->user_data
,"fs delete\n");
993 if (fs
->session
!= NULL
) {
994 MPLS_REFCNT_RELEASE(fs
->session
, ldp_session_delete
);
999 static ldp_attr
*_ldp_fs_find_attr(ldp_fs
* fs
, ldp_attr
* a
)
1001 ldp_attr
*ptr
= MPLS_LIST_HEAD(&fs
->attr_root
);
1003 while (ptr
!= NULL
) {
1004 if (ldp_attr_is_equal(a
, ptr
, LDP_ATTR_LABEL
| LDP_ATTR_FEC
) == MPLS_BOOL_TRUE
) {
1007 ptr
= MPLS_LIST_NEXT(&fs
->attr_root
, ptr
, _fs
);
1012 static mpls_return_enum
_ldp_fs_add_attr(ldp_fs
* fs
, ldp_attr
* a
)
1014 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
1016 MPLS_ASSERT(ptr
== NULL
);
1017 MPLS_REFCNT_HOLD(a
);
1018 MPLS_LIST_ADD_HEAD(&fs
->attr_root
, a
, _fs
, ldp_attr
);
1019 return MPLS_SUCCESS
;
1022 static mpls_bool
_ldp_fs_del_attr(ldp_fs
* fs
, ldp_attr
* a
)
1024 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
1027 MPLS_LIST_REMOVE(&fs
->attr_root
, ptr
, _fs
);
1028 MPLS_REFCNT_RELEASE(ptr
, ldp_attr_delete
);
1030 if (MPLS_LIST_HEAD(&fs
->attr_root
) == NULL
)
1031 return MPLS_BOOL_TRUE
;
1032 return MPLS_BOOL_FALSE
;
1035 static uint32_t _ldp_attr_get_next_index()
1037 uint32_t retval
= _ldp_attr_next_index
;
1039 _ldp_attr_next_index
++;
1040 if (retval
> _ldp_attr_next_index
) {
1041 _ldp_attr_next_index
= 1;