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_fec2(ldp_global
* g
, mpls_fec
* f
, mpls_bool flag
);
30 static ldp_fec
*_ldp_attr_get_fec(ldp_global
* g
, ldp_attr
* a
, mpls_bool flag
);
31 static ldp_fs
*_ldp_fec_add_fs_ds(ldp_fec
* fec
, ldp_session
* s
);
32 static ldp_fs
*_ldp_fec_add_fs_us(ldp_fec
* fec
, ldp_session
* s
);
33 static ldp_fs
*_ldp_fec_find_fs_us(ldp_fec
* fec
, ldp_session
* s
,
35 static ldp_fs
*_ldp_fec_find_fs_ds(ldp_fec
* fec
, ldp_session
* s
,
37 static void _ldp_fec_del_fs_us(ldp_fec
* fec
, ldp_fs
* fs
);
38 static void _ldp_fec_del_fs_ds(ldp_fec
* fec
, ldp_fs
* fs
);
39 static ldp_fs
*_ldp_fs_create(ldp_session
* s
);
40 static void _ldp_fs_delete(ldp_fs
* fs
);
41 static ldp_attr
*_ldp_fs_find_attr(ldp_fs
* fs
, ldp_attr
* a
);
42 static mpls_return_enum
_ldp_fs_add_attr(ldp_fs
* fs
, ldp_attr
* a
);
43 static mpls_bool
_ldp_fs_del_attr(ldp_fs
* fs
, ldp_attr
* a
);
44 static uint32_t _ldp_attr_get_next_index();
46 static uint32_t _ldp_attr_next_index
= 1;
48 int ldp_attr_num_us2ds(ldp_attr
* ds
)
50 ldp_attr
*attr
= NULL
;
53 attr
= MPLS_LIST_HEAD(&ds
->us_attr_root
);
56 attr
= MPLS_LIST_NEXT(&ds
->us_attr_root
, attr
, _ds_attr
);
61 mpls_bool
ldp_attr_us_partof_ds(ldp_attr
* us
, ldp_attr
* ds
)
63 if (us
->ds_attr
== ds
) {
64 return MPLS_BOOL_TRUE
;
66 return MPLS_BOOL_FALSE
;
69 void ldp_attr_del_us2ds(ldp_attr
* us
, ldp_attr
* ds
)
74 if (ldp_attr_us_partof_ds(us
, ds
) == MPLS_BOOL_TRUE
) {
76 MPLS_REFCNT_RELEASE(ds
, ldp_attr_delete
);
77 MPLS_LIST_REMOVE(&ds
->us_attr_root
, us
, _ds_attr
);
78 MPLS_REFCNT_RELEASE(us
, ldp_attr_delete
);
84 void ldp_attr_add_us2ds(ldp_attr
* us
, ldp_attr
* ds
)
90 if (ldp_attr_us_partof_ds(us
, ds
) == MPLS_BOOL_TRUE
) {
94 MPLS_LIST_ADD_TAIL(&ds
->us_attr_root
, us
, _ds_attr
, ldp_attr
);
99 void ldp_attr_action_callback(mpls_timer_handle timer
, void *extra
,
104 ldp_attr
*ldp_attr_find_downstream_state_any(ldp_global
* g
, mpls_fec
* f
,
107 ldp_fec
*fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
);
108 ldp_attr
*attr
= NULL
;
115 fs
= MPLS_LIST_HEAD(&fnode
->fs_root_ds
);
117 attr
= MPLS_LIST_HEAD(&fs
->attr_root
);
118 while (attr
!= NULL
) {
119 if (attr
->state
== state
) {
122 attr
= MPLS_LIST_NEXT(&fs
->attr_root
, attr
, _fs
);
124 fs
= MPLS_LIST_NEXT(&fnode
->fs_root_ds
, fs
, _fec
);
129 ldp_attr
*ldp_attr_find_upstream_state_any(ldp_global
* g
, mpls_fec
* f
,
132 ldp_fec
*fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
);
133 ldp_attr
*attr
= NULL
;
140 fs
= MPLS_LIST_HEAD(&fnode
->fs_root_us
);
142 attr
= MPLS_LIST_HEAD(&fs
->attr_root
);
143 while (attr
!= NULL
) {
144 if (attr
->state
== state
) {
147 attr
= MPLS_LIST_NEXT(&fs
->attr_root
, attr
, _fs
);
149 fs
= MPLS_LIST_NEXT(&fnode
->fs_root_us
, fs
, _fec
);
154 ldp_attr
*ldp_attr_find_downstream_state(ldp_global
* g
, ldp_session
* s
,
155 mpls_fec
* f
, ldp_lsp_state state
)
157 ldp_attr_list
*ds_list
= ldp_attr_find_downstream_all(g
, s
, f
);
159 if (ds_list
!= NULL
) {
160 ldp_attr
*ds_attr
= MPLS_LIST_HEAD(ds_list
);
162 while (ds_attr
!= NULL
) {
163 if (ds_attr
->state
== state
) {
166 ds_attr
= MPLS_LIST_NEXT(ds_list
, ds_attr
, _fs
);
172 ldp_attr
*ldp_attr_find_upstream_state(ldp_global
* g
, ldp_session
* s
,
173 mpls_fec
* f
, ldp_lsp_state state
)
175 ldp_attr_list
*us_list
= ldp_attr_find_upstream_all(g
, s
, f
);
177 if (us_list
!= NULL
) {
178 ldp_attr
*us_attr
= MPLS_LIST_HEAD(us_list
);
180 while (us_attr
!= NULL
) {
181 if (us_attr
->state
== state
) {
184 us_attr
= MPLS_LIST_NEXT(us_list
, us_attr
, _fs
);
190 void ldp_attr_remove_complete(ldp_global
* g
, ldp_attr
* attr
,
193 ldp_session
*session
= attr
->session
;
194 ldp_outlabel
*out
= NULL
;
195 ldp_inlabel
*in
= NULL
;
196 ldp_attr
*us_temp
= NULL
;
200 switch (attr
->state
) {
201 case LDP_LSP_STATE_MAP_RECV
:
202 if (attr
->ingress
== MPLS_BOOL_TRUE
) {
203 out
= attr
->outlabel
;
204 MPLS_ASSERT(out
!= NULL
);
205 while ((in
= MPLS_LIST_HEAD(&out
->inlabel_root
)) != NULL
) {
206 ldp_inlabel_del_outlabel(g
, in
);
209 if (out
->merge_count
> 0) {
210 for (i
= 0; i
< attr
->fecTlv
.numberFecElements
; i
++) {
211 fec_tlv2mpls_fec(&attr
->fecTlv
, i
, &fec
);
216 memcpy(&ftn
.fec
, &fec
, sizeof(mpls_fec
));
217 ftn
.outsegment_index
= out
->info
.handle
;
218 lsr_cfg_ftn_set2(g
->lsr_handle
, &ftn
, LSR_CFG_DEL
);
221 mpls_mpls_fec2out_del(g
->mpls_handle
, &fec
, &out
->info
);
225 MPLS_ASSERT(out
->merge_count
== 0);
226 ldp_attr_del_outlabel(attr
);
227 ldp_session_del_outlabel(session
, out
);
228 _ldp_global_del_outlabel(g
, out
);
230 while ((us_temp
= MPLS_LIST_HEAD(&attr
->us_attr_root
)) != NULL
) {
231 ldp_attr_del_us2ds(us_temp
, attr
);
233 ldp_attr_delete_downstream(g
, session
, attr
);
235 case LDP_LSP_STATE_MAP_SENT
:
240 if (in
->reuse_count
== 1) {
241 ldp_inlabel_del_outlabel(g
, in
);
245 ldp_attr_del_inlabel(attr
);
246 ldp_attr_delete_upstream(g
, session
, attr
);
247 ldp_attr_del_us2ds(attr
, attr
->ds_attr
);
248 ldp_session_del_inlabel(session
, in
);
250 if (in
->reuse_count
== 0) {
251 _ldp_global_del_inlabel(g
, in
);
254 case LDP_LSP_STATE_ABORT_SENT
:
255 case LDP_LSP_STATE_NOTIF_SENT
:
256 case LDP_LSP_STATE_REQ_RECV
:
257 case LDP_LSP_STATE_WITH_SENT
:
258 case LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT
:
260 ldp_attr_del_us2ds(attr
, attr
->ds_attr
);
261 ldp_attr_delete_upstream(g
, session
, attr
);
264 case LDP_LSP_STATE_ABORT_RECV
:
265 case LDP_LSP_STATE_NOTIF_RECV
:
266 case LDP_LSP_STATE_REQ_SENT
:
267 case LDP_LSP_STATE_WITH_RECV
:
268 case LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV
:
270 while ((us_temp
= MPLS_LIST_HEAD(&attr
->us_attr_root
)) != NULL
) {
271 ldp_attr_del_us2ds(us_temp
, attr
);
273 ldp_attr_delete_downstream(g
, session
, attr
);
279 ldp_attr
*ldp_attr_create(mpls_fec
* fec
)
281 ldp_attr
*a
= (ldp_attr
*) mpls_malloc(sizeof(ldp_attr
));
284 memset(a
, 0, sizeof(ldp_attr
));
285 MPLS_LIST_ELEM_INIT(a
, _session
);
286 MPLS_LIST_ELEM_INIT(a
, _global
);
287 MPLS_LIST_ELEM_INIT(a
, _fs
);
288 MPLS_LIST_INIT(&a
->us_attr_root
, ldp_attr
);
289 MPLS_REFCNT_INIT(a
, 0);
290 a
->index
= _ldp_attr_get_next_index();
291 a
->in_tree
= MPLS_BOOL_FALSE
;
292 a
->ingress
= MPLS_BOOL_FALSE
;
293 a
->filtered
= MPLS_BOOL_FALSE
;
296 mpls_fec2fec_tlv(fec
, &a
->fecTlv
, 0);
297 a
->fecTlv
.numberFecElements
= 1;
304 void ldp_attr_delete(ldp_attr
* a
)
306 LDP_PRINT(g
->user_data
,"attr delete\n");
307 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_FALSE
);
311 void ldp_attr2ldp_attr(ldp_attr
* a
, ldp_attr
* b
, uint32_t flag
)
313 if (a
->fecTlvExists
&& flag
& LDP_ATTR_FEC
) {
314 memcpy(&b
->fecTlv
, &a
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
317 if (a
->genLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
318 memcpy(&b
->genLblTlv
, &a
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
319 b
->genLblTlvExists
= 1;
320 } else if (a
->atmLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
321 memcpy(&b
->atmLblTlv
, &a
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
322 b
->atmLblTlvExists
= 1;
323 } else if (a
->frLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
324 memcpy(&b
->frLblTlv
, &a
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
325 b
->frLblTlvExists
= 1;
327 if (a
->hopCountTlvExists
&& flag
& LDP_ATTR_HOPCOUNT
) {
328 memcpy(&b
->hopCountTlv
, &a
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
329 b
->hopCountTlvExists
= 1;
331 if (a
->pathVecTlvExists
&& flag
& LDP_ATTR_PATH
) {
332 memcpy(&b
->pathVecTlv
, &a
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
333 b
->pathVecTlvExists
= 1;
335 if (a
->lblMsgIdTlvExists
&& flag
& LDP_ATTR_MSGID
) {
336 memcpy(&b
->lblMsgIdTlv
, &a
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
337 b
->lblMsgIdTlvExists
= 1;
339 if (a
->lspidTlvExists
&& flag
& LDP_ATTR_LSPID
) {
340 memcpy(&b
->lspidTlv
, &a
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
341 b
->lspidTlvExists
= 1;
343 if (a
->trafficTlvExists
&& flag
& LDP_ATTR_TRAFFIC
) {
344 memcpy(&b
->trafficTlv
, &a
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
345 b
->trafficTlvExists
= 1;
349 mpls_return_enum
ldp_attr_add_inlabel(ldp_attr
* a
, ldp_inlabel
* i
)
354 _ldp_inlabel_add_attr(i
, a
);
360 mpls_return_enum
ldp_attr_del_inlabel(ldp_attr
* a
)
362 if (a
&& a
->inlabel
) {
363 _ldp_inlabel_del_attr(a
->inlabel
, a
);
364 MPLS_REFCNT_RELEASE(a
->inlabel
, ldp_inlabel_delete
);
371 mpls_return_enum
ldp_attr_add_outlabel(ldp_attr
* a
, ldp_outlabel
* o
)
376 _ldp_outlabel_add_attr(o
, a
);
382 mpls_return_enum
ldp_attr_del_outlabel(ldp_attr
* a
)
384 if (a
&& a
->outlabel
) {
385 _ldp_outlabel_del_attr(a
->outlabel
);
386 MPLS_REFCNT_RELEASE(a
->outlabel
, ldp_outlabel_delete
);
393 mpls_return_enum
ldp_attr_add_session(ldp_attr
* a
, ldp_session
* s
)
398 _ldp_session_add_attr(s
, a
);
404 mpls_return_enum
ldp_attr_del_session(ldp_attr
* a
)
406 if (a
&& a
->session
) {
407 _ldp_session_del_attr(a
->session
, a
);
408 MPLS_REFCNT_RELEASE(a
->session
, ldp_session_delete
);
415 mpls_bool
ldp_attr_is_equal(ldp_attr
* a
, ldp_attr
* b
, uint32_t flag
)
417 if (flag
& LDP_ATTR_LABEL
) {
418 if (a
->genLblTlvExists
&& b
->genLblTlvExists
) {
419 if (a
->genLblTlv
.label
!= b
->genLblTlv
.label
) {
420 return MPLS_BOOL_FALSE
;
422 } else if (a
->atmLblTlvExists
&& b
->atmLblTlvExists
) {
423 if (a
->atmLblTlv
.flags
.flags
.vpi
!= b
->atmLblTlv
.flags
.flags
.vpi
||
424 a
->atmLblTlv
.vci
!= b
->atmLblTlv
.vci
) {
425 return MPLS_BOOL_FALSE
;
427 } else if (a
->frLblTlvExists
&& b
->frLblTlvExists
) {
428 if (a
->frLblTlv
.flags
.flags
.len
!= b
->frLblTlv
.flags
.flags
.len
||
429 a
->frLblTlv
.flags
.flags
.dlci
!= b
->frLblTlv
.flags
.flags
.dlci
) {
430 return MPLS_BOOL_FALSE
;
433 return MPLS_BOOL_FALSE
;
436 if (flag
& LDP_ATTR_HOPCOUNT
) {
437 if (a
->hopCountTlvExists
&& b
->hopCountTlvExists
) {
438 if (a
->hopCountTlv
.hcValue
!= b
->hopCountTlv
.hcValue
) {
439 return MPLS_BOOL_FALSE
;
442 if (a
->hopCountTlvExists
!= b
->hopCountTlvExists
) {
443 return MPLS_BOOL_FALSE
;
447 if (flag
& LDP_ATTR_PATH
) {
450 if (a
->pathVecTlvExists
&& b
->pathVecTlvExists
) {
451 for (i
= 0; i
< MPLS_MAXHOPSNUMBER
; i
++) {
452 if (a
->pathVecTlv
.lsrId
[i
] != b
->pathVecTlv
.lsrId
[i
]) {
453 return MPLS_BOOL_FALSE
;
457 if (a
->hopCountTlvExists
!= b
->hopCountTlvExists
) {
458 return MPLS_BOOL_FALSE
;
462 if (flag
& LDP_ATTR_FEC
) {
465 if (a
->fecTlvExists
&& b
->fecTlvExists
) {
466 if (a
->fecTlv
.numberFecElements
!= b
->fecTlv
.numberFecElements
) {
467 return MPLS_BOOL_FALSE
;
469 for (i
= 0; i
< a
->fecTlv
.numberFecElements
; i
++) {
470 if (a
->fecTlv
.fecElemTypes
[i
] != b
->fecTlv
.fecElemTypes
[i
]) {
471 return MPLS_BOOL_FALSE
;
473 switch (a
->fecTlv
.fecElemTypes
[i
]) {
476 /* nothing of interest to compare */
478 case MPLS_PREFIX_FEC
:
479 case MPLS_HOSTADR_FEC
:
480 if (a
->fecTlv
.fecElArray
[i
].addressEl
.addressFam
!=
481 b
->fecTlv
.fecElArray
[i
].addressEl
.addressFam
||
482 a
->fecTlv
.fecElArray
[i
].addressEl
.preLen
!=
483 b
->fecTlv
.fecElArray
[i
].addressEl
.preLen
||
484 a
->fecTlv
.fecElArray
[i
].addressEl
.address
!=
485 b
->fecTlv
.fecElArray
[i
].addressEl
.address
) {
486 return MPLS_BOOL_FALSE
;
494 return MPLS_BOOL_FALSE
;
497 if (flag
& LDP_ATTR_MSGID
) {
498 if (a
->lblMsgIdTlvExists
&& b
->lblMsgIdTlvExists
) {
499 if (a
->lblMsgIdTlv
.msgId
!= b
->lblMsgIdTlv
.msgId
) {
500 return MPLS_BOOL_FALSE
;
503 return MPLS_BOOL_FALSE
;
506 if (flag
& LDP_ATTR_LSPID
) {
507 if (a
->lspidTlvExists
&& b
->lspidTlvExists
) {
508 if (a
->lspidTlv
.localCrlspId
!= b
->lspidTlv
.localCrlspId
||
509 a
->lspidTlv
.routerId
!= b
->lspidTlv
.routerId
) {
510 return MPLS_BOOL_FALSE
;
513 return MPLS_BOOL_FALSE
;
516 if (flag
& LDP_ATTR_TRAFFIC
) {
518 return MPLS_BOOL_TRUE
;
521 mpls_return_enum
ldp_attr_insert_upstream(ldp_global
* g
, ldp_session
* s
,
524 ldp_fec
*fnode
= NULL
;
526 mpls_return_enum retval
;
528 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_FALSE
);
530 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_TRUE
)) == NULL
) {
531 /* we couldn't get/add a node from/to the tree! */
535 /* find the upstream fs for this session */
536 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_TRUE
)) == NULL
) {
537 /* this session isn't in the list and cannot be added */
541 ldp_attr_add_session(a
, s
);
543 retval
= _ldp_fs_add_attr(fs
, a
);
544 _ldp_global_add_attr(g
, a
);
545 a
->in_tree
= MPLS_BOOL_TRUE
;
549 mpls_return_enum
ldp_attr_insert_downstream(ldp_global
* g
, ldp_session
* s
,
552 ldp_fec
*fnode
= NULL
;
554 mpls_return_enum retval
;
556 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_FALSE
);
558 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_TRUE
)) == NULL
) {
559 /* we couldn't get/add a node from/to the tree! */
563 /* find the downstream fs for this session */
564 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_TRUE
)) == NULL
) {
565 /* this session isn't in the list and cannot be added */
569 ldp_attr_add_session(a
, s
);
571 retval
= _ldp_fs_add_attr(fs
, a
);
572 _ldp_global_add_attr(g
, a
);
573 a
->in_tree
= MPLS_BOOL_TRUE
;
577 ldp_attr_list
*ldp_attr_find_upstream_all(ldp_global
* g
, ldp_session
* s
,
580 ldp_fec
*fnode
= NULL
;
583 MPLS_ASSERT(s
&& f
&& g
);
585 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
586 /* we couldn't get the node from the tree! */
590 /* find the upstream fs for this session */
591 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
592 /* this session isn't in the list */
595 return &fs
->attr_root
;
598 ldp_attr_list
*ldp_attr_find_downstream_all(ldp_global
* g
, ldp_session
* s
,
601 ldp_fec
*fnode
= NULL
;
604 MPLS_ASSERT(s
&& f
&& g
);
606 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
607 /* we couldn't get the node from the tree! */
611 /* find the downstream fs for this session */
612 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
613 /* this session isn't in the list */
616 return &fs
->attr_root
;
619 void ldp_attr_delete_upstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
621 ldp_fec
*fnode
= NULL
;
624 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
626 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
)) == NULL
) {
627 /* we couldn't get the node from the tree! */
631 /* find the upstream fs for this session */
632 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
633 /* this session isn't in the list */
637 ldp_attr_del_session(a
);
639 if (_ldp_fs_del_attr(fs
, a
) == MPLS_BOOL_TRUE
) {
640 _ldp_fec_del_fs_us(fnode
, fs
);
642 a
->in_tree
= MPLS_BOOL_FALSE
;
643 _ldp_global_del_attr(g
, a
);
646 void ldp_attr_delete_downstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
648 ldp_fec
*fnode
= NULL
;
651 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
653 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
)) == NULL
) {
654 /* we couldn't get the node from the tree! */
658 /* find the downstream fs for this session */
659 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
660 /* this session isn't in the list */
664 ldp_attr_del_session(a
);
666 if (_ldp_fs_del_attr(fs
, a
) == MPLS_BOOL_TRUE
) {
667 _ldp_fec_del_fs_ds(fnode
, fs
);
669 a
->in_tree
= MPLS_BOOL_FALSE
;
670 _ldp_global_del_attr(g
, a
);
673 void ldp_attr2mpls_label_struct(ldp_attr
* a
, mpls_label_struct
* l
)
675 if (a
->genLblTlvExists
) {
676 l
->type
= MPLS_LABEL_TYPE_GENERIC
;
677 l
->u
.gen
= a
->genLblTlv
.label
;
678 } else if (a
->atmLblTlvExists
) {
679 l
->type
= MPLS_LABEL_TYPE_ATM
;
680 l
->u
.atm
.vpi
= a
->atmLblTlv
.flags
.flags
.vpi
;
681 l
->u
.atm
.vci
= a
->atmLblTlv
.vci
;
682 } else if (a
->frLblTlvExists
) {
683 l
->type
= MPLS_LABEL_TYPE_FR
;
684 l
->u
.fr
.len
= a
->frLblTlv
.flags
.flags
.len
;
685 l
->u
.fr
.dlci
= a
->frLblTlv
.flags
.flags
.dlci
;
691 void mpls_label_struct2ldp_attr(mpls_label_struct
* l
, ldp_attr
* a
)
694 case MPLS_LABEL_TYPE_GENERIC
:
695 a
->genLblTlvExists
= 1;
696 a
->atmLblTlvExists
= 0;
697 a
->frLblTlvExists
= 0;
698 a
->genLblTlv
.label
= l
->u
.gen
;
700 case MPLS_LABEL_TYPE_ATM
:
701 a
->genLblTlvExists
= 0;
702 a
->atmLblTlvExists
= 1;
703 a
->frLblTlvExists
= 0;
704 a
->atmLblTlv
.flags
.flags
.vpi
= l
->u
.atm
.vpi
;
705 a
->atmLblTlv
.vci
= l
->u
.atm
.vci
;
706 case MPLS_LABEL_TYPE_FR
:
707 a
->genLblTlvExists
= 0;
708 a
->atmLblTlvExists
= 0;
709 a
->frLblTlvExists
= 1;
710 a
->frLblTlv
.flags
.flags
.len
= l
->u
.fr
.len
;
711 a
->frLblTlv
.flags
.flags
.dlci
= l
->u
.fr
.dlci
;
718 void ldp_attr2ldp_attr(ldp_attr
* src
, ldp_attr
* dst
, u_int32 flag
)
720 if (flag
& LDP_ATTR_FEC
) {
721 memcpy(&dst
->fecTlv
, &src
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
722 dst
->fecTlvExists
= src
->fecTlvExists
;
724 if (flag
& LDP_ATTR_LABEL
) {
725 memcpy(&dst
->genLblTlv
, &src
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
726 memcpy(&dst
->atmLblTlv
, &src
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
727 memcpy(&dst
->frLblTlv
, &src
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
728 dst
->genLblTlvExists
= src
->genLblTlvExists
729 dst
->atmLblTlvExists
= src
->atmLblTlvExists
730 dst
->frLblTlvExists
= src
->frLblTlvExists
}
731 if (flag
& LDP_ATTR_HOPCOUNT
) {
732 memcpy(&dst
->hopCountTlv
, &src
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
733 dst
->hopCountTlvExists
= src
->hopCountTlvExists
;
735 if (flag
& LDP_ATTR_PATH
) {
736 memcpy(&dst
->pathVecTlv
, &src
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
737 dst
->pathVecTlvExists
= src
->pathVecTlvExists
;
739 if (flag
& LDP_ATTR_MSGID
) {
740 memcpy(&dst
->lblMsgIdTlv
, &src
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
741 dst
->lblMsgIdTlvExists
= src
->lblMsgIdTlvExists
;
743 if (flag
& LDP_ATTR_LSPID
) {
744 memcpy(&dst
->lspidTlv
, &src
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
745 dst
->lspidTlvExists
= src
->lspidTlvExists
;
747 if (flag
& LDP_ATTR_TRAFFIC
) {
748 memcpy(&dst
->trafficTlv
, &src
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
749 dst
->trafficTlvExists
= src
->trafficTlvExists
;
754 static ldp_fec
*_ldp_attr_get_fec2(ldp_global
* g
, mpls_fec
* f
, mpls_bool flag
)
756 ldp_fec
*fnode
= NULL
;
761 case MPLS_FEC_PREFIX
:
762 key
= f
->u
.prefix
.network
.u
.ipv4
;
763 len
= f
->u
.prefix
.length
;
766 key
= f
->u
.host
.u
.ipv4
;
772 if (mpls_tree_get(g
->fec_tree
, key
, len
, (void **)&fnode
) ==
773 MPLS_FAILURE
|| fnode
== NULL
) {
775 if (flag
== MPLS_BOOL_FALSE
) {
779 /* this FEC doesn't exist in the tree yet, create one ... */
780 fnode
= ldp_fec_create();
781 mpls_fec2ldp_fec(f
, fnode
);
782 MPLS_REFCNT_HOLD(fnode
);
784 /* ... add it to the tree ... */
785 if (mpls_tree_insert(g
->fec_tree
,key
,len
,(void *)fnode
) == MPLS_FAILURE
) {
786 /* insert failed, by releasing our refcnt it will be deleted */
787 MPLS_REFCNT_RELEASE(fnode
, ldp_fec_delete
);
794 static ldp_fec
*_ldp_attr_get_fec(ldp_global
* g
, ldp_attr
* a
, mpls_bool flag
)
798 /* get FEC from attr */
799 fec_tlv2mpls_fec(&a
->fecTlv
, 0, &fec
);
800 return _ldp_attr_get_fec2(g
, &fec
, flag
);
803 static ldp_fs
*_ldp_fec_add_fs_ds(ldp_fec
* fec
, ldp_session
* s
)
805 ldp_fs
*fs
= _ldp_fec_find_fs_ds(fec
, s
, MPLS_BOOL_FALSE
);
808 fs
= _ldp_fs_create(s
);
812 MPLS_LIST_ADD_HEAD(&fec
->fs_root_ds
, fs
, _fec
, ldp_fs
);
817 static ldp_fs
*_ldp_fec_add_fs_us(ldp_fec
* fec
, ldp_session
* s
)
819 ldp_fs
*fs
= _ldp_fec_find_fs_us(fec
, s
, MPLS_BOOL_FALSE
);
822 fs
= _ldp_fs_create(s
);
826 MPLS_LIST_ADD_HEAD(&fec
->fs_root_us
, fs
, _fec
, ldp_fs
);
831 static ldp_fs
*_ldp_fec_find_fs_us(ldp_fec
* fec
, ldp_session
* s
,
834 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_us
);
837 if (fs
->session
->index
== s
->index
) {
840 fs
= MPLS_LIST_NEXT(&fec
->fs_root_us
, fs
, _fec
);
842 if (flag
== MPLS_BOOL_FALSE
) {
845 return _ldp_fec_add_fs_us(fec
, s
);
848 static ldp_fs
*_ldp_fec_find_fs_ds(ldp_fec
* fec
, ldp_session
* s
,
851 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_ds
);
854 if (fs
->session
->index
== s
->index
) {
857 fs
= MPLS_LIST_NEXT(&fec
->fs_root_ds
, fs
, _fec
);
859 if (flag
== MPLS_BOOL_FALSE
) {
862 return _ldp_fec_add_fs_ds(fec
, s
);
865 static void _ldp_fec_del_fs_us(ldp_fec
* fec
, ldp_fs
* fs
)
870 MPLS_LIST_REMOVE(&fec
->fs_root_us
, fs
, _fec
);
874 static void _ldp_fec_del_fs_ds(ldp_fec
* fec
, ldp_fs
* fs
)
879 MPLS_LIST_REMOVE(&fec
->fs_root_ds
, fs
, _fec
);
883 static ldp_fs
*_ldp_fs_create(ldp_session
* s
)
885 ldp_fs
*fs
= (ldp_fs
*) mpls_malloc(sizeof(ldp_fs
));
888 memset(fs
, 0, sizeof(ldp_fs
));
889 MPLS_LIST_INIT(&fs
->attr_root
, ldp_attr
);
890 MPLS_LIST_ELEM_INIT(fs
, _fec
);
899 static void _ldp_fs_delete(ldp_fs
* fs
)
901 LDP_PRINT(g
->user_data
,"fs delete\n");
902 if (fs
->session
!= NULL
) {
903 MPLS_REFCNT_RELEASE(fs
->session
, ldp_session_delete
);
908 static ldp_attr
*_ldp_fs_find_attr(ldp_fs
* fs
, ldp_attr
* a
)
910 ldp_attr
*ptr
= MPLS_LIST_HEAD(&fs
->attr_root
);
912 while (ptr
!= NULL
) {
913 if (ldp_attr_is_equal(a
, ptr
, LDP_ATTR_LABEL
| LDP_ATTR_FEC
) == MPLS_BOOL_TRUE
) {
916 ptr
= MPLS_LIST_NEXT(&fs
->attr_root
, ptr
, _fs
);
921 static mpls_return_enum
_ldp_fs_add_attr(ldp_fs
* fs
, ldp_attr
* a
)
923 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
925 MPLS_ASSERT(ptr
== NULL
);
927 MPLS_LIST_ADD_HEAD(&fs
->attr_root
, a
, _fs
, ldp_attr
);
931 static mpls_bool
_ldp_fs_del_attr(ldp_fs
* fs
, ldp_attr
* a
)
933 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
936 MPLS_LIST_REMOVE(&fs
->attr_root
, ptr
, _fs
);
937 MPLS_REFCNT_RELEASE(ptr
, ldp_attr_delete
);
939 if (MPLS_LIST_HEAD(&fs
->attr_root
) == NULL
)
940 return MPLS_BOOL_TRUE
;
941 return MPLS_BOOL_FALSE
;
944 static uint32_t _ldp_attr_get_next_index()
946 uint32_t retval
= _ldp_attr_next_index
;
948 _ldp_attr_next_index
++;
949 if (retval
> _ldp_attr_next_index
) {
950 _ldp_attr_next_index
= 1;