Changed the relationship between entity-adj-sessios (again)
[mpls-ldp-portable.git] / lsr / lsr_global.c
blob3df7254c9ee0e4cc4da12dcc284bfdad33a34321
2 /*
3 * Copyright (C) James R. Leu 2002
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 "lsr_struct.h"
11 #include "lsr_global.h"
12 #include "lsr_outsegment.h"
13 #include "lsr_insegment.h"
14 #include "lsr_xconnect.h"
15 #include "lsr_ftn.h"
16 #include "lsr_if.h"
18 #include "mpls_ifmgr_impl.h"
19 #include "mpls_mpls_impl.h"
20 #include "mpls_lock_impl.h"
21 #include "mpls_mm_impl.h"
22 #include "mpls_trace_impl.h"
24 lsr_global *lsr_global_create(mpls_instance_handle data)
26 lsr_global *g = (lsr_global *) mpls_malloc(sizeof(lsr_global));
28 if (g) {
29 memset(g, 0, sizeof(lsr_global));
31 LDP_ENTER(g->user_data, "lsr_global_create");
33 g->global_lock = mpls_lock_create("_lsr_global_lock_");
34 mpls_lock_get(g->global_lock);
36 MPLS_LIST_INIT(&g->outsegment, lsr_outsegment);
37 MPLS_LIST_INIT(&g->insegment, lsr_insegment);
38 MPLS_LIST_INIT(&g->xconnect, lsr_xconnect);
39 MPLS_LIST_INIT(&g->ftn, lsr_ftn);
40 MPLS_LIST_INIT(&g->iff, lsr_if);
42 g->admin_state = MPLS_ADMIN_DISABLE;
43 g->user_data = data;
45 mpls_lock_release(g->global_lock);
47 LDP_EXIT(g->user_data, "lsr_global_create");
50 return g;
53 mpls_return_enum lsr_global_startup(lsr_global * g)
55 MPLS_ASSERT(g != NULL);
57 LDP_ENTER(g->user_data, "lsr_global_startup");
59 g->ifmgr_handle = mpls_ifmgr_open(g->user_data, g, NULL);
60 if (mpls_ifmgr_handle_verify(g->ifmgr_handle) == MPLS_BOOL_FALSE) {
61 goto lsr_global_startup_cleanup;
64 g->mpls_handle = mpls_mpls_open(g->user_data);
65 if (mpls_mpls_handle_verify(g->mpls_handle) == MPLS_BOOL_FALSE) {
66 goto lsr_global_startup_cleanup;
69 g->admin_state = MPLS_ADMIN_ENABLE;
71 LDP_EXIT(g->user_data, "lsr_global_startup");
72 return MPLS_SUCCESS;
74 lsr_global_startup_cleanup:
75 lsr_global_shutdown(g);
77 LDP_EXIT(g->user_data, "lsr_global_startup-error");
79 return MPLS_FAILURE;
82 mpls_return_enum lsr_global_shutdown(lsr_global * g)
84 MPLS_ASSERT(g);
86 LDP_ENTER(g->user_data, "lsr_global_shutdown");
88 g->admin_state = MPLS_ADMIN_DISABLE;
90 mpls_lock_release(g->global_lock);
91 mpls_lock_get(g->global_lock);
93 mpls_ifmgr_close(g->ifmgr_handle);
94 mpls_mpls_close(g->mpls_handle);
96 LDP_EXIT(g->user_data, "lsr_global_shutdown");
98 return MPLS_SUCCESS;
101 mpls_return_enum lsr_global_delete(lsr_global * g)
103 if (g) {
104 mpls_lock_delete(g->global_lock);
105 LDP_PRINT(g->user_data, "global delete\n");
106 mpls_free(g);
108 return MPLS_SUCCESS;
111 /* struct if */
113 mpls_return_enum _lsr_global_add_if(lsr_global * g, lsr_if * i)
115 lsr_if *ip = NULL;
117 if (g && i) {
118 MPLS_REFCNT_HOLD(i);
119 ip = MPLS_LIST_HEAD(&g->iff);
120 while (ip != NULL) {
121 if (ip->index > i->index) {
122 MPLS_LIST_INSERT_BEFORE(&g->iff, ip, i, _global);
123 return MPLS_SUCCESS;
125 ip = MPLS_LIST_NEXT(&g->iff, ip, _global);
127 MPLS_LIST_ADD_TAIL(&g->iff, i, _global, lsr_if);
128 return MPLS_SUCCESS;
130 return MPLS_FAILURE;
133 mpls_return_enum _lsr_global_del_if(lsr_global * g, lsr_if * i)
135 if (g && i) {
136 MPLS_LIST_REMOVE(&g->iff, i, _global);
137 MPLS_REFCNT_RELEASE(i, lsr_if_delete);
138 return MPLS_SUCCESS;
140 return MPLS_FAILURE;
143 mpls_return_enum lsr_global_find_if_index(lsr_global * g, uint32_t index,
144 lsr_if ** iff)
146 lsr_if *i = NULL;
148 if (g && index > 0) {
150 /* because we sort our inserts by index, this lets us know
151 if we've "walked" past the end of the list */
153 i = MPLS_LIST_TAIL(&g->iff);
154 if (i == NULL || i->index < index) {
155 *iff = NULL;
156 return MPLS_END_OF_LIST;
159 i = MPLS_LIST_HEAD(&g->iff);
160 while (i != NULL) {
161 if (i->index == index) {
162 *iff = i;
163 return MPLS_SUCCESS;
165 i = MPLS_LIST_NEXT(&g->iff, i, _global);
168 *iff = NULL;
169 return MPLS_FAILURE;
172 lsr_if * lsr_global_find_if_ifhandle(lsr_global * g, mpls_if_handle ifhandle)
174 lsr_if *i = NULL;
176 if (g && mpls_if_handle_verify(g->ifmgr_handle, ifhandle) == MPLS_BOOL_TRUE) {
177 i = MPLS_LIST_HEAD(&g->iff);
178 while (i != NULL) {
179 if (!mpls_if_handle_compare(i->handle, ifhandle)) {
180 return i;
182 i = MPLS_LIST_NEXT(&g->iff, i, _global);
185 return NULL;
188 /* struct outsegment */
190 mpls_return_enum _lsr_global_add_outsegment(lsr_global * g, lsr_outsegment * o)
192 lsr_outsegment *op = NULL;
194 if (g && o) {
195 MPLS_REFCNT_HOLD(o);
196 op = MPLS_LIST_HEAD(&g->outsegment);
197 while (op != NULL) {
198 if (op->index > o->index) {
199 MPLS_LIST_INSERT_BEFORE(&g->outsegment, op, o, _global);
200 return MPLS_SUCCESS;
202 op = MPLS_LIST_NEXT(&g->outsegment, op, _global);
204 MPLS_LIST_ADD_TAIL(&g->outsegment, o, _global, lsr_outsegment);
205 return MPLS_SUCCESS;
207 return MPLS_FAILURE;
210 mpls_return_enum _lsr_global_del_outsegment(lsr_global * g, lsr_outsegment * o)
212 if (g && o) {
213 MPLS_LIST_REMOVE(&g->outsegment, o, _global);
214 MPLS_REFCNT_RELEASE(o, lsr_outsegment_delete);
215 return MPLS_SUCCESS;
217 return MPLS_FAILURE;
220 mpls_return_enum lsr_global_find_outsegment_index(lsr_global * g,
221 uint32_t index, lsr_outsegment ** outsegment)
223 lsr_outsegment *o = NULL;
225 if (g && index > 0) {
227 /* because we sort our inserts by index, this lets us know
228 if we've "walked" past the end of the list */
230 o = MPLS_LIST_TAIL(&g->outsegment);
231 if (o == NULL || o->index < index) {
232 *outsegment = NULL;
233 return MPLS_END_OF_LIST;
236 o = MPLS_LIST_HEAD(&g->outsegment);
237 while (o != NULL) {
238 if (o->index == index) {
239 *outsegment = o;
240 return MPLS_SUCCESS;
242 o = MPLS_LIST_NEXT(&g->outsegment, o, _global);
245 *outsegment = NULL;
246 return MPLS_FAILURE;
249 /* struct insegment */
251 mpls_return_enum _lsr_global_add_insegment(lsr_global * g, lsr_insegment * i)
253 lsr_insegment *ip = NULL;
255 if (g && i) {
256 MPLS_REFCNT_HOLD(i);
257 ip = MPLS_LIST_HEAD(&g->insegment);
258 while (ip != NULL) {
259 if (ip->index > i->index) {
260 MPLS_LIST_INSERT_BEFORE(&g->insegment, ip, i, _global);
261 return MPLS_SUCCESS;
263 ip = MPLS_LIST_NEXT(&g->insegment, ip, _global);
265 MPLS_LIST_ADD_TAIL(&g->insegment, i, _global, lsr_insegment);
266 return MPLS_SUCCESS;
268 return MPLS_FAILURE;
271 mpls_return_enum _lsr_global_del_insegment(lsr_global * g, lsr_insegment * i)
273 if (g && i) {
274 MPLS_LIST_REMOVE(&g->insegment, i, _global);
275 MPLS_REFCNT_RELEASE(i, lsr_insegment_delete);
276 return MPLS_SUCCESS;
278 return MPLS_FAILURE;
281 mpls_return_enum lsr_global_find_insegment_index(lsr_global * g,
282 uint32_t index, lsr_insegment ** insegment)
284 lsr_insegment *i = NULL;
286 if (g && index > 0) {
288 /* because we sort our inserts by index, this lets us know
289 if we've "walked" past the end of the list */
291 i = MPLS_LIST_TAIL(&g->insegment);
292 if (i == NULL || i->index < index) {
293 *insegment = NULL;
294 return MPLS_END_OF_LIST;
297 i = MPLS_LIST_HEAD(&g->insegment);
298 while (i != NULL) {
299 if (i->index == index) {
300 *insegment = i;
301 return MPLS_SUCCESS;
303 i = MPLS_LIST_NEXT(&g->insegment, i, _global);
306 *insegment = NULL;
307 return MPLS_FAILURE;
310 /* struct xconnect */
312 mpls_return_enum _lsr_global_add_xconnect(lsr_global * g, lsr_xconnect * x)
314 lsr_xconnect *xp = NULL;
316 if (g && x) {
317 MPLS_REFCNT_HOLD(x);
318 xp = MPLS_LIST_HEAD(&g->xconnect);
319 while (xp != NULL) {
320 if (xp->index > x->index) {
321 MPLS_LIST_INSERT_BEFORE(&g->xconnect, xp, x, _global);
322 return MPLS_SUCCESS;
324 xp = MPLS_LIST_NEXT(&g->xconnect, xp, _global);
326 MPLS_LIST_ADD_TAIL(&g->xconnect, x, _global, lsr_xconnect);
327 return MPLS_SUCCESS;
329 return MPLS_FAILURE;
332 mpls_return_enum _lsr_global_del_xconnect(lsr_global * g, lsr_xconnect * x)
334 if (g && x) {
335 MPLS_LIST_REMOVE(&g->xconnect, x, _global);
336 MPLS_REFCNT_RELEASE(x, lsr_xconnect_delete);
337 return MPLS_SUCCESS;
339 return MPLS_FAILURE;
342 mpls_return_enum lsr_global_find_xconnect_index(lsr_global * g,
343 uint32_t index, lsr_xconnect ** xconnect)
345 lsr_xconnect *x = NULL;
347 if (g && index > 0) {
349 /* because we sort our inserts by index, this lets us know
350 if we've "walked" past the end of the list */
352 x = MPLS_LIST_TAIL(&g->xconnect);
353 if (x == NULL || x->index < index) {
354 *xconnect = NULL;
355 return MPLS_END_OF_LIST;
358 x = MPLS_LIST_HEAD(&g->xconnect);
359 while (x != NULL) {
360 if (x->index == index) {
361 *xconnect = x;
362 return MPLS_SUCCESS;
364 x = MPLS_LIST_NEXT(&g->xconnect, x, _global);
367 *xconnect = NULL;
368 return MPLS_FAILURE;
371 mpls_return_enum lsr_global_find_xconnect_index2(lsr_global * g,
372 uint32_t in, uint32_t out, lsr_xconnect ** xconnect)
374 lsr_insegment *iseg = NULL;
375 lsr_xconnect *x = NULL;
377 if (g && in > 0 && out > 0) {
379 if (lsr_global_find_insegment_index(g,in,&iseg) != MPLS_SUCCESS) {
380 return MPLS_FAILURE;
383 x = MPLS_LIST_HEAD(&iseg->xconnect_root);
384 while (x != NULL) {
385 if (x->outsegment && x->outsegment->index == out) {
386 *xconnect = x;
387 return MPLS_SUCCESS;
389 x = MPLS_LIST_NEXT(&iseg->xconnect_root, x, _insegment);
392 *xconnect = NULL;
393 return MPLS_FAILURE;
396 /* struct ftn */
398 mpls_return_enum _lsr_global_add_ftn(lsr_global * g, lsr_ftn * f)
400 lsr_ftn *fp = NULL;
402 if (g && f) {
403 MPLS_REFCNT_HOLD(f);
404 fp = MPLS_LIST_HEAD(&g->ftn);
405 while (fp != NULL) {
406 if (fp->index > f->index) {
407 MPLS_LIST_INSERT_BEFORE(&g->ftn, fp, f, _global);
408 return MPLS_SUCCESS;
410 fp = MPLS_LIST_NEXT(&g->ftn, fp, _global);
412 MPLS_LIST_ADD_TAIL(&g->ftn, f, _global, lsr_ftn);
413 return MPLS_SUCCESS;
415 return MPLS_FAILURE;
418 mpls_return_enum _lsr_global_del_ftn(lsr_global * g, lsr_ftn * f)
420 if (g && f) {
421 MPLS_LIST_REMOVE(&g->ftn, f, _global);
422 MPLS_REFCNT_RELEASE(f, lsr_ftn_delete);
423 return MPLS_SUCCESS;
425 return MPLS_FAILURE;
428 mpls_return_enum lsr_global_find_ftn_index(lsr_global * g,
429 uint32_t index, lsr_ftn ** ftn)
431 lsr_ftn *f = NULL;
433 if (g && index > 0) {
435 /* because we sort our inserts by index, this lets us know
436 if we've "walked" past the end of the list */
438 f = MPLS_LIST_TAIL(&g->ftn);
439 if (f == NULL || f->index < index) {
440 *ftn = NULL;
441 return MPLS_END_OF_LIST;
444 f = MPLS_LIST_HEAD(&g->ftn);
445 while (f != NULL) {
446 if (f->index == index) {
447 *ftn = f;
448 return MPLS_SUCCESS;
450 f = MPLS_LIST_NEXT(&g->ftn, f, _global);
453 *ftn = NULL;
454 return MPLS_FAILURE;
457 mpls_return_enum lsr_global_find_ftn_index2(lsr_global * g,
458 lsr_ftn * f, lsr_ftn ** ftn)
460 lsr_ftn *fp = NULL;
462 if (g && f) {
463 fp = MPLS_LIST_HEAD(&g->ftn);
464 while (fp != NULL) {
465 if (fp->outsegment->index == f->outsegment_index) {
466 if (fp->fec.type == f->fec.type) {
467 switch(fp->fec.type) {
468 case MPLS_FEC_PREFIX:
469 if (fp->fec.u.prefix.network.u.ipv4 == f->fec.u.prefix.network.u.ipv4 &&
470 fp->fec.u.prefix.length == f->fec.u.prefix.length) {
471 *ftn = fp;
472 return MPLS_SUCCESS;
474 break;
475 case MPLS_FEC_HOST:
476 if (fp->fec.u.host.u.ipv4 == f->fec.u.host.u.ipv4) {
477 *ftn = fp;
478 return MPLS_SUCCESS;
480 break;
481 case MPLS_FEC_L2CC:
482 if (fp->fec.u.l2cc.connection_id == f->fec.u.l2cc.connection_id &&
483 fp->fec.u.l2cc.group_id == f->fec.u.l2cc.group_id &&
484 fp->fec.u.l2cc.type == f->fec.u.l2cc.type) {
485 *ftn = fp;
486 return MPLS_SUCCESS;
488 break;
489 default:
490 MPLS_ASSERT(0);
494 fp = MPLS_LIST_NEXT(&g->ftn, fp, _global);
497 *ftn = NULL;
498 return MPLS_FAILURE;