Make sure to mark LDP globally up before trying to startup
[mpls-ldp-portable.git] / ldp / ldp_global.c
blob9d06254ecc2122ae392ff1996d4aba1e3cf62b5f
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 <netinet/in.h>
12 #include "ldp_struct.h"
13 #include "ldp_inet_addr.h"
14 #include "ldp_session.h"
15 #include "ldp_entity.h"
16 #include "ldp_global.h"
17 #include "ldp_nexthop.h"
18 #include "ldp_outlabel.h"
19 #include "ldp_inlabel.h"
20 #include "ldp_hello.h"
21 #include "ldp_peer.h"
22 #include "ldp_attr.h"
23 #include "ldp_addr.h"
24 #include "ldp_adj.h"
25 #include "ldp_fec.h"
26 #include "ldp_if.h"
27 #include "ldp_label_mapping.h"
28 #include "ldp_tunnel.h"
29 #include "ldp_resource.h"
30 #include "ldp_hop_list.h"
32 #include "mpls_compare.h"
34 #include "mpls_socket_impl.h"
35 #include "mpls_timer_impl.h"
36 #include "mpls_ifmgr_impl.h"
37 #include "mpls_tree_impl.h"
38 #include "mpls_lock_impl.h"
39 #include "mpls_fib_impl.h"
40 #include "mpls_policy_impl.h"
41 #include "mpls_mm_impl.h"
42 #include "mpls_trace_impl.h"
44 #if MPLS_USE_LSR
45 #include "lsr_cfg.h"
46 #else
47 #include "mpls_mpls_impl.h"
48 #endif
50 ldp_global *ldp_global_create(mpls_instance_handle data)
52 ldp_global *g = (ldp_global *) mpls_malloc(sizeof(ldp_global));
54 if (g) {
55 memset(g, 0, sizeof(ldp_global));
57 LDP_ENTER(g->user_data, "ldp_global_create");
59 g->global_lock = mpls_lock_create("_ldp_global_lock_");
60 mpls_lock_get(g->global_lock);
62 MPLS_LIST_INIT(&g->hop_list, ldp_hop_list);
63 MPLS_LIST_INIT(&g->outlabel, ldp_outlabel);
64 MPLS_LIST_INIT(&g->resource, ldp_resource);
65 MPLS_LIST_INIT(&g->inlabel, ldp_inlabel);
66 MPLS_LIST_INIT(&g->session, ldp_session);
67 MPLS_LIST_INIT(&g->nexthop, ldp_nexthop);
68 MPLS_LIST_INIT(&g->tunnel, ldp_tunnel);
69 MPLS_LIST_INIT(&g->entity, ldp_entity);
70 MPLS_LIST_INIT(&g->addr, ldp_addr);
71 MPLS_LIST_INIT(&g->attr, ldp_attr);
72 MPLS_LIST_INIT(&g->peer, ldp_peer);
73 MPLS_LIST_INIT(&g->fec, ldp_fec);
74 MPLS_LIST_INIT(&g->adj, ldp_adj);
75 MPLS_LIST_INIT(&g->iff, ldp_if);
77 g->message_identifier = 1;
78 g->configuration_sequence_number = 1;
79 g->lsp_control_mode = LDP_GLOBAL_DEF_CONTROL_MODE;
80 g->label_retention_mode = LDP_GLOBAL_DEF_RETENTION_MODE;
81 g->lsp_repair_mode = LDP_GLOBAL_DEF_REPAIR_MODE;
82 g->propagate_release = LDP_GLOBAL_DEF_PROPOGATE_RELEASE;
83 g->label_merge = LDP_GLOBAL_DEF_LABEL_MERGE;
84 g->loop_detection_mode = LDP_GLOBAL_DEF_LOOP_DETECTION_MODE;
85 g->ttl_less_domain = LDP_GLOBAL_DEF_TTLLESS_DOMAIN;
86 g->local_tcp_port = LDP_GLOBAL_DEF_LOCAL_TCP_PORT;
87 g->local_udp_port = LDP_GLOBAL_DEF_LOCAL_UDP_PORT;
88 g->send_address_messages = LDP_GLOBAL_DEF_SEND_ADDR_MSG;
89 g->backoff_step = LDP_GLOBAL_DEF_BACKOFF_STEP;
90 g->send_lsrid_mapping = LDP_GLOBAL_DEF_SEND_LSRID_MAPPING;
91 g->no_route_to_peer_time = LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME;
93 g->keepalive_timer = LDP_ENTITY_DEF_KEEPALIVE_TIMER;
94 g->keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL;
95 g->hellotime_timer = LDP_ENTITY_DEF_HELLOTIME_TIMER;
96 g->hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL;
98 g->admin_state = MPLS_ADMIN_DISABLE;
99 g->user_data = data;
101 g->addr_tree = mpls_tree_create(32);
102 g->fec_tree = mpls_tree_create(32);
104 mpls_lock_release(g->global_lock);
106 LDP_EXIT(g->user_data, "ldp_global_create");
109 return g;
112 mpls_return_enum ldp_global_startup(ldp_global * g)
114 ldp_entity *e = NULL;
115 mpls_dest dest;
117 MPLS_ASSERT(g != NULL);
119 LDP_ENTER(g->user_data, "ldp_global_startup");
121 if (g->lsr_identifier.type == MPLS_FAMILY_NONE) {
122 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
123 "ldp_global_startup: invalid LSRID\n");
124 goto ldp_global_startup_cleanup;
127 g->timer_handle = mpls_timer_open(g->user_data);
128 if (mpls_timer_mgr_handle_verify(g->timer_handle) == MPLS_BOOL_FALSE) {
129 goto ldp_global_startup_cleanup;
132 g->socket_handle = mpls_socket_mgr_open(g->user_data);
133 if (mpls_socket_mgr_handle_verify(g->socket_handle) == MPLS_BOOL_FALSE) {
134 goto ldp_global_startup_cleanup;
137 g->ifmgr_handle = mpls_ifmgr_open(g->user_data, g);
138 if (mpls_ifmgr_handle_verify(g->ifmgr_handle) == MPLS_BOOL_FALSE) {
139 goto ldp_global_startup_cleanup;
142 g->fib_handle = mpls_fib_open(g->user_data, g);
143 if (mpls_fib_handle_verify(g->fib_handle) == MPLS_BOOL_FALSE) {
144 goto ldp_global_startup_cleanup;
147 #if MPLS_USE_LSR
148 if (!g->lsr_handle) {
149 goto ldp_global_startup_cleanup;
151 #else
152 g->mpls_handle = mpls_mpls_open(g->user_data);
153 if (mpls_mpls_handle_verify(g->mpls_handle) == MPLS_BOOL_FALSE) {
154 goto ldp_global_startup_cleanup;
156 #endif
158 g->hello_socket = mpls_socket_create_udp(g->socket_handle);
159 if (mpls_socket_handle_verify(g->socket_handle, g->hello_socket) == MPLS_BOOL_FALSE) {
160 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
161 "ldp_global_startup: error creating UDP socket\n");
162 goto ldp_global_startup_cleanup;
165 dest.addr.type = MPLS_FAMILY_IPV4;
166 dest.port = g->local_udp_port;
167 dest.addr.u.ipv4 = INADDR_ANY;
168 // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
170 if (mpls_socket_bind(g->socket_handle, g->hello_socket, &dest) == MPLS_FAILURE) {
171 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
172 "ldp_global_startup: error binding UDP socket\n");
173 goto ldp_global_startup_cleanup;
176 if (mpls_socket_options(g->socket_handle, g->hello_socket,
177 MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) {
178 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
179 "ldp_global_startup: error setting UDP socket options\n");
180 goto ldp_global_startup_cleanup;
182 if (mpls_socket_multicast_options(g->socket_handle, g->hello_socket, 1, 0) ==
183 MPLS_FAILURE) {
184 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
185 "ldp_global_startup: error setting UDP socket multicast options\n");
186 goto ldp_global_startup_cleanup;
188 mpls_socket_readlist_add(g->socket_handle, g->hello_socket, 0, MPLS_SOCKET_UDP_DATA);
190 g->listen_socket = mpls_socket_create_tcp(g->socket_handle);
191 if (mpls_socket_handle_verify(g->socket_handle, g->listen_socket) == MPLS_BOOL_FALSE) {
192 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
193 "ldp_global_startup: error creating TCP socket\n");
194 goto ldp_global_startup_cleanup;
196 if (mpls_socket_options(g->socket_handle, g->listen_socket,
197 MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) {
198 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
199 "ldp_global_startup: error setting TCP socket options\n");
200 goto ldp_global_startup_cleanup;
203 dest.addr.type = MPLS_FAMILY_IPV4;
204 dest.port = g->local_tcp_port;
205 dest.addr.u.ipv4 = INADDR_ANY;
207 if (mpls_socket_bind(g->socket_handle, g->listen_socket, &dest) == MPLS_FAILURE) {
208 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
209 "ldp_global_startup: error binding TCP socket\n");
210 goto ldp_global_startup_cleanup;
213 if (mpls_socket_tcp_listen(g->socket_handle, g->listen_socket, 15) ==
214 MPLS_FAILURE) {
215 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
216 "ldp_global_startup: error setting listen buffer for TCP socket\n");
217 goto ldp_global_startup_cleanup;
220 mpls_socket_readlist_add(g->socket_handle, g->listen_socket, 0,
221 MPLS_SOCKET_TCP_LISTEN);
223 g->admin_state = MPLS_ADMIN_ENABLE;
225 e = MPLS_LIST_HEAD(&g->entity);
226 while (e != NULL) {
227 ldp_entity_startup(g, e);
228 e = MPLS_LIST_NEXT(&g->entity, e, _global);
231 LDP_EXIT(g->user_data, "ldp_global_startup");
232 return MPLS_SUCCESS;
234 ldp_global_startup_cleanup:
235 ldp_global_shutdown(g);
236 mpls_socket_close(g->socket_handle, g->hello_socket);
237 mpls_socket_close(g->socket_handle, g->listen_socket);
238 g->hello_socket = 0;
239 g->listen_socket = 0;
241 LDP_EXIT(g->user_data, "ldp_global_startup-error");
243 return MPLS_FAILURE;
246 mpls_return_enum ldp_global_shutdown(ldp_global * g)
248 ldp_entity *e = NULL;
249 ldp_nexthop *n;
250 ldp_fec *f;
251 ldp_addr *a;
252 ldp_if *i;
254 MPLS_ASSERT(g);
256 LDP_ENTER(g->user_data, "ldp_global_shutdown");
258 e = MPLS_LIST_HEAD(&g->entity);
259 while (e != NULL) {
260 ldp_entity_shutdown(g, e, 1);
261 e = MPLS_LIST_NEXT(&g->entity, e, _global);
264 g->admin_state = MPLS_ADMIN_DISABLE;
266 mpls_socket_readlist_del(g->socket_handle, g->hello_socket);
267 mpls_socket_close(g->socket_handle, g->hello_socket);
269 mpls_socket_readlist_del(g->socket_handle, g->listen_socket);
270 mpls_socket_close(g->socket_handle, g->listen_socket);
272 mpls_lock_release(g->global_lock);
273 mpls_timer_close(g->timer_handle);
274 mpls_lock_get(g->global_lock);
276 mpls_socket_mgr_close(g->socket_handle);
277 mpls_ifmgr_close(g->ifmgr_handle);
278 mpls_fib_close(g->fib_handle);
280 #if MPLS_USE_LSR
281 #else
282 mpls_mpls_close(g->mpls_handle);
283 #endif
285 LDP_EXIT(g->user_data, "ldp_global_shutdown");
287 return MPLS_SUCCESS;
290 mpls_return_enum ldp_global_delete(ldp_global * g)
292 if (g) {
293 mpls_tree_delete(g->addr_tree);
294 mpls_tree_delete(g->fec_tree);
296 mpls_lock_delete(g->global_lock);
297 LDP_PRINT(g->user_data, "global delete\n");
298 mpls_free(g);
300 return MPLS_SUCCESS;
303 void _ldp_global_add_attr(ldp_global * g, ldp_attr * a)
305 ldp_attr *ap = NULL;
307 MPLS_ASSERT(g && a);
308 MPLS_REFCNT_HOLD(a);
309 ap = MPLS_LIST_HEAD(&g->attr);
310 while (ap != NULL) {
311 if (ap->index > a->index) {
312 MPLS_LIST_INSERT_BEFORE(&g->attr, ap, a, _global);
313 return;
315 ap = MPLS_LIST_NEXT(&g->attr, ap, _global);
317 MPLS_LIST_ADD_TAIL(&g->attr, a, _global, ldp_attr);
320 void _ldp_global_del_attr(ldp_global * g, ldp_attr * a)
322 MPLS_ASSERT(g && a);
323 MPLS_LIST_REMOVE(&g->attr, a, _global);
324 MPLS_REFCNT_RELEASE(a, ldp_attr_delete);
327 void _ldp_global_add_peer(ldp_global * g, ldp_peer * p)
329 ldp_peer *pp = NULL;
331 MPLS_ASSERT(g && p);
332 MPLS_REFCNT_HOLD(p);
333 pp = MPLS_LIST_HEAD(&g->peer);
334 while (pp != NULL) {
335 if (pp->index > p->index) {
336 MPLS_LIST_INSERT_BEFORE(&g->peer, pp, p, _global);
337 return;
339 pp = MPLS_LIST_NEXT(&g->peer, pp, _global);
341 MPLS_LIST_ADD_TAIL(&g->peer, p, _global, ldp_peer);
344 void _ldp_global_del_peer(ldp_global * g, ldp_peer * p)
346 MPLS_ASSERT(g && p);
347 MPLS_LIST_REMOVE(&g->peer, p, _global);
348 MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
352 * _ldp_global_add_if/del_if and _ldp_global_add_addr/del_addr are
353 * not the same as the rest of the global_add/del functions. They
354 * do not hold refcnts, they are used as part of the create and delete
355 * process of these structures
358 void _ldp_global_add_if(ldp_global * g, ldp_if * i)
360 ldp_if *ip = NULL;
362 MPLS_ASSERT(g && i);
363 ip = MPLS_LIST_HEAD(&g->iff);
364 while (ip != NULL) {
365 if (ip->index > i->index) {
366 MPLS_LIST_INSERT_BEFORE(&g->iff, ip, i, _global);
367 return;
369 ip = MPLS_LIST_NEXT(&g->iff, ip, _global);
371 MPLS_LIST_ADD_TAIL(&g->iff, i, _global, ldp_if);
374 void _ldp_global_del_if(ldp_global * g, ldp_if * i)
376 MPLS_ASSERT(g && i);
377 MPLS_LIST_REMOVE(&g->iff, i, _global);
380 void _ldp_global_add_addr(ldp_global * g, ldp_addr * a)
382 ldp_addr *ap = NULL;
384 MPLS_ASSERT(g && a);
385 ap = MPLS_LIST_HEAD(&g->addr);
386 while (ap != NULL) {
387 if (ap->index > a->index) {
388 MPLS_LIST_INSERT_BEFORE(&g->addr, ap, a, _global);
389 return;
391 ap = MPLS_LIST_NEXT(&g->addr, ap, _global);
393 MPLS_LIST_ADD_TAIL(&g->addr, a, _global, ldp_addr);
396 void _ldp_global_del_addr(ldp_global * g, ldp_addr * a)
398 MPLS_ASSERT(g && a);
399 MPLS_LIST_REMOVE(&g->addr, a, _global);
402 void _ldp_global_add_adj(ldp_global * g, ldp_adj * a)
404 ldp_adj *ap = NULL;
406 MPLS_ASSERT(g && a);
407 MPLS_REFCNT_HOLD(a);
408 ap = MPLS_LIST_HEAD(&g->adj);
409 while (ap != NULL) {
410 if (ap->index > a->index) {
411 MPLS_LIST_INSERT_BEFORE(&g->adj, ap, a, _global);
412 return;
414 ap = MPLS_LIST_NEXT(&g->adj, ap, _global);
416 MPLS_LIST_ADD_TAIL(&g->adj, a, _global, ldp_adj);
419 void _ldp_global_del_adj(ldp_global * g, ldp_adj * a)
421 MPLS_ASSERT(g && a);
422 MPLS_LIST_REMOVE(&g->adj, a, _global);
423 MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
426 void _ldp_global_add_entity(ldp_global * g, ldp_entity * e)
428 ldp_entity *ep = NULL;
430 MPLS_ASSERT(g && e);
431 MPLS_REFCNT_HOLD(e);
432 ep = MPLS_LIST_HEAD(&g->entity);
433 while (ep != NULL) {
434 if (ep->index > e->index) {
435 MPLS_LIST_INSERT_BEFORE(&g->entity, ep, e, _global);
436 return;
438 ep = MPLS_LIST_NEXT(&g->entity, ep, _global);
440 MPLS_LIST_ADD_TAIL(&g->entity, e, _global, ldp_entity);
443 void _ldp_global_del_entity(ldp_global * g, ldp_entity * e)
445 MPLS_ASSERT(g && e);
446 MPLS_LIST_REMOVE(&g->entity, e, _global);
447 MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
450 void _ldp_global_add_session(ldp_global * g, ldp_session * s)
452 ldp_session *sp = NULL;
454 MPLS_ASSERT(g && s);
455 MPLS_REFCNT_HOLD(s);
456 s->on_global = MPLS_BOOL_TRUE;
457 sp = MPLS_LIST_HEAD(&g->session);
458 while (sp != NULL) {
459 if (sp->index > s->index) {
460 MPLS_LIST_INSERT_BEFORE(&g->session, sp, s, _global);
461 return;
463 sp = MPLS_LIST_NEXT(&g->session, sp, _global);
465 MPLS_LIST_ADD_TAIL(&g->session, s, _global, ldp_session);
468 void _ldp_global_del_session(ldp_global * g, ldp_session * s)
470 MPLS_ASSERT(g && s);
471 MPLS_ASSERT(s->on_global == MPLS_BOOL_TRUE);
472 MPLS_LIST_REMOVE(&g->session, s, _global);
473 s->on_global = MPLS_BOOL_FALSE;
474 MPLS_REFCNT_RELEASE(s, ldp_session_delete);
477 mpls_return_enum _ldp_global_add_inlabel(ldp_global * g, ldp_inlabel * i)
479 ldp_inlabel *ip = NULL;
480 mpls_return_enum result;
482 MPLS_ASSERT(g && i);
484 #if MPLS_USE_LSR
486 lsr_insegment iseg;
487 memcpy(&iseg.info,&i->info,sizeof(mpls_insegment));
488 result = lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_ADD|
489 LSR_INSEGMENT_CFG_NPOP|LSR_INSEGMENT_CFG_FAMILY|
490 LSR_INSEGMENT_CFG_LABELSPACE|LSR_INSEGMENT_CFG_LABEL|
491 LSR_INSEGMENT_CFG_OWNER);
492 memcpy(&i->info, &iseg.info, sizeof(mpls_insegment));
493 i->info.handle = iseg.index;
495 #else
496 result = mpls_mpls_insegment_add(g->mpls_handle, &i->info);
497 #endif
498 if (result != MPLS_SUCCESS) {
499 return result;
502 MPLS_REFCNT_HOLD(i);
503 ip = MPLS_LIST_HEAD(&g->inlabel);
504 while (ip != NULL) {
505 if (ip->index > i->index) {
506 MPLS_LIST_INSERT_BEFORE(&g->inlabel, ip, i, _global);
507 return MPLS_SUCCESS;
509 ip = MPLS_LIST_NEXT(&g->inlabel, ip, _global);
511 MPLS_LIST_ADD_TAIL(&g->inlabel, i, _global, ldp_inlabel);
512 return MPLS_SUCCESS;
515 mpls_return_enum _ldp_global_del_inlabel(ldp_global * g, ldp_inlabel * i)
517 MPLS_ASSERT(g && i);
518 MPLS_ASSERT(i->reuse_count == 0);
519 #if MPLS_USE_LSR
521 lsr_insegment iseg;
522 iseg.index = i->info.handle;
523 lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_DEL);
525 #else
526 mpls_mpls_insegment_del(g->mpls_handle, &i->info);
527 #endif
528 MPLS_LIST_REMOVE(&g->inlabel, i, _global);
529 MPLS_REFCNT_RELEASE(i, ldp_inlabel_delete);
530 return MPLS_SUCCESS;
533 mpls_return_enum _ldp_global_add_outlabel(ldp_global * g, ldp_outlabel * o)
535 ldp_outlabel *op = NULL;
536 mpls_return_enum result;
538 MPLS_ASSERT(g && o);
539 #if MPLS_USE_LSR
541 lsr_outsegment oseg;
542 memcpy(&oseg.info, &o->info, sizeof(mpls_outsegment));
543 result = lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_ADD|
544 LSR_OUTSEGMENT_CFG_PUSH_LABEL|LSR_OUTSEGMENT_CFG_OWNER|
545 LSR_OUTSEGMENT_CFG_INTERFACE|LSR_OUTSEGMENT_CFG_LABEL|
546 LSR_OUTSEGMENT_CFG_NEXTHOP);
547 o->info.handle = oseg.index;
549 #else
550 result = mpls_mpls_outsegment_add(g->mpls_handle, &o->info);
551 #endif
553 if (result != MPLS_SUCCESS) {
554 return result;
557 MPLS_REFCNT_HOLD(o);
558 o->switching = MPLS_BOOL_TRUE;
559 op = MPLS_LIST_HEAD(&g->outlabel);
560 while (op != NULL) {
561 if (op->index > o->index) {
562 MPLS_LIST_INSERT_BEFORE(&g->outlabel, op, o, _global);
563 return MPLS_SUCCESS;
565 op = MPLS_LIST_NEXT(&g->outlabel, op, _global);
567 MPLS_LIST_ADD_TAIL(&g->outlabel, o, _global, ldp_outlabel);
568 return MPLS_SUCCESS;
571 mpls_return_enum _ldp_global_del_outlabel(ldp_global * g, ldp_outlabel * o)
573 MPLS_ASSERT(g && o);
574 #if MPLS_USE_LSR
576 lsr_outsegment oseg;
577 oseg.index = o->info.handle;
578 lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_DEL);
580 #else
581 mpls_mpls_outsegment_del(g->mpls_handle, &o->info);
582 #endif
584 o->switching = MPLS_BOOL_FALSE;
585 MPLS_ASSERT(o->merge_count == 0);
586 MPLS_LIST_REMOVE(&g->outlabel, o, _global);
587 MPLS_REFCNT_RELEASE(o, ldp_outlabel_delete);
588 return MPLS_SUCCESS;
591 mpls_return_enum ldp_global_find_attr_index(ldp_global * g, uint32_t index,
592 ldp_attr ** attr)
594 ldp_attr *a = NULL;
596 if (g && index > 0) {
598 /* because we sort our inserts by index, this lets us know
599 if we've "walked" past the end of the list */
601 a = MPLS_LIST_TAIL(&g->attr);
602 if (a == NULL || a->index < index) {
603 return MPLS_END_OF_LIST;
604 *attr = NULL;
607 a = MPLS_LIST_HEAD(&g->attr);
608 while (a != NULL) {
609 if (a->index == index) {
610 *attr = a;
611 return MPLS_SUCCESS;
613 a = MPLS_LIST_NEXT(&g->attr, a, _global);
616 *attr = NULL;
617 return MPLS_FAILURE;
620 mpls_return_enum ldp_global_find_session_index(ldp_global * g, uint32_t index,
621 ldp_session ** session)
623 ldp_session *s = NULL;
625 if (g && index > 0) {
627 /* because we sort our inserts by index, this lets us know
628 if we've "walked" past the end of the list */
630 s = MPLS_LIST_TAIL(&g->session);
631 if (s == NULL || s->index < index) {
632 *session = NULL;
633 return MPLS_END_OF_LIST;
636 s = MPLS_LIST_HEAD(&g->session);
637 while (s != NULL) {
638 if (s->index == index) {
639 *session = s;
640 return MPLS_SUCCESS;
642 s = MPLS_LIST_NEXT(&g->session, s, _global);
645 *session = NULL;
646 return MPLS_FAILURE;
649 mpls_return_enum ldp_global_find_inlabel_index(ldp_global * g, uint32_t index,
650 ldp_inlabel ** inlabel)
652 ldp_inlabel *i = NULL;
654 if (g && index > 0) {
656 /* because we sort our inserts by index, this lets us know
657 if we've "walked" past the end of the list */
659 i = MPLS_LIST_TAIL(&g->inlabel);
660 if (i == NULL || i->index < index) {
661 *inlabel = NULL;
662 return MPLS_END_OF_LIST;
665 i = MPLS_LIST_HEAD(&g->inlabel);
666 while (i != NULL) {
667 if (i->index == index) {
668 *inlabel = i;
669 return MPLS_SUCCESS;
671 i = MPLS_LIST_NEXT(&g->inlabel, i, _global);
674 *inlabel = NULL;
675 return MPLS_FAILURE;
678 mpls_return_enum ldp_global_find_outlabel_index(ldp_global * g, uint32_t index,
679 ldp_outlabel ** outlabel)
681 ldp_outlabel *o = NULL;
683 if (g && index > 0) {
685 /* because we sort our inserts by index, this lets us know
686 if we've "walked" past the end of the list */
688 o = MPLS_LIST_TAIL(&g->outlabel);
689 if (o == NULL || o->index < index) {
690 *outlabel = NULL;
691 return MPLS_END_OF_LIST;
694 o = MPLS_LIST_HEAD(&g->outlabel);
695 while (o != NULL) {
696 if (o->index == index) {
697 *outlabel = o;
698 return MPLS_SUCCESS;
700 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
703 *outlabel = NULL;
704 return MPLS_FAILURE;
707 ldp_outlabel *ldp_global_find_outlabel_handle(ldp_global * g,
708 mpls_outsegment_handle handle)
710 ldp_outlabel *o = MPLS_LIST_HEAD(&g->outlabel);
712 if (g) {
713 while (o != NULL) {
714 if (!mpls_outsegment_handle_compare(o->info.handle, handle))
715 return o;
717 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
720 return NULL;
723 mpls_return_enum ldp_global_find_entity_index(ldp_global * g, uint32_t index,
724 ldp_entity ** entity)
726 ldp_entity *e = NULL;
728 if (g && index > 0) {
730 /* because we sort our inserts by index, this lets us know
731 if we've "walked" past the end of the list */
733 e = MPLS_LIST_TAIL(&g->entity);
734 if (e == NULL || e->index < index) {
735 *entity = NULL;
736 return MPLS_END_OF_LIST;
739 e = MPLS_LIST_HEAD(&g->entity);
740 while (e != NULL) {
741 if (e->index == index) {
742 *entity = e;
743 return MPLS_SUCCESS;
745 e = MPLS_LIST_NEXT(&g->entity, e, _global);
748 *entity = NULL;
749 return MPLS_FAILURE;
752 ldp_peer *ldp_global_find_peer_addr(ldp_global * g, mpls_inet_addr * addr)
754 ldp_peer *p;
756 MPLS_ASSERT(g && addr);
758 /* JLEU: we will need to add a tree to optimize this search,
759 known peers will be in tree, unknown will take a "slow path" to
760 verify them, then be added to tree */
762 p = MPLS_LIST_HEAD(&g->peer);
763 while (p) {
764 LDP_PRINT(g->user_data,
765 "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
766 p->dest.addr.u.ipv4, addr->u.ipv4);
767 if (!mpls_inet_addr_compare(&p->dest.addr, addr)) {
768 return p;
770 p = MPLS_LIST_NEXT(&g->peer, p, _global);
772 return NULL;
775 mpls_return_enum ldp_global_find_adj_index(ldp_global * g, uint32_t index,
776 ldp_adj ** adj)
778 ldp_adj *a = NULL;
780 if (g && index > 0) {
781 /* because we sort our inserts by index, this lets us know
782 if we've "walked" past the end of the list */
784 a = MPLS_LIST_TAIL(&g->adj);
785 if (a == NULL || a->index < index) {
786 return MPLS_END_OF_LIST;
787 *adj = NULL;
790 a = MPLS_LIST_HEAD(&g->adj);
791 while (a != NULL) {
792 if (a->index == index) {
793 *adj = a;
794 return MPLS_SUCCESS;
796 a = MPLS_LIST_NEXT(&g->adj, a, _global);
799 *adj = NULL;
800 return MPLS_FAILURE;
803 mpls_return_enum ldp_global_find_peer_index(ldp_global * g, uint32_t index,
804 ldp_peer ** peer)
806 ldp_peer *p = NULL;
808 if (g && index > 0) {
809 /* because we sort our inserts by index, this lets us know
810 if we've "walked" past the end of the list */
812 p = MPLS_LIST_TAIL(&g->peer);
813 if (p == NULL || p->index < index) {
814 *peer = NULL;
815 return MPLS_END_OF_LIST;
818 p = MPLS_LIST_HEAD(&g->peer);
819 while (p != NULL) {
820 if (p->index == index) {
821 *peer = p;
822 return MPLS_SUCCESS;
824 p = MPLS_LIST_NEXT(&g->peer, p, _global);
827 *peer = NULL;
828 return MPLS_FAILURE;
831 mpls_return_enum ldp_global_find_fec_index(ldp_global * g, uint32_t index,
832 ldp_fec ** fec)
834 ldp_fec *f = NULL;
836 if (g && index > 0) {
837 /* because we sort our inserts by index, this lets us know
838 if we've "walked" past the end of the list */
840 f = MPLS_LIST_TAIL(&g->fec);
841 if (f == NULL || f->index < index) {
842 *fec = NULL;
843 return MPLS_END_OF_LIST;
846 f = MPLS_LIST_HEAD(&g->fec);
847 while (f != NULL) {
848 if (f->index == index) {
849 *fec = f;
850 return MPLS_SUCCESS;
852 f = MPLS_LIST_NEXT(&g->fec, f, _global);
855 *fec = NULL;
856 return MPLS_FAILURE;
859 mpls_return_enum ldp_global_find_fec(ldp_global * g, mpls_fec * m,
860 ldp_fec ** fec)
862 ldp_fec *f = NULL;
864 MPLS_ASSERT(g && m);
866 f = MPLS_LIST_HEAD(&g->fec);
867 do {
868 if (!mpls_fec_compare(m, &f->info)) {
869 *fec = f;
870 return MPLS_SUCCESS;
872 } while((f = MPLS_LIST_NEXT(&g->fec, f, _global)));
873 *fec = NULL;
874 return MPLS_FAILURE;
877 mpls_return_enum ldp_global_find_addr_index(ldp_global * g, uint32_t index,
878 ldp_addr ** addr)
880 ldp_addr *a = NULL;
882 if (g && index > 0) {
884 /* because we sort our inserts by index, this lets us know
885 if we've "walked" past the end of the list */
887 a = MPLS_LIST_TAIL(&g->addr);
888 if (a == NULL || a->index < index) {
889 *addr = NULL;
890 return MPLS_END_OF_LIST;
893 a = MPLS_LIST_HEAD(&g->addr);
894 while (a != NULL) {
895 if (a->index == index) {
896 *addr = a;
897 return MPLS_SUCCESS;
899 a = MPLS_LIST_NEXT(&g->addr, a, _global);
902 *addr = NULL;
903 return MPLS_FAILURE;
906 mpls_return_enum ldp_global_find_if_index(ldp_global * g, uint32_t index,
907 ldp_if ** iff)
909 ldp_if *i = NULL;
911 if (g && index > 0) {
913 /* because we sort our inserts by index, this lets us know
914 if we've "walked" past the end of the list */
916 i = MPLS_LIST_TAIL(&g->iff);
917 if (i == NULL || i->index < index) {
918 *iff = NULL;
919 return MPLS_END_OF_LIST;
922 i = MPLS_LIST_HEAD(&g->iff);
923 while (i != NULL) {
924 if (i->index == index) {
925 *iff = i;
926 return MPLS_SUCCESS;
928 i = MPLS_LIST_NEXT(&g->iff, i, _global);
931 *iff = NULL;
932 return MPLS_FAILURE;
935 ldp_if *ldp_global_find_if_handle(ldp_global * g, mpls_if_handle handle)
937 ldp_if *i = MPLS_LIST_HEAD(&g->iff);
939 if (g) {
940 while (i != NULL) {
941 if (!mpls_if_handle_compare(i->handle, handle))
942 return i;
944 i = MPLS_LIST_NEXT(&g->iff, i, _global);
947 return NULL;
950 ldp_adj *ldp_global_find_adj_ldpid(ldp_global * g, mpls_inet_addr * lsraddr,
951 int labelspace)
954 ldp_adj *a = MPLS_LIST_HEAD(&g->adj);
956 while (a != NULL) {
957 if ((!mpls_inet_addr_compare(lsraddr, &a->remote_lsr_address)) &&
958 labelspace == a->remote_label_space)
959 return a;
961 a = MPLS_LIST_NEXT(&g->adj, a, _global);
963 return NULL;
966 mpls_return_enum ldp_global_find_tunnel_index(ldp_global * g, uint32_t index,
967 ldp_tunnel ** tunnel)
969 ldp_tunnel *t = NULL;
971 if (g && index > 0) {
972 /* because we sort our inserts by index, this lets us know
973 if we've "walked" past the end of the list */
975 t = MPLS_LIST_TAIL(&g->tunnel);
976 if (t == NULL || t->index < index) {
977 *tunnel = NULL;
978 return MPLS_END_OF_LIST;
981 t = MPLS_LIST_HEAD(&g->tunnel);
982 while (t != NULL) {
983 if (t->index == index) {
984 *tunnel = t;
985 return MPLS_SUCCESS;
987 t = MPLS_LIST_NEXT(&g->tunnel, t, _global);
990 *tunnel = NULL;
991 return MPLS_FAILURE;
994 mpls_return_enum ldp_global_find_resource_index(ldp_global * g, uint32_t index,
995 ldp_resource ** resource)
997 ldp_resource *r = NULL;
999 if (g && index > 0) {
1000 /* because we sort our inserts by index, this lets us know
1001 if we've "walked" past the end of the list */
1003 r = MPLS_LIST_TAIL(&g->resource);
1004 if (r == NULL || r->index < index) {
1005 *resource = NULL;
1006 return MPLS_END_OF_LIST;
1009 r = MPLS_LIST_HEAD(&g->resource);
1010 while (r != NULL) {
1011 if (r->index == index) {
1012 *resource = r;
1013 return MPLS_SUCCESS;
1015 r = MPLS_LIST_NEXT(&g->resource, r, _global);
1018 *resource = NULL;
1019 return MPLS_FAILURE;
1022 mpls_return_enum ldp_global_find_hop_list_index(ldp_global * g, uint32_t index,
1023 ldp_hop_list ** hop_list)
1025 ldp_hop_list *h = NULL;
1027 if (g && index > 0) {
1028 /* because we sort our inserts by index, this lets us know
1029 if we've "walked" past the end of the list */
1031 h = MPLS_LIST_TAIL(&g->hop_list);
1032 if (h == NULL || h->index < index) {
1033 *hop_list = NULL;
1034 return MPLS_END_OF_LIST;
1037 h = MPLS_LIST_HEAD(&g->hop_list);
1038 while (h != NULL) {
1039 if (h->index == index) {
1040 *hop_list = h;
1041 return MPLS_SUCCESS;
1043 h = MPLS_LIST_NEXT(&g->hop_list, h, _global);
1046 *hop_list = NULL;
1047 return MPLS_FAILURE;
1050 void _ldp_global_add_tunnel(ldp_global * g, ldp_tunnel * t)
1052 ldp_tunnel *tp = NULL;
1054 MPLS_ASSERT(g && t);
1055 MPLS_REFCNT_HOLD(t);
1056 tp = MPLS_LIST_HEAD(&g->tunnel);
1057 while (tp != NULL) {
1058 if (tp->index > t->index) {
1059 MPLS_LIST_INSERT_BEFORE(&g->tunnel, tp, t, _global);
1060 return;
1062 tp = MPLS_LIST_NEXT(&g->tunnel, tp, _global);
1064 MPLS_LIST_ADD_TAIL(&g->tunnel, t, _global, ldp_tunnel);
1067 void _ldp_global_del_tunnel(ldp_global * g, ldp_tunnel * t)
1069 MPLS_ASSERT(g && t);
1070 MPLS_LIST_REMOVE(&g->tunnel, t, _global);
1071 MPLS_REFCNT_RELEASE(t, ldp_tunnel_delete);
1074 void _ldp_global_add_resource(ldp_global * g, ldp_resource * r)
1076 ldp_resource *rp = NULL;
1078 MPLS_ASSERT(g && r);
1079 MPLS_REFCNT_HOLD(r);
1080 rp = MPLS_LIST_HEAD(&g->resource);
1081 while (rp != NULL) {
1082 if (rp->index > r->index) {
1083 MPLS_LIST_INSERT_BEFORE(&g->resource, rp, r, _global);
1084 return;
1086 rp = MPLS_LIST_NEXT(&g->resource, rp, _global);
1088 MPLS_LIST_ADD_TAIL(&g->resource, r, _global, ldp_resource);
1091 void _ldp_global_del_resource(ldp_global * g, ldp_resource * r)
1093 MPLS_ASSERT(g && r);
1094 MPLS_LIST_REMOVE(&g->resource, r, _global);
1095 MPLS_REFCNT_RELEASE(r, ldp_resource_delete);
1098 void _ldp_global_add_hop_list(ldp_global * g, ldp_hop_list * h)
1100 ldp_hop_list *hp = NULL;
1102 MPLS_ASSERT(g && h);
1103 MPLS_REFCNT_HOLD(h);
1104 hp = MPLS_LIST_HEAD(&g->hop_list);
1105 while (hp != NULL) {
1106 if (hp->index > h->index) {
1107 MPLS_LIST_INSERT_BEFORE(&g->hop_list, hp, h, _global);
1108 return;
1110 hp = MPLS_LIST_NEXT(&g->hop_list, hp, _global);
1112 MPLS_LIST_ADD_TAIL(&g->hop_list, h, _global, ldp_hop_list);
1115 void _ldp_global_del_hop_list(ldp_global * g, ldp_hop_list * h)
1117 MPLS_ASSERT(g && h);
1118 MPLS_LIST_REMOVE(&g->hop_list, h, _global);
1119 MPLS_REFCNT_RELEASE(h, ldp_hop_list_delete);
1122 void _ldp_global_add_fec(ldp_global * g, ldp_fec * f)
1124 ldp_fec *fp = NULL;
1126 MPLS_ASSERT(g && f);
1128 * TESTING: jleu 6/7/2004, since I want the FEC to be cleaned up
1129 * when it no longer has a nexthop, addr, or label, the only things that
1130 * should increment the ref are those (nh, addr, label etc), not global
1131 * nor inserting into the tree. I also added this comment in
1132 * ldp_fec_create()
1133 MPLS_REFCNT_HOLD(f);
1135 fp = MPLS_LIST_HEAD(&g->fec);
1136 while (fp != NULL) {
1137 if (fp->index > f->index) {
1138 MPLS_LIST_INSERT_BEFORE(&g->fec, fp, f, _global);
1139 return;
1141 fp = MPLS_LIST_NEXT(&g->fec, fp, _global);
1143 MPLS_LIST_ADD_TAIL(&g->fec, f, _global, ldp_fec);
1146 void _ldp_global_del_fec(ldp_global * g, ldp_fec * f)
1148 MPLS_ASSERT(g && f);
1149 MPLS_LIST_REMOVE(&g->fec, f, _global);
1152 void _ldp_global_add_nexthop(ldp_global * g, ldp_nexthop * nh)
1154 ldp_nexthop *nhp = NULL;
1156 MPLS_ASSERT(g && nh);
1157 nhp = MPLS_LIST_HEAD(&g->nexthop);
1158 while (nhp != NULL) {
1159 if (nhp->index > nh->index) {
1160 MPLS_LIST_INSERT_BEFORE(&g->nexthop, nhp, nh, _global);
1161 return;
1163 nhp = MPLS_LIST_NEXT(&g->nexthop, nhp, _global);
1165 MPLS_LIST_ADD_TAIL(&g->nexthop, nh, _global, ldp_nexthop);
1168 void _ldp_global_del_nexthop(ldp_global * g, ldp_nexthop * nh)
1170 MPLS_ASSERT(g && nh);
1171 MPLS_LIST_REMOVE(&g->nexthop, nh, _global);