Updated label mapping to better support the new fec -> nh relationship
[mpls-ldp-portable.git] / ldp / ldp_outlabel.c
blobc09e33224f2b7bcfb43ac0df14add66e5e89aeab
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 <stdlib.h>
11 #include "ldp_struct.h"
12 #include "ldp_addr.h"
13 #include "ldp_if.h"
14 #include "ldp_attr.h"
15 #include "ldp_fec.h"
16 #include "ldp_nexthop.h"
17 #include "ldp_outlabel.h"
18 #include "ldp_inlabel.h"
19 #include "ldp_session.h"
20 #include "ldp_tunnel.h"
21 #include "ldp_global.h"
23 #include "mpls_mm_impl.h"
24 #include "mpls_trace_impl.h"
26 static uint32_t _ldp_outlabel_next_index = 1;
28 ldp_outlabel *ldp_outlabel_create()
30 ldp_outlabel *o = (ldp_outlabel *) mpls_malloc(sizeof(ldp_outlabel));
32 if (o) {
33 memset(o, 0, sizeof(ldp_outlabel));
34 MPLS_REFCNT_INIT(o, 0);
35 MPLS_LIST_INIT(&o->inlabel_root, ldp_inlabel);
36 MPLS_LIST_INIT(&o->tunnel_root, ldp_tunnel);
37 MPLS_LIST_INIT(&o->nh_root, ldp_nexthop);
38 MPLS_LIST_ELEM_INIT(o, _global);
39 MPLS_LIST_ELEM_INIT(o, _session);
40 o->index = _ldp_outlabel_get_next_index();
41 o->info.label.type = MPLS_LABEL_TYPE_NONE;
42 o->switching = MPLS_BOOL_FALSE;
44 return o;
47 ldp_outlabel *ldp_outlabel_create_complete(ldp_global * g, ldp_session * s,
48 ldp_attr * a, ldp_nexthop *nh)
50 ldp_outlabel *out = ldp_outlabel_create();
52 if (out != NULL) {
53 ldp_outlabel_add_nexthop2(out, nh);
54 ldp_session_add_outlabel(s, out);
56 out->info.push_label = MPLS_BOOL_TRUE;
57 out->info.owner = MPLS_OWNER_LDP;
59 ldp_attr2mpls_label_struct(a, &out->info.label);
60 _ldp_global_add_outlabel(g, out);
61 ldp_attr_add_outlabel(a, out);
63 return out;
66 void ldp_outlabel_delete(ldp_outlabel * o)
68 LDP_PRINT(g->user_data,"outlabel delete\n");
69 MPLS_REFCNT_ASSERT(o, 0);
70 mpls_free(o);
73 void ldp_outlabel_delete_complete(ldp_global * g, ldp_outlabel * out)
75 ldp_attr_del_outlabel(out->attr);
76 if (out->session) {
77 ldp_session_del_outlabel(out->session, out);
79 _ldp_global_del_outlabel(g, out);
80 ldp_outlabel_del_nexthop2(out);
83 void _ldp_outlabel_add_inlabel(ldp_outlabel * o, ldp_inlabel * i)
85 MPLS_ASSERT(o && i);
86 MPLS_REFCNT_HOLD(i);
87 o->merge_count++;
88 MPLS_LIST_ADD_HEAD(&o->inlabel_root, i, _outlabel, ldp_inlabel);
91 void _ldp_outlabel_del_inlabel(ldp_outlabel * o, ldp_inlabel * i)
93 MPLS_ASSERT(o && i);
94 MPLS_LIST_REMOVE(&o->inlabel_root, i, _outlabel);
95 o->merge_count--;
96 MPLS_REFCNT_RELEASE(i, ldp_inlabel_delete);
99 void _ldp_outlabel_add_attr(ldp_outlabel * o, ldp_attr * a)
101 MPLS_ASSERT(o && a);
102 MPLS_REFCNT_HOLD(a);
103 o->attr = a;
106 void _ldp_outlabel_del_attr(ldp_outlabel * o)
108 MPLS_ASSERT(o && o->attr);
109 MPLS_REFCNT_RELEASE(o->attr, ldp_attr_delete);
110 o->attr = NULL;
113 void ldp_outlabel_add_nexthop(ldp_outlabel * o, ldp_nexthop * nh)
115 ldp_nexthop *np = NULL;
117 MPLS_ASSERT(o && nh);
118 MPLS_REFCNT_HOLD(nh);
120 ldp_nexthop_add_outlabel(nh,o);
122 np = MPLS_LIST_HEAD(&o->nh_root);
123 while (np != NULL) {
124 if (np->index > nh->index) {
125 MPLS_LIST_INSERT_BEFORE(&o->nh_root, np, nh, _outlabel);
126 return;
128 np = MPLS_LIST_NEXT(&o->nh_root, np, _outlabel);
130 MPLS_LIST_ADD_TAIL(&o->nh_root, nh, _outlabel, ldp_nexthop);
133 void ldp_outlabel_del_nexthop(ldp_outlabel * o, ldp_nexthop * nh)
135 MPLS_ASSERT(o && nh);
136 MPLS_LIST_REMOVE(&o->nh_root, nh, _outlabel);
137 ldp_nexthop_del_outlabel(nh);
138 MPLS_REFCNT_RELEASE(nh, ldp_nexthop_delete);
141 void ldp_outlabel_add_nexthop2(ldp_outlabel * o, ldp_nexthop * nh)
143 MPLS_ASSERT(o && nh);
144 MPLS_REFCNT_HOLD(nh);
145 o->nh = nh;
146 ldp_nexthop_add_outlabel2(nh, o);
149 void ldp_outlabel_del_nexthop2(ldp_outlabel * o)
151 MPLS_ASSERT(o);
152 ldp_nexthop_del_outlabel2(o->nh, o);
153 MPLS_REFCNT_RELEASE(o->nh, ldp_nexthop_delete);
154 o->nh = NULL;
157 void _ldp_outlabel_add_session(ldp_outlabel * o, ldp_session * s)
159 MPLS_ASSERT(o && s);
160 MPLS_REFCNT_HOLD(s);
161 o->session = s;
164 void _ldp_outlabel_del_session(ldp_outlabel * o)
166 MPLS_ASSERT(o && o->session);
167 MPLS_REFCNT_RELEASE(o->session, ldp_session_delete);
168 o->session = NULL;
171 void _ldp_outlabel_add_tunnel(ldp_outlabel * o, ldp_tunnel * t)
173 MPLS_ASSERT(o && t);
174 MPLS_REFCNT_HOLD(t);
175 o->merge_count++;
176 MPLS_LIST_ADD_HEAD(&o->tunnel_root, t, _outlabel, ldp_tunnel);
179 void _ldp_outlabel_del_tunnel(ldp_outlabel * o, ldp_tunnel * t)
181 MPLS_ASSERT(o && t);
182 MPLS_LIST_REMOVE(&o->tunnel_root, t, _outlabel);
183 o->merge_count--;
184 MPLS_REFCNT_RELEASE(t, ldp_tunnel_delete);
187 uint32_t _ldp_outlabel_get_next_index()
189 uint32_t retval = _ldp_outlabel_next_index;
191 _ldp_outlabel_next_index++;
192 if (retval > _ldp_outlabel_next_index) {
193 _ldp_outlabel_next_index = 1;
195 return retval;