Results of major ATTR rework:
[mpls-ldp-portable.git] / ldp / ldp_attr.c
blob391e13326a8f5515e9149126d6257f2eb06e6ed0
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_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;
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_global *g, 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_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);
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(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);
287 break;
288 case LDP_LSP_STATE_MAP_SENT:
289 in = attr->inlabel;
290 out = in->outlabel;
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);
299 break;
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);
308 break;
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);
320 break;
325 ldp_attr *ldp_attr_create(ldp_global *g, mpls_fec * fec)
327 ldp_attr *a = (ldp_attr *) mpls_malloc(sizeof(ldp_attr));
329 if (a != NULL) {
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;
341 if (fec != NULL) {
342 mpls_fec2fec_tlv(fec, &a->fecTlv, 0);
343 a->fecTlv.numberFecElements = 1;
344 a->fecTlvExists = 1;
346 _ldp_global_add_attr(g, a);
348 return 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);
357 mpls_free(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));
364 b->fecTlvExists = 1;
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)
400 if (a && i) {
401 MPLS_REFCNT_HOLD(i);
402 a->inlabel = i;
403 _ldp_inlabel_add_attr(g, i, a);
404 return MPLS_SUCCESS;
406 return MPLS_FAILURE;
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);
414 a->inlabel = NULL;
415 return MPLS_SUCCESS;
417 return MPLS_FAILURE;
420 mpls_return_enum ldp_attr_add_outlabel(ldp_attr * a, ldp_outlabel * o)
422 if (a && o) {
423 MPLS_REFCNT_HOLD(o);
424 a->outlabel = o;
425 _ldp_outlabel_add_attr(o, a);
426 return MPLS_SUCCESS;
428 return MPLS_FAILURE;
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);
436 a->outlabel = NULL;
437 return MPLS_SUCCESS;
439 return MPLS_FAILURE;
442 mpls_return_enum ldp_attr_add_session(ldp_attr * a, ldp_session * s)
444 if (a && s) {
445 MPLS_REFCNT_HOLD(s);
446 a->session = s;
447 _ldp_session_add_attr(s, a);
448 return MPLS_SUCCESS;
450 return MPLS_FAILURE;
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);
458 a->session = NULL;
459 return MPLS_SUCCESS;
461 return MPLS_FAILURE;
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;
481 } else {
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;
490 } else {
491 if (a->hopCountTlvExists != b->hopCountTlvExists) {
492 return MPLS_BOOL_FALSE;
496 if (flag & LDP_ATTR_PATH) {
497 int i;
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;
505 } else {
506 if (a->hopCountTlvExists != b->hopCountTlvExists) {
507 return MPLS_BOOL_FALSE;
511 if (flag & LDP_ATTR_FEC) {
512 int i;
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]) {
523 case MPLS_CRLSP_FEC:
524 case MPLS_WC_FEC:
525 /* nothing of interest to compare */
526 break;
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;
537 break;
538 default:
539 MPLS_ASSERT(0);
542 } else {
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;
551 } else {
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;
561 } else {
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)
573 ldp_fs *fs = NULL;
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 */
581 return MPLS_FAILURE;
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;
589 return retval;
592 mpls_return_enum ldp_attr_insert_upstream(ldp_global * g, ldp_session * s,
593 ldp_attr * a)
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! */
601 return MPLS_FAILURE;
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)
610 ldp_fs *fs = NULL;
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 */
618 return MPLS_FAILURE;
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;
626 return retval;
629 mpls_return_enum ldp_attr_insert_downstream(ldp_global * g, ldp_session * s,
630 ldp_attr * a)
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! */
638 return MPLS_FAILURE;
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,
645 ldp_fec * f)
647 ldp_fs *fs = NULL;
649 MPLS_ASSERT(f && g);
651 if (!s) {
652 return NULL;
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 */
658 return NULL;
660 return &fs->attr_root;
663 ldp_attr_list *ldp_attr_find_upstream_all(ldp_global * g, ldp_session * s,
664 mpls_fec * f)
666 ldp_fec *fnode = NULL;
668 MPLS_ASSERT(f && g);
670 if (!s) {
671 return NULL;
674 if ((fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE)) == NULL) {
675 /* we couldn't get the node from the tree! */
676 return NULL;
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,
683 ldp_fec * f)
685 ldp_fs *fs = NULL;
687 MPLS_ASSERT(f && g);
689 if (!s) {
690 return NULL;
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 */
696 return NULL;
698 return &fs->attr_root;
701 ldp_attr_list *ldp_attr_find_downstream_all(ldp_global * g, ldp_session * s,
702 mpls_fec * f)
704 ldp_fec *fnode = NULL;
706 MPLS_ASSERT(f && g);
708 if (!s) {
709 return NULL;
712 if ((fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE)) == NULL) {
713 /* we couldn't get the node from the tree! */
714 return NULL;
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;
723 ldp_fs *fs = NULL;
725 MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE);
727 MPLS_REFCNT_HOLD(a);
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;
752 ldp_fs *fs = NULL;
754 MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE);
756 MPLS_REFCNT_HOLD(a);
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;
786 } else {
787 MPLS_ASSERT(0);
791 void mpls_label_struct2ldp_attr(mpls_label_struct * l, ldp_attr * a)
793 switch (l->type) {
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;
799 break;
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;
812 default:
813 MPLS_ASSERT(0);
817 #if 0
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;
852 #endif
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) {
860 return NULL;
863 /* this FEC doesn't exist in the tree yet, create one ... */
864 if (!(fnode = ldp_fec_create(g, f))) {
865 /* insert failed */
866 return NULL;
869 return fnode;
872 static ldp_fec *_ldp_attr_get_fec(ldp_global * g, ldp_attr * a, mpls_bool flag)
874 mpls_fec fec;
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);
885 if (fs == NULL) {
886 fs = _ldp_fs_create(s);
887 if (fs == NULL) {
888 return NULL;
890 MPLS_LIST_ADD_HEAD(&fec->fs_root_ds, fs, _fec, ldp_fs);
892 return 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);
899 if (fs == NULL) {
900 fs = _ldp_fs_create(s);
901 if (fs == NULL) {
902 return NULL;
904 MPLS_LIST_ADD_HEAD(&fec->fs_root_us, fs, _fec, ldp_fs);
906 return fs;
909 static ldp_fs *_ldp_fec_find_fs_us(ldp_fec * fec, ldp_session * s,
910 mpls_bool flag)
912 ldp_fs *fs = MPLS_LIST_HEAD(&fec->fs_root_us);
914 while (fs != NULL) {
915 if (fs->session->index == s->index) {
916 return fs;
918 fs = MPLS_LIST_NEXT(&fec->fs_root_us, fs, _fec);
920 if (flag == MPLS_BOOL_FALSE) {
921 return NULL;
923 return _ldp_fec_add_fs_us(fec, s);
926 static ldp_fs *_ldp_fec_find_fs_ds(ldp_fec * fec, ldp_session * s,
927 mpls_bool flag)
929 ldp_fs *fs = MPLS_LIST_HEAD(&fec->fs_root_ds);
931 while (fs != NULL) {
932 if (fs->session->index == s->index) {
933 return fs;
935 fs = MPLS_LIST_NEXT(&fec->fs_root_ds, fs, _fec);
937 if (flag == MPLS_BOOL_FALSE) {
938 return NULL;
940 return _ldp_fec_add_fs_ds(fec, s);
943 static void _ldp_fec_del_fs_us(ldp_fec * fec, ldp_fs * fs)
945 if (fs == NULL) {
946 return;
948 MPLS_LIST_REMOVE(&fec->fs_root_us, fs, _fec);
949 _ldp_fs_delete(fs);
952 static void _ldp_fec_del_fs_ds(ldp_fec * fec, ldp_fs * fs)
954 if (fs == NULL) {
955 return;
957 MPLS_LIST_REMOVE(&fec->fs_root_ds, fs, _fec);
958 _ldp_fs_delete(fs);
961 static ldp_fs *_ldp_fs_create(ldp_session * s)
963 ldp_fs *fs = (ldp_fs *) mpls_malloc(sizeof(ldp_fs));
965 if (fs != NULL) {
966 memset(fs, 0, sizeof(ldp_fs));
967 MPLS_LIST_INIT(&fs->attr_root, ldp_attr);
968 MPLS_LIST_ELEM_INIT(fs, _fec);
969 if (s != NULL) {
970 MPLS_REFCNT_HOLD(s);
971 fs->session = s;
974 return fs;
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);
983 mpls_free(fs);
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) {
992 return ptr;
994 ptr = MPLS_LIST_NEXT(&fs->attr_root, ptr, _fs);
996 return NULL;
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);
1013 if (ptr != NULL) {
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");
1027 while (fs) {
1028 ldp_attr *attr = MPLS_LIST_HEAD(&fs->attr_root);
1029 fprintf(stderr, "FS: %p\n", fs);
1030 while (attr) {
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");
1036 return attr;
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");
1044 return NULL;
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;
1055 return retval;