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_global
*g
, 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_global
*g
, ldp_attr
* us
, ldp_attr
* ds
)
76 if (ldp_attr_us_partof_ds(us
, ds
) == MPLS_BOOL_TRUE
) {
78 MPLS_REFCNT_RELEASE2(g
, ds
, ldp_attr_delete
);
79 MPLS_LIST_REMOVE(&ds
->us_attr_root
, us
, _ds_attr
);
80 MPLS_REFCNT_RELEASE2(g
, 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(g
, attr
);
281 ldp_session_del_outlabel(g
, session
, out
);
283 while ((us_temp
= MPLS_LIST_HEAD(&attr
->us_attr_root
)) != NULL
) {
284 ldp_attr_del_us2ds(g
, us_temp
, attr
);
286 ldp_attr_delete_downstream(g
, session
, attr
);
288 case LDP_LSP_STATE_MAP_SENT
:
292 if (in
->reuse_count
== 1 && out
) {
293 ldp_inlabel_del_outlabel(g
, in
);
295 ldp_attr_del_inlabel(g
, attr
);
296 ldp_attr_delete_upstream(g
, session
, attr
);
297 ldp_attr_del_us2ds(g
, attr
, attr
->ds_attr
);
298 ldp_session_del_inlabel(g
, session
, in
);
300 case LDP_LSP_STATE_ABORT_SENT
:
301 case LDP_LSP_STATE_NOTIF_SENT
:
302 case LDP_LSP_STATE_REQ_RECV
:
303 case LDP_LSP_STATE_WITH_SENT
:
304 case LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT
:
306 ldp_attr_del_us2ds(g
, attr
, attr
->ds_attr
);
307 ldp_attr_delete_upstream(g
, session
, attr
);
310 case LDP_LSP_STATE_ABORT_RECV
:
311 case LDP_LSP_STATE_NOTIF_RECV
:
312 case LDP_LSP_STATE_REQ_SENT
:
313 case LDP_LSP_STATE_WITH_RECV
:
314 case LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV
:
316 while ((us_temp
= MPLS_LIST_HEAD(&attr
->us_attr_root
)) != NULL
) {
317 ldp_attr_del_us2ds(g
, us_temp
, attr
);
319 ldp_attr_delete_downstream(g
, session
, attr
);
325 ldp_attr
*ldp_attr_create(ldp_global
*g
, mpls_fec
* fec
)
327 ldp_attr
*a
= (ldp_attr
*) mpls_malloc(sizeof(ldp_attr
));
330 memset(a
, 0, sizeof(ldp_attr
));
331 MPLS_LIST_ELEM_INIT(a
, _session
);
332 MPLS_LIST_ELEM_INIT(a
, _global
);
333 MPLS_LIST_ELEM_INIT(a
, _fs
);
334 MPLS_LIST_INIT(&a
->us_attr_root
, ldp_attr
);
335 MPLS_REFCNT_INIT(a
, 0);
336 a
->index
= _ldp_attr_get_next_index();
337 a
->in_tree
= MPLS_BOOL_FALSE
;
338 a
->ingress
= MPLS_BOOL_FALSE
;
339 a
->filtered
= MPLS_BOOL_FALSE
;
342 mpls_fec2fec_tlv(fec
, &a
->fecTlv
, 0);
343 a
->fecTlv
.numberFecElements
= 1;
346 _ldp_global_add_attr(g
, a
);
351 void ldp_attr_delete(ldp_global
*g
, ldp_attr
* a
)
353 fprintf(stderr
, "attr delete: %p\n", a
);
354 MPLS_REFCNT_ASSERT(a
, 0);
355 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_FALSE
);
356 _ldp_global_del_attr(g
, a
);
360 void ldp_attr2ldp_attr(ldp_attr
* a
, ldp_attr
* b
, uint32_t flag
)
362 if (a
->fecTlvExists
&& flag
& LDP_ATTR_FEC
) {
363 memcpy(&b
->fecTlv
, &a
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
366 if (a
->genLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
367 memcpy(&b
->genLblTlv
, &a
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
368 b
->genLblTlvExists
= 1;
369 } else if (a
->atmLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
370 memcpy(&b
->atmLblTlv
, &a
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
371 b
->atmLblTlvExists
= 1;
372 } else if (a
->frLblTlvExists
&& flag
& LDP_ATTR_LABEL
) {
373 memcpy(&b
->frLblTlv
, &a
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
374 b
->frLblTlvExists
= 1;
376 if (a
->hopCountTlvExists
&& flag
& LDP_ATTR_HOPCOUNT
) {
377 memcpy(&b
->hopCountTlv
, &a
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
378 b
->hopCountTlvExists
= 1;
380 if (a
->pathVecTlvExists
&& flag
& LDP_ATTR_PATH
) {
381 memcpy(&b
->pathVecTlv
, &a
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
382 b
->pathVecTlvExists
= 1;
384 if (a
->lblMsgIdTlvExists
&& flag
& LDP_ATTR_MSGID
) {
385 memcpy(&b
->lblMsgIdTlv
, &a
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
386 b
->lblMsgIdTlvExists
= 1;
388 if (a
->lspidTlvExists
&& flag
& LDP_ATTR_LSPID
) {
389 memcpy(&b
->lspidTlv
, &a
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
390 b
->lspidTlvExists
= 1;
392 if (a
->trafficTlvExists
&& flag
& LDP_ATTR_TRAFFIC
) {
393 memcpy(&b
->trafficTlv
, &a
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
394 b
->trafficTlvExists
= 1;
398 mpls_return_enum
ldp_attr_add_inlabel(ldp_global
*g
, ldp_attr
* a
, ldp_inlabel
* i
)
403 _ldp_inlabel_add_attr(g
, i
, a
);
409 mpls_return_enum
ldp_attr_del_inlabel(ldp_global
*g
, ldp_attr
* a
)
411 if (a
&& a
->inlabel
) {
412 _ldp_inlabel_del_attr(g
, a
->inlabel
, a
);
413 MPLS_REFCNT_RELEASE2(g
, a
->inlabel
, ldp_inlabel_delete
);
420 mpls_return_enum
ldp_attr_add_outlabel(ldp_attr
* a
, ldp_outlabel
* o
)
425 _ldp_outlabel_add_attr(o
, a
);
431 mpls_return_enum
ldp_attr_del_outlabel(ldp_global
* g
, ldp_attr
* a
)
433 if (a
&& a
->outlabel
) {
434 _ldp_outlabel_del_attr(g
, a
->outlabel
);
435 MPLS_REFCNT_RELEASE2(g
, a
->outlabel
, ldp_outlabel_delete
);
442 mpls_return_enum
ldp_attr_add_session(ldp_attr
* a
, ldp_session
* s
)
447 _ldp_session_add_attr(s
, a
);
453 mpls_return_enum
ldp_attr_del_session(ldp_global
*g
, ldp_attr
* a
)
455 if (a
&& a
->session
) {
456 _ldp_session_del_attr(g
, a
->session
, a
);
457 MPLS_REFCNT_RELEASE(a
->session
, ldp_session_delete
);
464 mpls_bool
ldp_attr_is_equal(ldp_attr
* a
, ldp_attr
* b
, uint32_t flag
)
466 if (flag
& LDP_ATTR_LABEL
) {
467 if (a
->genLblTlvExists
&& b
->genLblTlvExists
) {
468 if (a
->genLblTlv
.label
!= b
->genLblTlv
.label
) {
469 return MPLS_BOOL_FALSE
;
471 } else if (a
->atmLblTlvExists
&& b
->atmLblTlvExists
) {
472 if (a
->atmLblTlv
.flags
.flags
.vpi
!= b
->atmLblTlv
.flags
.flags
.vpi
||
473 a
->atmLblTlv
.vci
!= b
->atmLblTlv
.vci
) {
474 return MPLS_BOOL_FALSE
;
476 } else if (a
->frLblTlvExists
&& b
->frLblTlvExists
) {
477 if (a
->frLblTlv
.flags
.flags
.len
!= b
->frLblTlv
.flags
.flags
.len
||
478 a
->frLblTlv
.flags
.flags
.dlci
!= b
->frLblTlv
.flags
.flags
.dlci
) {
479 return MPLS_BOOL_FALSE
;
482 return MPLS_BOOL_FALSE
;
485 if (flag
& LDP_ATTR_HOPCOUNT
) {
486 if (a
->hopCountTlvExists
&& b
->hopCountTlvExists
) {
487 if (a
->hopCountTlv
.hcValue
!= b
->hopCountTlv
.hcValue
) {
488 return MPLS_BOOL_FALSE
;
491 if (a
->hopCountTlvExists
!= b
->hopCountTlvExists
) {
492 return MPLS_BOOL_FALSE
;
496 if (flag
& LDP_ATTR_PATH
) {
499 if (a
->pathVecTlvExists
&& b
->pathVecTlvExists
) {
500 for (i
= 0; i
< MPLS_MAXHOPSNUMBER
; i
++) {
501 if (a
->pathVecTlv
.lsrId
[i
] != b
->pathVecTlv
.lsrId
[i
]) {
502 return MPLS_BOOL_FALSE
;
506 if (a
->hopCountTlvExists
!= b
->hopCountTlvExists
) {
507 return MPLS_BOOL_FALSE
;
511 if (flag
& LDP_ATTR_FEC
) {
514 if (a
->fecTlvExists
&& b
->fecTlvExists
) {
515 if (a
->fecTlv
.numberFecElements
!= b
->fecTlv
.numberFecElements
) {
516 return MPLS_BOOL_FALSE
;
518 for (i
= 0; i
< a
->fecTlv
.numberFecElements
; i
++) {
519 if (a
->fecTlv
.fecElemTypes
[i
] != b
->fecTlv
.fecElemTypes
[i
]) {
520 return MPLS_BOOL_FALSE
;
522 switch (a
->fecTlv
.fecElemTypes
[i
]) {
525 /* nothing of interest to compare */
527 case MPLS_PREFIX_FEC
:
528 case MPLS_HOSTADR_FEC
:
529 if (a
->fecTlv
.fecElArray
[i
].addressEl
.addressFam
!=
530 b
->fecTlv
.fecElArray
[i
].addressEl
.addressFam
||
531 a
->fecTlv
.fecElArray
[i
].addressEl
.preLen
!=
532 b
->fecTlv
.fecElArray
[i
].addressEl
.preLen
||
533 a
->fecTlv
.fecElArray
[i
].addressEl
.address
!=
534 b
->fecTlv
.fecElArray
[i
].addressEl
.address
) {
535 return MPLS_BOOL_FALSE
;
543 return MPLS_BOOL_FALSE
;
546 if (flag
& LDP_ATTR_MSGID
) {
547 if (a
->lblMsgIdTlvExists
&& b
->lblMsgIdTlvExists
) {
548 if (a
->lblMsgIdTlv
.msgId
!= b
->lblMsgIdTlv
.msgId
) {
549 return MPLS_BOOL_FALSE
;
552 return MPLS_BOOL_FALSE
;
555 if (flag
& LDP_ATTR_LSPID
) {
556 if (a
->lspidTlvExists
&& b
->lspidTlvExists
) {
557 if (a
->lspidTlv
.localCrlspId
!= b
->lspidTlv
.localCrlspId
||
558 a
->lspidTlv
.routerId
!= b
->lspidTlv
.routerId
) {
559 return MPLS_BOOL_FALSE
;
562 return MPLS_BOOL_FALSE
;
565 if (flag
& LDP_ATTR_TRAFFIC
) {
567 return MPLS_BOOL_TRUE
;
570 mpls_return_enum
ldp_attr_insert_upstream2(ldp_global
* g
, ldp_session
* s
,
571 ldp_attr
* a
, ldp_fec
*f
)
574 mpls_return_enum retval
;
576 MPLS_ASSERT(g
&& s
&& a
&& (a
->in_tree
== MPLS_BOOL_FALSE
) && f
);
578 /* find the upstream fs for this session */
579 if ((fs
= _ldp_fec_find_fs_us(f
, s
, MPLS_BOOL_TRUE
)) == NULL
) {
580 /* this session isn't in the list and cannot be added */
584 ldp_attr_add_session(a
, s
);
585 ldp_attr_add_fec(a
, f
);
587 retval
= _ldp_fs_add_attr(fs
, a
);
588 a
->in_tree
= MPLS_BOOL_TRUE
;
592 mpls_return_enum
ldp_attr_insert_upstream(ldp_global
* g
, ldp_session
* s
,
595 ldp_fec
*fnode
= NULL
;
597 MPLS_ASSERT(g
&& s
&& a
&& (a
->in_tree
== MPLS_BOOL_FALSE
));
599 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_TRUE
)) == NULL
) {
600 /* we couldn't get/add a node from/to the tree! */
604 return ldp_attr_insert_upstream2(g
, s
, a
, fnode
);
607 mpls_return_enum
ldp_attr_insert_downstream2(ldp_global
* g
, ldp_session
* s
,
608 ldp_attr
* a
, ldp_fec
*f
)
611 mpls_return_enum retval
;
613 MPLS_ASSERT(g
&& s
&& a
&& (a
->in_tree
== MPLS_BOOL_FALSE
) && f
);
615 /* find the downstream fs for this session */
616 if ((fs
= _ldp_fec_find_fs_ds(f
, s
, MPLS_BOOL_TRUE
)) == NULL
) {
617 /* this session isn't in the list and cannot be added */
621 ldp_attr_add_session(a
, s
);
622 ldp_attr_add_fec(a
, f
);
624 retval
= _ldp_fs_add_attr(fs
, a
);
625 a
->in_tree
= MPLS_BOOL_TRUE
;
629 mpls_return_enum
ldp_attr_insert_downstream(ldp_global
* g
, ldp_session
* s
,
632 ldp_fec
*fnode
= NULL
;
634 MPLS_ASSERT(g
&& s
&& a
&& (a
->in_tree
== MPLS_BOOL_FALSE
));
636 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_TRUE
)) == NULL
) {
637 /* we couldn't get/add a node from/to the tree! */
641 return ldp_attr_insert_downstream2(g
, s
, a
, fnode
);
644 ldp_attr_list
*ldp_attr_find_upstream_all2(ldp_global
* g
, ldp_session
* s
,
655 /* find the upstream fs for this session */
656 if ((fs
= _ldp_fec_find_fs_us(f
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
657 /* this session isn't in the list */
660 return &fs
->attr_root
;
663 ldp_attr_list
*ldp_attr_find_upstream_all(ldp_global
* g
, ldp_session
* s
,
666 ldp_fec
*fnode
= NULL
;
674 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
675 /* we couldn't get the node from the tree! */
679 return ldp_attr_find_upstream_all2(g
, s
, fnode
);
682 ldp_attr_list
*ldp_attr_find_downstream_all2(ldp_global
* g
, ldp_session
* s
,
693 /* find the downstream fs for this session */
694 if ((fs
= _ldp_fec_find_fs_ds(f
, s
, MPLS_BOOL_FALSE
)) == NULL
) {
695 /* this session isn't in the list */
698 return &fs
->attr_root
;
701 ldp_attr_list
*ldp_attr_find_downstream_all(ldp_global
* g
, ldp_session
* s
,
704 ldp_fec
*fnode
= NULL
;
712 if ((fnode
= _ldp_attr_get_fec2(g
, f
, MPLS_BOOL_FALSE
)) == NULL
) {
713 /* we couldn't get the node from the tree! */
717 return ldp_attr_find_downstream_all2(g
, s
, fnode
);
720 void ldp_attr_delete_upstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
722 ldp_fec
*fnode
= NULL
;
725 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
729 /* find the fec node in the tree */
730 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
))) {
731 /* find the upstream fs for this session, on the fec */
732 if ((fs
= _ldp_fec_find_fs_us(fnode
, s
, MPLS_BOOL_FALSE
))) {
733 /* remove this attr from the fs, if this was the last
734 * attr on the fs, then remove the fs from the fec node
736 if (_ldp_fs_del_attr(g
, fs
, a
) == MPLS_BOOL_TRUE
) {
737 _ldp_fec_del_fs_us(fnode
, fs
);
742 ldp_attr_del_session(g
, a
);
743 ldp_attr_del_fec(g
, a
);
745 a
->in_tree
= MPLS_BOOL_FALSE
;
746 MPLS_REFCNT_RELEASE2(g
, a
, ldp_attr_delete
);
749 void ldp_attr_delete_downstream(ldp_global
* g
, ldp_session
* s
, ldp_attr
* a
)
751 ldp_fec
*fnode
= NULL
;
754 MPLS_ASSERT(a
->in_tree
== MPLS_BOOL_TRUE
);
757 /* see ldp_attr_delete_upstream for more info */
758 if ((fnode
= _ldp_attr_get_fec(g
, a
, MPLS_BOOL_FALSE
))) {
759 if ((fs
= _ldp_fec_find_fs_ds(fnode
, s
, MPLS_BOOL_FALSE
))) {
760 if (_ldp_fs_del_attr(g
, fs
, a
) == MPLS_BOOL_TRUE
) {
761 _ldp_fec_del_fs_ds(fnode
, fs
);
766 ldp_attr_del_session(g
, a
);
767 ldp_attr_del_fec(g
, a
);
769 a
->in_tree
= MPLS_BOOL_FALSE
;
770 MPLS_REFCNT_RELEASE2(g
, a
, ldp_attr_delete
);
773 void ldp_attr2mpls_label_struct(ldp_attr
* a
, mpls_label_struct
* l
)
775 if (a
->genLblTlvExists
) {
776 l
->type
= MPLS_LABEL_TYPE_GENERIC
;
777 l
->u
.gen
= a
->genLblTlv
.label
;
778 } else if (a
->atmLblTlvExists
) {
779 l
->type
= MPLS_LABEL_TYPE_ATM
;
780 l
->u
.atm
.vpi
= a
->atmLblTlv
.flags
.flags
.vpi
;
781 l
->u
.atm
.vci
= a
->atmLblTlv
.vci
;
782 } else if (a
->frLblTlvExists
) {
783 l
->type
= MPLS_LABEL_TYPE_FR
;
784 l
->u
.fr
.len
= a
->frLblTlv
.flags
.flags
.len
;
785 l
->u
.fr
.dlci
= a
->frLblTlv
.flags
.flags
.dlci
;
791 void mpls_label_struct2ldp_attr(mpls_label_struct
* l
, ldp_attr
* a
)
794 case MPLS_LABEL_TYPE_GENERIC
:
795 a
->genLblTlvExists
= 1;
796 a
->atmLblTlvExists
= 0;
797 a
->frLblTlvExists
= 0;
798 a
->genLblTlv
.label
= l
->u
.gen
;
800 case MPLS_LABEL_TYPE_ATM
:
801 a
->genLblTlvExists
= 0;
802 a
->atmLblTlvExists
= 1;
803 a
->frLblTlvExists
= 0;
804 a
->atmLblTlv
.flags
.flags
.vpi
= l
->u
.atm
.vpi
;
805 a
->atmLblTlv
.vci
= l
->u
.atm
.vci
;
806 case MPLS_LABEL_TYPE_FR
:
807 a
->genLblTlvExists
= 0;
808 a
->atmLblTlvExists
= 0;
809 a
->frLblTlvExists
= 1;
810 a
->frLblTlv
.flags
.flags
.len
= l
->u
.fr
.len
;
811 a
->frLblTlv
.flags
.flags
.dlci
= l
->u
.fr
.dlci
;
818 void ldp_attr2ldp_attr(ldp_attr
* src
, ldp_attr
* dst
, u_int32 flag
)
820 if (flag
& LDP_ATTR_FEC
) {
821 memcpy(&dst
->fecTlv
, &src
->fecTlv
, sizeof(mplsLdpFecTlv_t
));
822 dst
->fecTlvExists
= src
->fecTlvExists
;
824 if (flag
& LDP_ATTR_LABEL
) {
825 memcpy(&dst
->genLblTlv
, &src
->genLblTlv
, sizeof(mplsLdpGenLblTlv_t
));
826 memcpy(&dst
->atmLblTlv
, &src
->atmLblTlv
, sizeof(mplsLdpAtmLblTlv_t
));
827 memcpy(&dst
->frLblTlv
, &src
->frLblTlv
, sizeof(mplsLdpFrLblTlv_t
));
828 dst
->genLblTlvExists
= src
->genLblTlvExists
829 dst
->atmLblTlvExists
= src
->atmLblTlvExists
830 dst
->frLblTlvExists
= src
->frLblTlvExists
}
831 if (flag
& LDP_ATTR_HOPCOUNT
) {
832 memcpy(&dst
->hopCountTlv
, &src
->hopCountTlv
, sizeof(mplsLdpHopTlv_t
));
833 dst
->hopCountTlvExists
= src
->hopCountTlvExists
;
835 if (flag
& LDP_ATTR_PATH
) {
836 memcpy(&dst
->pathVecTlv
, &src
->pathVecTlv
, sizeof(mplsLdpPathTlv_t
));
837 dst
->pathVecTlvExists
= src
->pathVecTlvExists
;
839 if (flag
& LDP_ATTR_MSGID
) {
840 memcpy(&dst
->lblMsgIdTlv
, &src
->lblMsgIdTlv
, sizeof(mplsLdpLblMsgIdTlv_t
));
841 dst
->lblMsgIdTlvExists
= src
->lblMsgIdTlvExists
;
843 if (flag
& LDP_ATTR_LSPID
) {
844 memcpy(&dst
->lspidTlv
, &src
->lspidTlv
, sizeof(mplsLdpLspIdTlv_t
));
845 dst
->lspidTlvExists
= src
->lspidTlvExists
;
847 if (flag
& LDP_ATTR_TRAFFIC
) {
848 memcpy(&dst
->trafficTlv
, &src
->trafficTlv
, sizeof(mplsLdpTrafficTlv_t
));
849 dst
->trafficTlvExists
= src
->trafficTlvExists
;
854 ldp_fec
*_ldp_attr_get_fec2(ldp_global
* g
, mpls_fec
* f
, mpls_bool flag
)
856 ldp_fec
*fnode
= NULL
;
858 if (!(fnode
= ldp_fec_find(g
,f
))) {
859 if (flag
== MPLS_BOOL_FALSE
) {
863 /* this FEC doesn't exist in the tree yet, create one ... */
864 if (!(fnode
= ldp_fec_create(g
, f
))) {
872 static ldp_fec
*_ldp_attr_get_fec(ldp_global
* g
, ldp_attr
* a
, mpls_bool flag
)
876 /* get FEC from attr */
877 fec_tlv2mpls_fec(&a
->fecTlv
, 0, &fec
);
878 return _ldp_attr_get_fec2(g
, &fec
, flag
);
881 static ldp_fs
*_ldp_fec_add_fs_ds(ldp_fec
* fec
, ldp_session
* s
)
883 ldp_fs
*fs
= _ldp_fec_find_fs_ds(fec
, s
, MPLS_BOOL_FALSE
);
886 fs
= _ldp_fs_create(s
);
890 MPLS_LIST_ADD_HEAD(&fec
->fs_root_ds
, fs
, _fec
, ldp_fs
);
895 static ldp_fs
*_ldp_fec_add_fs_us(ldp_fec
* fec
, ldp_session
* s
)
897 ldp_fs
*fs
= _ldp_fec_find_fs_us(fec
, s
, MPLS_BOOL_FALSE
);
900 fs
= _ldp_fs_create(s
);
904 MPLS_LIST_ADD_HEAD(&fec
->fs_root_us
, fs
, _fec
, ldp_fs
);
909 static ldp_fs
*_ldp_fec_find_fs_us(ldp_fec
* fec
, ldp_session
* s
,
912 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_us
);
915 if (fs
->session
->index
== s
->index
) {
918 fs
= MPLS_LIST_NEXT(&fec
->fs_root_us
, fs
, _fec
);
920 if (flag
== MPLS_BOOL_FALSE
) {
923 return _ldp_fec_add_fs_us(fec
, s
);
926 static ldp_fs
*_ldp_fec_find_fs_ds(ldp_fec
* fec
, ldp_session
* s
,
929 ldp_fs
*fs
= MPLS_LIST_HEAD(&fec
->fs_root_ds
);
932 if (fs
->session
->index
== s
->index
) {
935 fs
= MPLS_LIST_NEXT(&fec
->fs_root_ds
, fs
, _fec
);
937 if (flag
== MPLS_BOOL_FALSE
) {
940 return _ldp_fec_add_fs_ds(fec
, s
);
943 static void _ldp_fec_del_fs_us(ldp_fec
* fec
, ldp_fs
* fs
)
948 MPLS_LIST_REMOVE(&fec
->fs_root_us
, fs
, _fec
);
952 static void _ldp_fec_del_fs_ds(ldp_fec
* fec
, ldp_fs
* fs
)
957 MPLS_LIST_REMOVE(&fec
->fs_root_ds
, fs
, _fec
);
961 static ldp_fs
*_ldp_fs_create(ldp_session
* s
)
963 ldp_fs
*fs
= (ldp_fs
*) mpls_malloc(sizeof(ldp_fs
));
966 memset(fs
, 0, sizeof(ldp_fs
));
967 MPLS_LIST_INIT(&fs
->attr_root
, ldp_attr
);
968 MPLS_LIST_ELEM_INIT(fs
, _fec
);
977 static void _ldp_fs_delete(ldp_fs
* fs
)
979 fprintf(stderr
, "fs delete %p\n", fs
);
980 if (fs
->session
!= NULL
) {
981 MPLS_REFCNT_RELEASE(fs
->session
, ldp_session_delete
);
986 static ldp_attr
*_ldp_fs_find_attr(ldp_fs
* fs
, ldp_attr
* a
)
988 ldp_attr
*ptr
= MPLS_LIST_HEAD(&fs
->attr_root
);
990 while (ptr
!= NULL
) {
991 if (ldp_attr_is_equal(a
, ptr
, LDP_ATTR_LABEL
| LDP_ATTR_FEC
) == MPLS_BOOL_TRUE
) {
994 ptr
= MPLS_LIST_NEXT(&fs
->attr_root
, ptr
, _fs
);
999 static mpls_return_enum
_ldp_fs_add_attr(ldp_fs
* fs
, ldp_attr
* a
)
1001 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
1003 MPLS_ASSERT(ptr
== NULL
);
1004 MPLS_REFCNT_HOLD(a
);
1005 MPLS_LIST_ADD_HEAD(&fs
->attr_root
, a
, _fs
, ldp_attr
);
1006 return MPLS_SUCCESS
;
1009 static mpls_bool
_ldp_fs_del_attr(ldp_global
*g
, ldp_fs
* fs
, ldp_attr
* a
)
1011 ldp_attr
*ptr
= _ldp_fs_find_attr(fs
, a
);
1014 MPLS_LIST_REMOVE(&fs
->attr_root
, ptr
, _fs
);
1015 MPLS_REFCNT_RELEASE2(g
, ptr
, ldp_attr_delete
);
1017 if (MPLS_LIST_HEAD(&fs
->attr_root
) == NULL
)
1018 return MPLS_BOOL_TRUE
;
1019 return MPLS_BOOL_FALSE
;
1022 ldp_attr
*ldp_attr_find_upstream_map_in_labelspace(ldp_fec
*f
, int labelspace
)
1024 ldp_fs
*fs
= MPLS_LIST_HEAD(&f
->fs_root_us
);
1026 fprintf(stderr
, "ldp_attr_find_upstream_map_in_labelspace: enter\n");
1028 ldp_attr
*attr
= MPLS_LIST_HEAD(&fs
->attr_root
);
1029 fprintf(stderr
, "FS: %p\n", fs
);
1031 fprintf(stderr
, "ATTR: %p\n", fs
);
1032 if (attr
->state
== LDP_LSP_STATE_MAP_SENT
) {
1033 fprintf(stderr
, "SESSION: %p\n", attr
->session
);
1034 if (attr
->session
->cfg_label_space
== labelspace
) {
1035 fprintf(stderr
, "ldp_attr_find_upstream_map_in_labelspace: exit\n");
1039 attr
= MPLS_LIST_NEXT(&fs
->attr_root
, attr
, _fs
);
1041 fs
= MPLS_LIST_NEXT(&f
->fs_root_us
, fs
, _fec
);
1043 fprintf(stderr
, "ldp_attr_find_upstream_map_in_labelspace: exit\n");
1047 static uint32_t _ldp_attr_get_next_index()
1049 uint32_t retval
= _ldp_attr_next_index
;
1051 _ldp_attr_next_index
++;
1052 if (retval
> _ldp_attr_next_index
) {
1053 _ldp_attr_next_index
= 1;