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_global
*g
, ldp_attr
*a
) {
95 MPLS_REFCNT_RELEASE2(g
, 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
,
662 /* find the upstream fs for this session */
663 if ((fs
= _ldp_fec_find_fs_us(f
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
664 /* this session isn't in the list */
667 return &fs
->attr_root
;
670 ldp_attr_list
*ldp_attr_find_upstream_all(ldp_global
* g
, ldp_session
* s
,
673 ldp_fec
*fnode
= NULL
;
681 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
682 /* we couldn't get the node from the tree! */
686 return ldp_attr_find_upstream_all2(g
, s
, fnode
);
689 ldp_attr_list
*ldp_attr_find_downstream_all2(ldp_global
* g
, ldp_session
* s
,
700 /* find the downstream fs for this session */
701 if ((fs
= _ldp_fec_find_fs_ds(f
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
702 /* this session isn't in the list */
705 return &fs
->attr_root
;
708 ldp_attr_list
*ldp_attr_find_downstream_all(ldp_global
* g
, ldp_session
* s
,
711 ldp_fec
*fnode
= NULL
;
719 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
720 /* we couldn't get the node from the tree! */
724 return ldp_attr_find_downstream_all2(g
, s
, fnode
);
727 void ldp_attr_delete_upstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
729 ldp_fec
*fnode
= NULL
;
732 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
734 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
)) == NULL
) {
735 /* we couldn't get the node from the tree! */
739 /* find the upstream fs for this session */
740 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
741 /* this session isn't in the list */
745 ldp_attr_del_session(a
);
746 ldp_attr_del_fec(g
, a
);
748 if (_ldp_fs_del_attr(fs
, a
) == MPLS_BOOL_TRUE
) {
749 _ldp_fec_del_fs_us(fnode
, fs
);
751 a
->in_tree
= MPLS_BOOL_FALSE
;
752 _ldp_global_del_attr(g
, a
);
755 void ldp_attr_delete_downstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
757 ldp_fec
*fnode
= NULL
;
760 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
762 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
)) == NULL
) {
763 /* we couldn't get the node from the tree! */
767 /* find the downstream fs for this session */
768 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
769 /* this session isn't in the list */
773 ldp_attr_del_session(a
);
774 ldp_attr_del_fec(g
, a
);
776 if (_ldp_fs_del_attr(fs
, a
) == MPLS_BOOL_TRUE
) {
777 _ldp_fec_del_fs_ds(fnode
, fs
);
779 a
->in_tree
= MPLS_BOOL_FALSE
;
780 _ldp_global_del_attr(g
, a
);
783 void ldp_attr2mpls_label_struct(ldp_attr
* a
, mpls_label_struct
* l
)
785 if (a
->genLblTlvExists
) {
786 l
->type
= MPLS_LABEL_TYPE_GENERIC
;
787 l
->u
.gen
= a
->genLblTlv
.label
;
788 } else if (a
->atmLblTlvExists
) {
789 l
->type
= MPLS_LABEL_TYPE_ATM
;
790 l
->u
.atm
.vpi
= a
->atmLblTlv
.flags
.flags
.vpi
;
791 l
->u
.atm
.vci
= a
->atmLblTlv
.vci
;
792 } else if (a
->frLblTlvExists
) {
793 l
->type
= MPLS_LABEL_TYPE_FR
;
794 l
->u
.fr
.len
= a
->frLblTlv
.flags
.flags
.len
;
795 l
->u
.fr
.dlci
= a
->frLblTlv
.flags
.flags
.dlci
;
801 void mpls_label_struct2ldp_attr(mpls_label_struct
* l
, ldp_attr
* a
)
804 case MPLS_LABEL_TYPE_GENERIC
:
805 a
->genLblTlvExists
= 1;
806 a
->atmLblTlvExists
= 0;
807 a
->frLblTlvExists
= 0;
808 a
->genLblTlv
.label
= l
->u
.gen
;
810 case MPLS_LABEL_TYPE_ATM
:
811 a
->genLblTlvExists
= 0;
812 a
->atmLblTlvExists
= 1;
813 a
->frLblTlvExists
= 0;
814 a
->atmLblTlv
.flags
.flags
.vpi
= l
->u
.atm
.vpi
;
815 a
->atmLblTlv
.vci
= l
->u
.atm
.vci
;
816 case MPLS_LABEL_TYPE_FR
:
817 a
->genLblTlvExists
= 0;
818 a
->atmLblTlvExists
= 0;
819 a
->frLblTlvExists
= 1;
820 a
->frLblTlv
.flags
.flags
.len
= l
->u
.fr
.len
;
821 a
->frLblTlv
.flags
.flags
.dlci
= l
->u
.fr
.dlci
;
828 void ldp_attr2ldp_attr(ldp_attr
* src
, ldp_attr
* dst
, u_int32 flag
)
830 if (flag
& LDP_ATTR_FEC
) {
831 memcpy(&dst
->fecTlv
, &src
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
832 dst
->fecTlvExists
= src
->fecTlvExists
;
834 if (flag
& LDP_ATTR_LABEL
) {
835 memcpy(&dst
->genLblTlv
, &src
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
836 memcpy(&dst
->atmLblTlv
, &src
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
837 memcpy(&dst
->frLblTlv
, &src
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
838 dst
->genLblTlvExists
= src
->genLblTlvExists
839 dst
->atmLblTlvExists
= src
->atmLblTlvExists
840 dst
->frLblTlvExists
= src
->frLblTlvExists
}
841 if (flag
& LDP_ATTR_HOPCOUNT
) {
842 memcpy(&dst
->hopCountTlv
, &src
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
843 dst
->hopCountTlvExists
= src
->hopCountTlvExists
;
845 if (flag
& LDP_ATTR_PATH
) {
846 memcpy(&dst
->pathVecTlv
, &src
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
847 dst
->pathVecTlvExists
= src
->pathVecTlvExists
;
849 if (flag
& LDP_ATTR_MSGID
) {
850 memcpy(&dst
->lblMsgIdTlv
, &src
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
851 dst
->lblMsgIdTlvExists
= src
->lblMsgIdTlvExists
;
853 if (flag
& LDP_ATTR_LSPID
) {
854 memcpy(&dst
->lspidTlv
, &src
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
855 dst
->lspidTlvExists
= src
->lspidTlvExists
;
857 if (flag
& LDP_ATTR_TRAFFIC
) {
858 memcpy(&dst
->trafficTlv
, &src
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
859 dst
->trafficTlvExists
= src
->trafficTlvExists
;
864 ldp_fec
*_ldp_attr_get_fec2(ldp_global
* g
, mpls_fec
* f
, mpls_bool flag
)
866 ldp_fec
*fnode
= NULL
;
868 if (!(fnode
= ldp_fec_find(g
,f
))) {
869 if (flag
== MPLS_BOOL_FALSE
) {
873 /* this FEC doesn't exist in the tree yet, create one ... */
874 if (!(fnode
= ldp_fec_create(g
, f
))) {
882 static ldp_fec
*_ldp_attr_get_fec(ldp_global
* g
, ldp_attr
* a
, mpls_bool flag
)
886 /* get FEC from attr */
887 fec_tlv2mpls_fec(&a
->fecTlv
, 0, &fec
);
888 return _ldp_attr_get_fec2(g
, &fec
, flag
);
891 static ldp_fs
*_ldp_fec_add_fs_ds(ldp_fec
* fec
, ldp_session
* s
)
893 ldp_fs
*fs
= _ldp_fec_find_fs_ds(fec
, s
, MPLS_BOOL_FALSE
);
896 fs
= _ldp_fs_create(s
);
900 MPLS_LIST_ADD_HEAD(&fec
->fs_root_ds
, fs
, _fec
, ldp_fs
);
905 static ldp_fs
*_ldp_fec_add_fs_us(ldp_fec
* fec
, ldp_session
* s
)
907 ldp_fs
*fs
= _ldp_fec_find_fs_us(fec
, s
, MPLS_BOOL_FALSE
);
910 fs
= _ldp_fs_create(s
);
914 MPLS_LIST_ADD_HEAD(&fec
->fs_root_us
, fs
, _fec
, ldp_fs
);
919 static ldp_fs
*_ldp_fec_find_fs_us(ldp_fec
* fec
, ldp_session
* s
,
922 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_us
);
925 if (fs
->session
->index
== s
->index
) {
928 fs
= MPLS_LIST_NEXT(&fec
->fs_root_us
, fs
, _fec
);
930 if (flag
== MPLS_BOOL_FALSE
) {
933 return _ldp_fec_add_fs_us(fec
, s
);
936 static ldp_fs
*_ldp_fec_find_fs_ds(ldp_fec
* fec
, ldp_session
* s
,
939 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_ds
);
942 if (fs
->session
->index
== s
->index
) {
945 fs
= MPLS_LIST_NEXT(&fec
->fs_root_ds
, fs
, _fec
);
947 if (flag
== MPLS_BOOL_FALSE
) {
950 return _ldp_fec_add_fs_ds(fec
, s
);
953 static void _ldp_fec_del_fs_us(ldp_fec
* fec
, ldp_fs
* fs
)
958 MPLS_LIST_REMOVE(&fec
->fs_root_us
, fs
, _fec
);
962 static void _ldp_fec_del_fs_ds(ldp_fec
* fec
, ldp_fs
* fs
)
967 MPLS_LIST_REMOVE(&fec
->fs_root_ds
, fs
, _fec
);
971 static ldp_fs
*_ldp_fs_create(ldp_session
* s
)
973 ldp_fs
*fs
= (ldp_fs
*) mpls_malloc(sizeof(ldp_fs
));
976 memset(fs
, 0, sizeof(ldp_fs
));
977 MPLS_LIST_INIT(&fs
->attr_root
, ldp_attr
);
978 MPLS_LIST_ELEM_INIT(fs
, _fec
);
987 static void _ldp_fs_delete(ldp_fs
* fs
)
989 LDP_PRINT(g
->user_data
,"fs delete\n");
990 if (fs
->session
!= NULL
) {
991 MPLS_REFCNT_RELEASE(fs
->session
, ldp_session_delete
);
996 static ldp_attr
*_ldp_fs_find_attr(ldp_fs
* fs
, ldp_attr
* a
)
998 ldp_attr
*ptr
= MPLS_LIST_HEAD(&fs
->attr_root
);
1000 while (ptr
!= NULL
) {
1001 if (ldp_attr_is_equal(a
, ptr
, LDP_ATTR_LABEL
| LDP_ATTR_FEC
) == MPLS_BOOL_TRUE
) {
1004 ptr
= MPLS_LIST_NEXT(&fs
->attr_root
, ptr
, _fs
);
1009 static mpls_return_enum
_ldp_fs_add_attr(ldp_fs
* fs
, ldp_attr
* a
)
1011 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
1013 MPLS_ASSERT(ptr
== NULL
);
1014 MPLS_REFCNT_HOLD(a
);
1015 MPLS_LIST_ADD_HEAD(&fs
->attr_root
, a
, _fs
, ldp_attr
);
1016 return MPLS_SUCCESS
;
1019 static mpls_bool
_ldp_fs_del_attr(ldp_fs
* fs
, ldp_attr
* a
)
1021 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
1024 MPLS_LIST_REMOVE(&fs
->attr_root
, ptr
, _fs
);
1025 MPLS_REFCNT_RELEASE(ptr
, ldp_attr_delete
);
1027 if (MPLS_LIST_HEAD(&fs
->attr_root
) == NULL
)
1028 return MPLS_BOOL_TRUE
;
1029 return MPLS_BOOL_FALSE
;
1032 ldp_attr
*ldp_attr_find_upstream_map_in_labelspace(ldp_fec
*f
, int labelspace
)
1034 ldp_fs
*fs
= MPLS_LIST_HEAD(&f
->fs_root_us
);
1036 fprintf(stderr
, "ldp_attr_find_upstream_map_in_labelspace: enter\n");
1038 ldp_attr
*attr
= MPLS_LIST_HEAD(&fs
->attr_root
);
1039 fprintf(stderr
, "FS: %p\n", fs
);
1041 fprintf(stderr
, "ATTR: %p\n", fs
);
1042 if (attr
->state
== LDP_LSP_STATE_MAP_SENT
) {
1043 fprintf(stderr
, "SESSION: %p\n", attr
->session
);
1044 if (attr
->session
->cfg_label_space
== labelspace
) {
1045 fprintf(stderr
, "ldp_attr_find_upstream_map_in_labelspace: exit\n");
1049 attr
= MPLS_LIST_NEXT(&fs
->attr_root
, attr
, _fs
);
1051 fs
= MPLS_LIST_NEXT(&f
->fs_root_us
, fs
, _fec
);
1053 fprintf(stderr
, "ldp_attr_find_upstream_map_in_labelspace: exit\n");
1057 static uint32_t _ldp_attr_get_next_index()
1059 uint32_t retval
= _ldp_attr_next_index
;
1061 _ldp_attr_next_index
++;
1062 if (retval
> _ldp_attr_next_index
) {
1063 _ldp_attr_next_index
= 1;