Add additional comments
[mpls-ldp-portable.git] / ldp / ldp_attr.c
blob28d23b96254b4f02249cc6357e9eb1f8111eb237
2 /*
3 * Copyright (C) James R. Leu 2000
4 * jleu@mindspring.com
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
8 */
10 #include "ldp_struct.h"
11 #include "ldp_label_mapping.h"
12 #include "ldp_attr.h"
13 #include "ldp_if.h"
14 #include "ldp_addr.h"
15 #include "ldp_fec.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"
25 #if MPLS_USE_LSR
26 #include "lsr_cfg.h"
27 #else
28 #include "mpls_mpls_impl.h"
29 #endif
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,
36 mpls_bool flag);
37 static ldp_fs *_ldp_fec_find_fs_ds(ldp_fec * fec, ldp_session * s,
38 mpls_bool flag);
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;
53 int count = 0;
55 attr = MPLS_LIST_HEAD(&ds->us_attr_root);
56 while (attr) {
57 count++;
58 attr = MPLS_LIST_NEXT(&ds->us_attr_root, attr, _ds_attr);
60 return count;
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)
73 if (!us || !ds) {
74 return;
76 if (ldp_attr_us_partof_ds(us, ds) == MPLS_BOOL_TRUE) {
77 us->ds_attr = NULL;
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);
81 } else {
82 MPLS_ASSERT(0);
86 void ldp_attr_add_fec(ldp_attr *a, ldp_fec *fec) {
87 MPLS_ASSERT(a && fec);
88 MPLS_REFCNT_HOLD(fec);
89 a->fec = fec;
92 void ldp_attr_del_fec(ldp_global *g, ldp_attr *a) {
93 MPLS_ASSERT(a);
94 if (a->fec) {
95 MPLS_REFCNT_RELEASE2(g, a->fec, ldp_fec_delete);
96 a->fec = NULL;
100 void ldp_attr_add_us2ds(ldp_attr * us, ldp_attr * ds)
103 if (!us || !ds) {
104 return;
106 if (ldp_attr_us_partof_ds(us, ds) == MPLS_BOOL_TRUE) {
107 return;
109 MPLS_REFCNT_HOLD(us);
110 MPLS_LIST_ADD_TAIL(&ds->us_attr_root, us, _ds_attr, ldp_attr);
111 MPLS_REFCNT_HOLD(ds);
112 us->ds_attr = ds;
115 void ldp_attr_action_callback(mpls_timer_handle timer, void *extra,
116 mpls_cfg_handle g)
120 ldp_attr *ldp_attr_find_downstream_state_any2(ldp_global * g, ldp_fec * f,
121 ldp_lsp_state state)
123 ldp_attr *attr = NULL;
124 ldp_fs *fs = NULL;
126 fs = MPLS_LIST_HEAD(&f->fs_root_ds);
127 while (fs != NULL) {
128 attr = MPLS_LIST_HEAD(&fs->attr_root);
129 while (attr != NULL) {
130 if (attr->state == state) {
131 return attr;
133 attr = MPLS_LIST_NEXT(&fs->attr_root, attr, _fs);
135 fs = MPLS_LIST_NEXT(&f->fs_root_ds, fs, _fec);
137 return NULL;
140 ldp_attr *ldp_attr_find_downstream_state_any(ldp_global * g, mpls_fec * f,
141 ldp_lsp_state state)
143 ldp_fec *fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE);
145 if (!fnode) {
146 return NULL;
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,
153 ldp_lsp_state state)
155 ldp_attr *attr = NULL;
156 ldp_fs *fs = NULL;
158 fs = MPLS_LIST_HEAD(&f->fs_root_us);
159 while (fs != NULL) {
160 attr = MPLS_LIST_HEAD(&fs->attr_root);
161 while (attr != NULL) {
162 if (attr->state == state) {
163 return attr;
165 attr = MPLS_LIST_NEXT(&fs->attr_root, attr, _fs);
167 fs = MPLS_LIST_NEXT(&f->fs_root_us, fs, _fec);
169 return NULL;
172 ldp_attr *ldp_attr_find_upstream_state_any(ldp_global * g, mpls_fec * f,
173 ldp_lsp_state state)
175 ldp_fec *fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE);
177 if (!fnode) {
178 return NULL;
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,
185 ldp_lsp_state state)
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) {
192 return ds_attr;
194 ds_attr = MPLS_LIST_NEXT(ds_list, ds_attr, _fs);
197 return NULL;
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,
215 ldp_lsp_state state)
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) {
222 return us_attr;
224 us_attr = MPLS_LIST_NEXT(us_list, us_attr, _fs);
227 return NULL;
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,
245 mpls_bool complete)
247 ldp_session *session = attr->session;
248 ldp_outlabel *out = NULL;
249 ldp_inlabel *in = NULL;
250 ldp_attr *us_temp = NULL;
251 mpls_fec fec;
252 int i;
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);
266 out->merge_count--;
267 #if MPLS_USE_LSR
269 lsr_ftn ftn;
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);
274 #else
275 mpls_mpls_fec2out_del(g->mpls_handle, &fec, &out->info);
276 #endif
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);
288 break;
289 case LDP_LSP_STATE_MAP_SENT:
290 in = attr->inlabel;
291 out = in->outlabel;
293 if (out != NULL) {
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);
307 break;
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);
316 break;
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);
328 break;
333 ldp_attr *ldp_attr_create(mpls_fec * fec)
335 ldp_attr *a = (ldp_attr *) mpls_malloc(sizeof(ldp_attr));
337 if (a != NULL) {
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;
349 if (fec != NULL) {
350 mpls_fec2fec_tlv(fec, &a->fecTlv, 0);
351 a->fecTlv.numberFecElements = 1;
352 a->fecTlvExists = 1;
355 return a;
358 void ldp_attr_delete(ldp_attr * a)
360 fprintf(stderr, "attr delete: %p\n", a);
361 MPLS_ASSERT(a->in_tree == MPLS_BOOL_FALSE);
362 mpls_free(a);
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));
369 b->fecTlvExists = 1;
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)
405 if (a && i) {
406 MPLS_REFCNT_HOLD(i);
407 a->inlabel = i;
408 _ldp_inlabel_add_attr(i, a);
409 return MPLS_SUCCESS;
411 return MPLS_FAILURE;
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);
419 a->inlabel = NULL;
420 return MPLS_SUCCESS;
422 return MPLS_FAILURE;
425 mpls_return_enum ldp_attr_add_outlabel(ldp_attr * a, ldp_outlabel * o)
427 if (a && o) {
428 MPLS_REFCNT_HOLD(o);
429 a->outlabel = o;
430 _ldp_outlabel_add_attr(o, a);
431 return MPLS_SUCCESS;
433 return MPLS_FAILURE;
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);
441 a->outlabel = NULL;
442 return MPLS_SUCCESS;
444 return MPLS_FAILURE;
447 mpls_return_enum ldp_attr_add_session(ldp_attr * a, ldp_session * s)
449 if (a && s) {
450 MPLS_REFCNT_HOLD(s);
451 a->session = s;
452 _ldp_session_add_attr(s, a);
453 return MPLS_SUCCESS;
455 return MPLS_FAILURE;
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);
463 a->session = NULL;
464 return MPLS_SUCCESS;
466 return MPLS_FAILURE;
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;
486 } else {
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;
495 } else {
496 if (a->hopCountTlvExists != b->hopCountTlvExists) {
497 return MPLS_BOOL_FALSE;
501 if (flag & LDP_ATTR_PATH) {
502 int i;
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;
510 } else {
511 if (a->hopCountTlvExists != b->hopCountTlvExists) {
512 return MPLS_BOOL_FALSE;
516 if (flag & LDP_ATTR_FEC) {
517 int i;
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]) {
528 case MPLS_CRLSP_FEC:
529 case MPLS_WC_FEC:
530 /* nothing of interest to compare */
531 break;
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;
542 break;
543 default:
544 MPLS_ASSERT(0);
547 } else {
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;
556 } else {
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;
566 } else {
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)
578 ldp_fs *fs = NULL;
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 */
586 return MPLS_FAILURE;
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;
595 return retval;
598 mpls_return_enum ldp_attr_insert_upstream(ldp_global * g, ldp_session * s,
599 ldp_attr * a)
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! */
607 return MPLS_FAILURE;
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)
616 ldp_fs *fs = NULL;
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 */
624 return MPLS_FAILURE;
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;
633 return retval;
636 mpls_return_enum ldp_attr_insert_downstream(ldp_global * g, ldp_session * s,
637 ldp_attr * a)
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! */
645 return MPLS_FAILURE;
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,
652 ldp_fec * f)
654 ldp_fs *fs = NULL;
656 MPLS_ASSERT(f && g);
658 if (!s) {
659 return NULL;
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 */
665 return NULL;
667 return &fs->attr_root;
670 ldp_attr_list *ldp_attr_find_upstream_all(ldp_global * g, ldp_session * s,
671 mpls_fec * f)
673 ldp_fec *fnode = NULL;
675 MPLS_ASSERT(f && g);
677 if (!s) {
678 return NULL;
681 if ((fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE)) == NULL) {
682 /* we couldn't get the node from the tree! */
683 return NULL;
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,
690 ldp_fec * f)
692 ldp_fs *fs = NULL;
694 MPLS_ASSERT(f && g);
696 if (!s) {
697 return NULL;
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 */
703 return NULL;
705 return &fs->attr_root;
708 ldp_attr_list *ldp_attr_find_downstream_all(ldp_global * g, ldp_session * s,
709 mpls_fec * f)
711 ldp_fec *fnode = NULL;
713 MPLS_ASSERT(f && g);
715 if (!s) {
716 return NULL;
719 if ((fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE)) == NULL) {
720 /* we couldn't get the node from the tree! */
721 return NULL;
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;
730 ldp_fs *fs = 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! */
736 return;
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 */
742 return;
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;
758 ldp_fs *fs = 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! */
764 return;
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 */
770 return;
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;
796 } else {
797 MPLS_ASSERT(0);
801 void mpls_label_struct2ldp_attr(mpls_label_struct * l, ldp_attr * a)
803 switch (l->type) {
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;
809 break;
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;
822 default:
823 MPLS_ASSERT(0);
827 #if 0
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;
862 #endif
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) {
870 return NULL;
873 /* this FEC doesn't exist in the tree yet, create one ... */
874 if (!(fnode = ldp_fec_create(g, f))) {
875 /* insert failed */
876 return NULL;
879 return fnode;
882 static ldp_fec *_ldp_attr_get_fec(ldp_global * g, ldp_attr * a, mpls_bool flag)
884 mpls_fec fec;
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);
895 if (fs == NULL) {
896 fs = _ldp_fs_create(s);
897 if (fs == NULL) {
898 return NULL;
900 MPLS_LIST_ADD_HEAD(&fec->fs_root_ds, fs, _fec, ldp_fs);
902 return 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);
909 if (fs == NULL) {
910 fs = _ldp_fs_create(s);
911 if (fs == NULL) {
912 return NULL;
914 MPLS_LIST_ADD_HEAD(&fec->fs_root_us, fs, _fec, ldp_fs);
916 return fs;
919 static ldp_fs *_ldp_fec_find_fs_us(ldp_fec * fec, ldp_session * s,
920 mpls_bool flag)
922 ldp_fs *fs = MPLS_LIST_HEAD(&fec->fs_root_us);
924 while (fs != NULL) {
925 if (fs->session->index == s->index) {
926 return fs;
928 fs = MPLS_LIST_NEXT(&fec->fs_root_us, fs, _fec);
930 if (flag == MPLS_BOOL_FALSE) {
931 return NULL;
933 return _ldp_fec_add_fs_us(fec, s);
936 static ldp_fs *_ldp_fec_find_fs_ds(ldp_fec * fec, ldp_session * s,
937 mpls_bool flag)
939 ldp_fs *fs = MPLS_LIST_HEAD(&fec->fs_root_ds);
941 while (fs != NULL) {
942 if (fs->session->index == s->index) {
943 return fs;
945 fs = MPLS_LIST_NEXT(&fec->fs_root_ds, fs, _fec);
947 if (flag == MPLS_BOOL_FALSE) {
948 return NULL;
950 return _ldp_fec_add_fs_ds(fec, s);
953 static void _ldp_fec_del_fs_us(ldp_fec * fec, ldp_fs * fs)
955 if (fs == NULL) {
956 return;
958 MPLS_LIST_REMOVE(&fec->fs_root_us, fs, _fec);
959 _ldp_fs_delete(fs);
962 static void _ldp_fec_del_fs_ds(ldp_fec * fec, ldp_fs * fs)
964 if (fs == NULL) {
965 return;
967 MPLS_LIST_REMOVE(&fec->fs_root_ds, fs, _fec);
968 _ldp_fs_delete(fs);
971 static ldp_fs *_ldp_fs_create(ldp_session * s)
973 ldp_fs *fs = (ldp_fs *) mpls_malloc(sizeof(ldp_fs));
975 if (fs != NULL) {
976 memset(fs, 0, sizeof(ldp_fs));
977 MPLS_LIST_INIT(&fs->attr_root, ldp_attr);
978 MPLS_LIST_ELEM_INIT(fs, _fec);
979 if (s != NULL) {
980 MPLS_REFCNT_HOLD(s);
981 fs->session = s;
984 return fs;
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);
993 mpls_free(fs);
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) {
1002 return ptr;
1004 ptr = MPLS_LIST_NEXT(&fs->attr_root, ptr, _fs);
1006 return NULL;
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);
1023 if (ptr != NULL) {
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");
1037 while (fs) {
1038 ldp_attr *attr = MPLS_LIST_HEAD(&fs->attr_root);
1039 fprintf(stderr, "FS: %p\n", fs);
1040 while (attr) {
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");
1046 return attr;
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");
1054 return NULL;
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;
1065 return retval;