First step towards making this work:
[mpls-ldp-portable.git] / ldp / ldp_global.c
blob92a9507be327cd0ecb12c04ab6076f35126c7ae9
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 void _ldp_global_ifmgr_callback(mpls_cfg_handle handle, const mpls_update_enum type, mpls_inet_addr *addr)
52 ldp_session *s = NULL;
53 ldp_global *cfg = (ldp_global*)handle;
55 LDP_ENTER(cfg->user_data, "_ldp_global_ifmgr_callback");
57 mpls_lock_get(cfg->global_lock);
59 if (mpls_policy_address_export_check(cfg->user_data, addr) == MPLS_BOOL_TRUE) {
60 s = MPLS_LIST_HEAD(&cfg->session);
61 while (s != NULL) {
62 switch (type) {
63 case MPLS_UPDATE_ADD:
64 LDP_TRACE_LOG(cfg->user_data, MPLS_TRACE_STATE_ALL,
65 LDP_TRACE_FLAG_EVENT, "ADD\n");
66 ldp_addr_send(cfg, s, addr);
67 break;
68 case MPLS_UPDATE_DEL:
69 LDP_TRACE_LOG(cfg->user_data, MPLS_TRACE_STATE_ALL,
70 LDP_TRACE_FLAG_EVENT, "DEL\n");
71 ldp_waddr_send(cfg, s, addr);
72 break;
73 default:
74 MPLS_ASSERT(0);
76 s = MPLS_LIST_NEXT(&cfg->session, s, _global);
80 mpls_lock_release(cfg->global_lock);
82 LDP_EXIT(cfg->user_data, "_ldp_global_ifmgr_callback");
85 ldp_global *ldp_global_create(mpls_instance_handle data)
87 ldp_global *g = (ldp_global *) mpls_malloc(sizeof(ldp_global));
89 if (g) {
90 memset(g, 0, sizeof(ldp_global));
92 LDP_ENTER(g->user_data, "ldp_global_create");
94 g->global_lock = mpls_lock_create("_ldp_global_lock_");
95 mpls_lock_get(g->global_lock);
97 MPLS_LIST_INIT(&g->hop_list, ldp_hop_list);
98 MPLS_LIST_INIT(&g->outlabel, ldp_outlabel);
99 MPLS_LIST_INIT(&g->resource, ldp_resource);
100 MPLS_LIST_INIT(&g->inlabel, ldp_inlabel);
101 MPLS_LIST_INIT(&g->session, ldp_session);
102 MPLS_LIST_INIT(&g->nexthop, ldp_nexthop);
103 MPLS_LIST_INIT(&g->tunnel, ldp_tunnel);
104 MPLS_LIST_INIT(&g->entity, ldp_entity);
105 MPLS_LIST_INIT(&g->attr, ldp_attr);
106 MPLS_LIST_INIT(&g->peer, ldp_peer);
107 MPLS_LIST_INIT(&g->fec, ldp_fec);
108 MPLS_LIST_INIT(&g->adj, ldp_adj);
109 MPLS_LIST_INIT(&g->iff, ldp_if);
111 g->message_identifier = 1;
112 g->configuration_sequence_number = 1;
113 g->lsp_control_mode = LDP_GLOBAL_DEF_CONTROL_MODE;
114 g->label_retention_mode = LDP_GLOBAL_DEF_RETENTION_MODE;
115 g->lsp_repair_mode = LDP_GLOBAL_DEF_REPAIR_MODE;
116 g->propagate_release = LDP_GLOBAL_DEF_PROPOGATE_RELEASE;
117 g->label_merge = LDP_GLOBAL_DEF_LABEL_MERGE;
118 g->loop_detection_mode = LDP_GLOBAL_DEF_LOOP_DETECTION_MODE;
119 g->ttl_less_domain = LDP_GLOBAL_DEF_TTLLESS_DOMAIN;
120 g->local_tcp_port = LDP_GLOBAL_DEF_LOCAL_TCP_PORT;
121 g->local_udp_port = LDP_GLOBAL_DEF_LOCAL_UDP_PORT;
122 g->send_address_messages = LDP_GLOBAL_DEF_SEND_ADDR_MSG;
123 g->backoff_step = LDP_GLOBAL_DEF_BACKOFF_STEP;
124 g->send_lsrid_mapping = LDP_GLOBAL_DEF_SEND_LSRID_MAPPING;
125 g->no_route_to_peer_time = LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME;
127 g->keepalive_timer = LDP_ENTITY_DEF_KEEPALIVE_TIMER;
128 g->keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL;
129 g->hellotime_timer = LDP_ENTITY_DEF_HELLOTIME_TIMER;
130 g->hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL;
132 g->admin_state = MPLS_ADMIN_DISABLE;
133 g->user_data = data;
135 mpls_lock_release(g->global_lock);
137 LDP_EXIT(g->user_data, "ldp_global_create");
140 return g;
143 mpls_return_enum ldp_global_startup(ldp_global * g)
145 ldp_entity *e = NULL;
146 mpls_dest dest;
148 MPLS_ASSERT(g != NULL);
150 LDP_ENTER(g->user_data, "ldp_global_startup");
152 if (g->lsr_identifier.type == MPLS_FAMILY_NONE) {
153 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
154 "ldp_global_startup: invalid LSRID\n");
155 goto ldp_global_startup_cleanup;
158 g->timer_handle = mpls_timer_open(g->user_data);
159 if (mpls_timer_mgr_handle_verify(g->timer_handle) == MPLS_BOOL_FALSE) {
160 goto ldp_global_startup_cleanup;
163 g->socket_handle = mpls_socket_mgr_open(g->user_data);
164 if (mpls_socket_mgr_handle_verify(g->socket_handle) == MPLS_BOOL_FALSE) {
165 goto ldp_global_startup_cleanup;
168 g->ifmgr_handle = mpls_ifmgr_open(g->user_data, g, _ldp_global_ifmgr_callback);
169 if (mpls_ifmgr_handle_verify(g->ifmgr_handle) == MPLS_BOOL_FALSE) {
170 goto ldp_global_startup_cleanup;
173 g->fib_handle = mpls_fib_open(g->user_data, g);
174 if (mpls_fib_handle_verify(g->fib_handle) == MPLS_BOOL_FALSE) {
175 goto ldp_global_startup_cleanup;
178 #if MPLS_USE_LSR
179 if (!g->lsr_handle) {
180 goto ldp_global_startup_cleanup;
182 #else
183 g->mpls_handle = mpls_mpls_open(g->user_data);
184 if (mpls_mpls_handle_verify(g->mpls_handle) == MPLS_BOOL_FALSE) {
185 goto ldp_global_startup_cleanup;
187 #endif
189 g->addr_tree = mpls_tree_create(32);
190 g->fec_tree = mpls_tree_create(32);
192 g->hello_socket = mpls_socket_create_udp(g->socket_handle);
193 if (mpls_socket_handle_verify(g->socket_handle, g->hello_socket) == MPLS_BOOL_FALSE) {
194 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
195 "ldp_global_startup: error creating UDP socket\n");
196 goto ldp_global_startup_cleanup;
199 dest.addr.type = MPLS_FAMILY_IPV4;
200 dest.port = g->local_udp_port;
201 dest.addr.u.ipv4 = INADDR_ANY;
202 // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
204 if (mpls_socket_bind(g->socket_handle, g->hello_socket, &dest) == MPLS_FAILURE) {
205 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
206 "ldp_global_startup: error binding UDP socket\n");
207 goto ldp_global_startup_cleanup;
210 if (mpls_socket_options(g->socket_handle, g->hello_socket,
211 MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) {
212 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
213 "ldp_global_startup: error setting UDP socket options\n");
214 goto ldp_global_startup_cleanup;
216 if (mpls_socket_multicast_options(g->socket_handle, g->hello_socket, 1, 0) ==
217 MPLS_FAILURE) {
218 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
219 "ldp_global_startup: error setting UDP socket multicast options\n");
220 goto ldp_global_startup_cleanup;
222 mpls_socket_readlist_add(g->socket_handle, g->hello_socket, 0, MPLS_SOCKET_UDP_DATA);
224 g->listen_socket = mpls_socket_create_tcp(g->socket_handle);
225 if (mpls_socket_handle_verify(g->socket_handle, g->listen_socket) == MPLS_BOOL_FALSE) {
226 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
227 "ldp_global_startup: error creating TCP socket\n");
228 goto ldp_global_startup_cleanup;
230 if (mpls_socket_options(g->socket_handle, g->listen_socket,
231 MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) {
232 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
233 "ldp_global_startup: error setting TCP socket options\n");
234 goto ldp_global_startup_cleanup;
237 dest.addr.type = MPLS_FAMILY_IPV4;
238 dest.port = g->local_tcp_port;
239 dest.addr.u.ipv4 = INADDR_ANY;
241 if (mpls_socket_bind(g->socket_handle, g->listen_socket, &dest) == MPLS_FAILURE) {
242 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
243 "ldp_global_startup: error binding TCP socket\n");
244 goto ldp_global_startup_cleanup;
247 if (mpls_socket_tcp_listen(g->socket_handle, g->listen_socket, 15) ==
248 MPLS_FAILURE) {
249 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
250 "ldp_global_startup: error setting listen buffer for TCP socket\n");
251 goto ldp_global_startup_cleanup;
254 mpls_socket_readlist_add(g->socket_handle, g->listen_socket, 0,
255 MPLS_SOCKET_TCP_LISTEN);
257 e = MPLS_LIST_HEAD(&g->entity);
258 while (e != NULL) {
259 ldp_entity_startup(g, e);
260 e = MPLS_LIST_NEXT(&g->entity, e, _global);
263 g->admin_state = MPLS_ADMIN_ENABLE;
265 LDP_EXIT(g->user_data, "ldp_global_startup");
266 return MPLS_SUCCESS;
268 ldp_global_startup_cleanup:
269 ldp_global_shutdown(g);
270 mpls_socket_close(g->socket_handle, g->hello_socket);
271 mpls_socket_close(g->socket_handle, g->listen_socket);
272 g->hello_socket = 0;
273 g->listen_socket = 0;
275 LDP_EXIT(g->user_data, "ldp_global_startup-error");
277 return MPLS_FAILURE;
280 mpls_return_enum ldp_global_shutdown(ldp_global * g)
282 ldp_entity *e = NULL;
284 MPLS_ASSERT(g);
286 LDP_ENTER(g->user_data, "ldp_global_shutdown");
288 e = MPLS_LIST_HEAD(&g->entity);
289 while (e != NULL) {
290 ldp_entity_shutdown(g, e, 1);
291 e = MPLS_LIST_NEXT(&g->entity, e, _global);
294 g->admin_state = MPLS_ADMIN_DISABLE;
296 mpls_socket_readlist_del(g->socket_handle, g->hello_socket);
297 mpls_socket_close(g->socket_handle, g->hello_socket);
299 mpls_socket_readlist_del(g->socket_handle, g->listen_socket);
300 mpls_socket_close(g->socket_handle, g->listen_socket);
302 mpls_tree_delete(g->addr_tree);
303 mpls_tree_delete(g->fec_tree);
305 mpls_lock_release(g->global_lock);
306 mpls_timer_close(g->timer_handle);
307 mpls_lock_get(g->global_lock);
309 mpls_socket_mgr_close(g->socket_handle);
310 mpls_ifmgr_close(g->ifmgr_handle);
311 mpls_fib_close(g->fib_handle);
313 #if MPLS_USE_LSR
314 #else
315 mpls_mpls_close(g->mpls_handle);
316 #endif
318 LDP_EXIT(g->user_data, "ldp_global_shutdown");
320 return MPLS_SUCCESS;
323 mpls_return_enum ldp_global_delete(ldp_global * g)
325 if (g) {
326 mpls_lock_delete(g->global_lock);
327 LDP_PRINT(g->user_data, "global delete\n");
328 mpls_free(g);
330 return MPLS_SUCCESS;
333 void _ldp_global_add_attr(ldp_global * g, ldp_attr * a)
335 ldp_attr *ap = NULL;
337 MPLS_ASSERT(g && a);
338 MPLS_REFCNT_HOLD(a);
339 ap = MPLS_LIST_HEAD(&g->attr);
340 while (ap != NULL) {
341 if (ap->index > a->index) {
342 MPLS_LIST_INSERT_BEFORE(&g->attr, ap, a, _global);
343 return;
345 ap = MPLS_LIST_NEXT(&g->attr, ap, _global);
347 MPLS_LIST_ADD_TAIL(&g->attr, a, _global, ldp_attr);
350 void _ldp_global_del_attr(ldp_global * g, ldp_attr * a)
352 MPLS_ASSERT(g && a);
353 MPLS_LIST_REMOVE(&g->attr, a, _global);
354 MPLS_REFCNT_RELEASE(a, ldp_attr_delete);
357 void _ldp_global_add_peer(ldp_global * g, ldp_peer * p)
359 ldp_peer *pp = NULL;
361 MPLS_ASSERT(g && p);
362 MPLS_REFCNT_HOLD(p);
363 pp = MPLS_LIST_HEAD(&g->peer);
364 while (pp != NULL) {
365 if (pp->index > p->index) {
366 MPLS_LIST_INSERT_BEFORE(&g->peer, pp, p, _global);
367 return;
369 pp = MPLS_LIST_NEXT(&g->peer, pp, _global);
371 MPLS_LIST_ADD_TAIL(&g->peer, p, _global, ldp_peer);
374 void _ldp_global_del_peer(ldp_global * g, ldp_peer * p)
376 MPLS_ASSERT(g && p);
377 MPLS_LIST_REMOVE(&g->peer, p, _global);
378 MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
381 void _ldp_global_add_if(ldp_global * g, ldp_if * i)
383 ldp_if *ip = NULL;
385 MPLS_ASSERT(g && i);
386 MPLS_REFCNT_HOLD(i);
387 ip = MPLS_LIST_HEAD(&g->iff);
388 while (ip != NULL) {
389 if (ip->index > i->index) {
390 MPLS_LIST_INSERT_BEFORE(&g->iff, ip, i, _global);
391 return;
393 ip = MPLS_LIST_NEXT(&g->iff, ip, _global);
395 MPLS_LIST_ADD_TAIL(&g->iff, i, _global, ldp_if);
398 void _ldp_global_del_if(ldp_global * g, ldp_if * i)
400 MPLS_ASSERT(g && i);
401 MPLS_LIST_REMOVE(&g->iff, i, _global);
402 MPLS_REFCNT_RELEASE(i, ldp_if_delete);
405 void _ldp_global_add_adj(ldp_global * g, ldp_adj * a)
407 ldp_adj *ap = NULL;
409 MPLS_ASSERT(g && a);
410 MPLS_REFCNT_HOLD(a);
411 ap = MPLS_LIST_HEAD(&g->adj);
412 while (ap != NULL) {
413 if (ap->index > a->index) {
414 MPLS_LIST_INSERT_BEFORE(&g->adj, ap, a, _global);
415 return;
417 ap = MPLS_LIST_NEXT(&g->adj, ap, _global);
419 MPLS_LIST_ADD_TAIL(&g->adj, a, _global, ldp_adj);
422 void _ldp_global_del_adj(ldp_global * g, ldp_adj * a)
424 MPLS_ASSERT(g && a);
425 MPLS_LIST_REMOVE(&g->adj, a, _global);
426 MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
429 void _ldp_global_add_entity(ldp_global * g, ldp_entity * e)
431 ldp_entity *ep = NULL;
433 MPLS_ASSERT(g && e);
434 MPLS_REFCNT_HOLD(e);
435 ep = MPLS_LIST_HEAD(&g->entity);
436 while (ep != NULL) {
437 if (ep->index > e->index) {
438 MPLS_LIST_INSERT_BEFORE(&g->entity, ep, e, _global);
439 return;
441 ep = MPLS_LIST_NEXT(&g->entity, ep, _global);
443 MPLS_LIST_ADD_TAIL(&g->entity, e, _global, ldp_entity);
446 void _ldp_global_del_entity(ldp_global * g, ldp_entity * e)
448 MPLS_ASSERT(g && e);
449 MPLS_LIST_REMOVE(&g->entity, e, _global);
450 MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
453 void _ldp_global_add_session(ldp_global * g, ldp_session * s)
455 ldp_session *sp = NULL;
457 MPLS_ASSERT(g && s);
458 MPLS_REFCNT_HOLD(s);
459 s->on_global = MPLS_BOOL_TRUE;
460 sp = MPLS_LIST_HEAD(&g->session);
461 while (sp != NULL) {
462 if (sp->index > s->index) {
463 MPLS_LIST_INSERT_BEFORE(&g->session, sp, s, _global);
464 return;
466 sp = MPLS_LIST_NEXT(&g->session, sp, _global);
468 MPLS_LIST_ADD_TAIL(&g->session, s, _global, ldp_session);
471 void _ldp_global_del_session(ldp_global * g, ldp_session * s)
473 MPLS_ASSERT(g && s);
474 MPLS_ASSERT(s->on_global == MPLS_BOOL_TRUE);
475 MPLS_LIST_REMOVE(&g->session, s, _global);
476 s->on_global = MPLS_BOOL_FALSE;
477 MPLS_REFCNT_RELEASE(s, ldp_session_delete);
480 mpls_return_enum _ldp_global_add_inlabel(ldp_global * g, ldp_inlabel * i)
482 ldp_inlabel *ip = NULL;
483 mpls_return_enum result;
485 MPLS_ASSERT(g && i);
487 #if MPLS_USE_LSR
489 lsr_insegment iseg;
490 memcpy(&iseg.info,&i->info,sizeof(mpls_insegment));
491 result = lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_ADD|
492 LSR_INSEGMENT_CFG_NPOP|LSR_INSEGMENT_CFG_FAMILY|
493 LSR_INSEGMENT_CFG_LABELSPACE|LSR_INSEGMENT_CFG_LABEL|
494 LSR_INSEGMENT_CFG_OWNER);
495 memcpy(&i->info, &iseg.info, sizeof(mpls_insegment));
496 i->info.handle = iseg.index;
498 #else
499 result = mpls_mpls_insegment_add(g->mpls_handle, &i->info);
500 #endif
501 if (result != MPLS_SUCCESS) {
502 return result;
505 MPLS_REFCNT_HOLD(i);
506 ip = MPLS_LIST_HEAD(&g->inlabel);
507 while (ip != NULL) {
508 if (ip->index > i->index) {
509 MPLS_LIST_INSERT_BEFORE(&g->inlabel, ip, i, _global);
510 return MPLS_SUCCESS;
512 ip = MPLS_LIST_NEXT(&g->inlabel, ip, _global);
514 MPLS_LIST_ADD_TAIL(&g->inlabel, i, _global, ldp_inlabel);
515 return MPLS_SUCCESS;
518 mpls_return_enum _ldp_global_del_inlabel(ldp_global * g, ldp_inlabel * i)
520 MPLS_ASSERT(g && i);
521 MPLS_ASSERT(i->reuse_count == 0);
522 #if MPLS_USE_LSR
524 lsr_insegment iseg;
525 iseg.index = i->info.handle;
526 lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_DEL);
528 #else
529 mpls_mpls_insegment_del(g->mpls_handle, &i->info);
530 #endif
531 MPLS_LIST_REMOVE(&g->inlabel, i, _global);
532 MPLS_REFCNT_RELEASE(i, ldp_inlabel_delete);
533 return MPLS_SUCCESS;
536 mpls_return_enum _ldp_global_add_outlabel(ldp_global * g, ldp_outlabel * o)
538 ldp_outlabel *op = NULL;
539 mpls_return_enum result;
541 MPLS_ASSERT(g && o);
542 #if MPLS_USE_LSR
544 lsr_outsegment oseg;
545 memcpy(&oseg.info, &o->info, sizeof(mpls_outsegment));
546 result = lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_ADD|
547 LSR_OUTSEGMENT_CFG_PUSH_LABEL|LSR_OUTSEGMENT_CFG_OWNER|
548 LSR_OUTSEGMENT_CFG_INTERFACE|LSR_OUTSEGMENT_CFG_LABEL|
549 LSR_OUTSEGMENT_CFG_NEXTHOP);
550 o->info.handle = oseg.index;
552 #else
553 result = mpls_mpls_outsegment_add(g->mpls_handle, &o->info);
554 #endif
556 if (result != MPLS_SUCCESS) {
557 return result;
560 MPLS_REFCNT_HOLD(o);
561 o->switching = MPLS_BOOL_TRUE;
562 op = MPLS_LIST_HEAD(&g->outlabel);
563 while (op != NULL) {
564 if (op->index > o->index) {
565 MPLS_LIST_INSERT_BEFORE(&g->outlabel, op, o, _global);
566 return MPLS_SUCCESS;
568 op = MPLS_LIST_NEXT(&g->outlabel, op, _global);
570 MPLS_LIST_ADD_TAIL(&g->outlabel, o, _global, ldp_outlabel);
571 return MPLS_SUCCESS;
574 mpls_return_enum _ldp_global_del_outlabel(ldp_global * g, ldp_outlabel * o)
576 MPLS_ASSERT(g && o);
577 #if MPLS_USE_LSR
579 lsr_outsegment oseg;
580 oseg.index = o->info.handle;
581 lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_DEL);
583 #else
584 mpls_mpls_outsegment_del(g->mpls_handle, &o->info);
585 #endif
587 o->switching = MPLS_BOOL_FALSE;
588 MPLS_ASSERT(o->merge_count == 0);
589 MPLS_LIST_REMOVE(&g->outlabel, o, _global);
590 MPLS_REFCNT_RELEASE(o, ldp_outlabel_delete);
591 return MPLS_SUCCESS;
594 mpls_return_enum ldp_global_find_attr_index(ldp_global * g, uint32_t index,
595 ldp_attr ** attr)
597 ldp_attr *a = NULL;
599 if (g && index > 0) {
601 /* because we sort our inserts by index, this lets us know
602 if we've "walked" past the end of the list */
604 a = MPLS_LIST_TAIL(&g->attr);
605 if (a == NULL || a->index < index) {
606 return MPLS_END_OF_LIST;
607 *attr = NULL;
610 a = MPLS_LIST_HEAD(&g->attr);
611 while (a != NULL) {
612 if (a->index == index) {
613 *attr = a;
614 return MPLS_SUCCESS;
616 a = MPLS_LIST_NEXT(&g->attr, a, _global);
619 *attr = NULL;
620 return MPLS_FAILURE;
623 mpls_return_enum ldp_global_find_session_index(ldp_global * g, uint32_t index,
624 ldp_session ** session)
626 ldp_session *s = NULL;
628 if (g && index > 0) {
630 /* because we sort our inserts by index, this lets us know
631 if we've "walked" past the end of the list */
633 s = MPLS_LIST_TAIL(&g->session);
634 if (s == NULL || s->index < index) {
635 *session = NULL;
636 return MPLS_END_OF_LIST;
639 s = MPLS_LIST_HEAD(&g->session);
640 while (s != NULL) {
641 if (s->index == index) {
642 *session = s;
643 return MPLS_SUCCESS;
645 s = MPLS_LIST_NEXT(&g->session, s, _global);
648 *session = NULL;
649 return MPLS_FAILURE;
652 mpls_return_enum ldp_global_find_inlabel_index(ldp_global * g, uint32_t index,
653 ldp_inlabel ** inlabel)
655 ldp_inlabel *i = NULL;
657 if (g && index > 0) {
659 /* because we sort our inserts by index, this lets us know
660 if we've "walked" past the end of the list */
662 i = MPLS_LIST_TAIL(&g->inlabel);
663 if (i == NULL || i->index < index) {
664 *inlabel = NULL;
665 return MPLS_END_OF_LIST;
668 i = MPLS_LIST_HEAD(&g->inlabel);
669 while (i != NULL) {
670 if (i->index == index) {
671 *inlabel = i;
672 return MPLS_SUCCESS;
674 i = MPLS_LIST_NEXT(&g->inlabel, i, _global);
677 *inlabel = NULL;
678 return MPLS_FAILURE;
681 mpls_return_enum ldp_global_find_outlabel_index(ldp_global * g, uint32_t index,
682 ldp_outlabel ** outlabel)
684 ldp_outlabel *o = NULL;
686 if (g && index > 0) {
688 /* because we sort our inserts by index, this lets us know
689 if we've "walked" past the end of the list */
691 o = MPLS_LIST_TAIL(&g->outlabel);
692 if (o == NULL || o->index < index) {
693 *outlabel = NULL;
694 return MPLS_END_OF_LIST;
697 o = MPLS_LIST_HEAD(&g->outlabel);
698 while (o != NULL) {
699 if (o->index == index) {
700 *outlabel = o;
701 return MPLS_SUCCESS;
703 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
706 *outlabel = NULL;
707 return MPLS_FAILURE;
710 ldp_outlabel *ldp_global_find_outlabel_handle(ldp_global * g,
711 mpls_outsegment_handle handle)
713 ldp_outlabel *o = MPLS_LIST_HEAD(&g->outlabel);
715 if (g) {
716 while (o != NULL) {
717 if (!mpls_outsegment_handle_compare(o->info.handle, handle))
718 return o;
720 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
723 return NULL;
726 mpls_return_enum ldp_global_find_entity_index(ldp_global * g, uint32_t index,
727 ldp_entity ** entity)
729 ldp_entity *e = NULL;
731 if (g && index > 0) {
733 /* because we sort our inserts by index, this lets us know
734 if we've "walked" past the end of the list */
736 e = MPLS_LIST_TAIL(&g->entity);
737 if (e == NULL || e->index < index) {
738 *entity = NULL;
739 return MPLS_END_OF_LIST;
742 e = MPLS_LIST_HEAD(&g->entity);
743 while (e != NULL) {
744 if (e->index == index) {
745 *entity = e;
746 return MPLS_SUCCESS;
748 e = MPLS_LIST_NEXT(&g->entity, e, _global);
751 *entity = NULL;
752 return MPLS_FAILURE;
755 ldp_peer *ldp_global_find_peer_addr(ldp_global * g, mpls_inet_addr * addr)
757 ldp_peer *p;
759 MPLS_ASSERT(g && addr);
761 /* JLEU: we will need to add a tree to optimize this search,
762 known peers will be in tree, unknown will take a "slow path" to
763 verify them, then be added to tree */
765 p = MPLS_LIST_HEAD(&g->peer);
766 while (p) {
767 LDP_PRINT(g->user_data,
768 "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
769 p->dest.addr.u.ipv4, addr->u.ipv4);
770 if (!mpls_inet_addr_compare(&p->dest.addr, addr)) {
771 return p;
773 p = MPLS_LIST_NEXT(&g->peer, p, _global);
775 return NULL;
778 mpls_return_enum ldp_global_find_adj_index(ldp_global * g, uint32_t index,
779 ldp_adj ** adj)
781 ldp_adj *a = NULL;
783 if (g && index > 0) {
784 /* because we sort our inserts by index, this lets us know
785 if we've "walked" past the end of the list */
787 a = MPLS_LIST_TAIL(&g->adj);
788 if (a == NULL || a->index < index) {
789 return MPLS_END_OF_LIST;
790 *adj = NULL;
793 a = MPLS_LIST_HEAD(&g->adj);
794 while (a != NULL) {
795 if (a->index == index) {
796 *adj = a;
797 return MPLS_SUCCESS;
799 a = MPLS_LIST_NEXT(&g->adj, a, _global);
802 *adj = NULL;
803 return MPLS_FAILURE;
806 mpls_return_enum ldp_global_find_peer_index(ldp_global * g, uint32_t index,
807 ldp_peer ** peer)
809 ldp_peer *p = NULL;
811 if (g && index > 0) {
812 /* because we sort our inserts by index, this lets us know
813 if we've "walked" past the end of the list */
815 p = MPLS_LIST_TAIL(&g->peer);
816 if (p == NULL || p->index < index) {
817 *peer = NULL;
818 return MPLS_END_OF_LIST;
821 p = MPLS_LIST_HEAD(&g->peer);
822 while (p != NULL) {
823 if (p->index == index) {
824 *peer = p;
825 return MPLS_SUCCESS;
827 p = MPLS_LIST_NEXT(&g->peer, p, _global);
830 *peer = NULL;
831 return MPLS_FAILURE;
834 mpls_return_enum ldp_global_find_fec_index(ldp_global * g, uint32_t index,
835 ldp_fec ** fec)
837 ldp_fec *f = NULL;
839 if (g && index > 0) {
840 /* because we sort our inserts by index, this lets us know
841 if we've "walked" past the end of the list */
843 f = MPLS_LIST_TAIL(&g->fec);
844 if (f == NULL || f->index < index) {
845 *fec = NULL;
846 return MPLS_END_OF_LIST;
849 f = MPLS_LIST_HEAD(&g->fec);
850 while (f != NULL) {
851 if (f->index == index) {
852 *fec = f;
853 return MPLS_SUCCESS;
855 f = MPLS_LIST_NEXT(&g->fec, f, _global);
858 *fec = NULL;
859 return MPLS_FAILURE;
862 mpls_return_enum ldp_global_find_fec(ldp_global * g, mpls_fec * m,
863 ldp_fec ** fec)
865 ldp_fec *f = NULL;
867 MPLS_ASSERT(g && m);
869 f = MPLS_LIST_HEAD(&g->fec);
870 do {
871 if (!mpls_fec_compare(m, &f->info)) {
872 *fec = f;
873 return MPLS_SUCCESS;
875 } while((f = MPLS_LIST_NEXT(&g->fec, f, _global)));
876 *fec = NULL;
877 return MPLS_FAILURE;
880 mpls_return_enum ldp_global_find_if_index(ldp_global * g, uint32_t index,
881 ldp_if ** iff)
883 ldp_if *i = NULL;
885 if (g && index > 0) {
887 /* because we sort our inserts by index, this lets us know
888 if we've "walked" past the end of the list */
890 i = MPLS_LIST_TAIL(&g->iff);
891 if (i == NULL || i->index < index) {
892 *iff = NULL;
893 return MPLS_END_OF_LIST;
896 i = MPLS_LIST_HEAD(&g->iff);
897 while (i != NULL) {
898 if (i->index == index) {
899 *iff = i;
900 return MPLS_SUCCESS;
902 i = MPLS_LIST_NEXT(&g->iff, i, _global);
905 *iff = NULL;
906 return MPLS_FAILURE;
909 ldp_if *ldp_global_find_if_handle(ldp_global * g, mpls_if_handle handle)
911 ldp_if *i = MPLS_LIST_HEAD(&g->iff);
913 if (g) {
914 while (i != NULL) {
915 if (!mpls_if_handle_compare(i->handle, handle))
916 return i;
918 i = MPLS_LIST_NEXT(&g->iff, i, _global);
921 return NULL;
924 ldp_adj *ldp_global_find_adj_ldpid(ldp_global * g, mpls_inet_addr * lsraddr,
925 int labelspace)
928 ldp_adj *a = MPLS_LIST_HEAD(&g->adj);
930 while (a != NULL) {
931 if ((!mpls_inet_addr_compare(lsraddr, &a->remote_lsr_address)) &&
932 labelspace == a->remote_label_space)
933 return a;
935 a = MPLS_LIST_NEXT(&g->adj, a, _global);
937 return NULL;
940 mpls_return_enum ldp_global_find_tunnel_index(ldp_global * g, uint32_t index,
941 ldp_tunnel ** tunnel)
943 ldp_tunnel *t = NULL;
945 if (g && index > 0) {
946 /* because we sort our inserts by index, this lets us know
947 if we've "walked" past the end of the list */
949 t = MPLS_LIST_TAIL(&g->tunnel);
950 if (t == NULL || t->index < index) {
951 *tunnel = NULL;
952 return MPLS_END_OF_LIST;
955 t = MPLS_LIST_HEAD(&g->tunnel);
956 while (t != NULL) {
957 if (t->index == index) {
958 *tunnel = t;
959 return MPLS_SUCCESS;
961 t = MPLS_LIST_NEXT(&g->tunnel, t, _global);
964 *tunnel = NULL;
965 return MPLS_FAILURE;
968 mpls_return_enum ldp_global_find_resource_index(ldp_global * g, uint32_t index,
969 ldp_resource ** resource)
971 ldp_resource *r = NULL;
973 if (g && index > 0) {
974 /* because we sort our inserts by index, this lets us know
975 if we've "walked" past the end of the list */
977 r = MPLS_LIST_TAIL(&g->resource);
978 if (r == NULL || r->index < index) {
979 *resource = NULL;
980 return MPLS_END_OF_LIST;
983 r = MPLS_LIST_HEAD(&g->resource);
984 while (r != NULL) {
985 if (r->index == index) {
986 *resource = r;
987 return MPLS_SUCCESS;
989 r = MPLS_LIST_NEXT(&g->resource, r, _global);
992 *resource = NULL;
993 return MPLS_FAILURE;
996 mpls_return_enum ldp_global_find_hop_list_index(ldp_global * g, uint32_t index,
997 ldp_hop_list ** hop_list)
999 ldp_hop_list *h = NULL;
1001 if (g && index > 0) {
1002 /* because we sort our inserts by index, this lets us know
1003 if we've "walked" past the end of the list */
1005 h = MPLS_LIST_TAIL(&g->hop_list);
1006 if (h == NULL || h->index < index) {
1007 *hop_list = NULL;
1008 return MPLS_END_OF_LIST;
1011 h = MPLS_LIST_HEAD(&g->hop_list);
1012 while (h != NULL) {
1013 if (h->index == index) {
1014 *hop_list = h;
1015 return MPLS_SUCCESS;
1017 h = MPLS_LIST_NEXT(&g->hop_list, h, _global);
1020 *hop_list = NULL;
1021 return MPLS_FAILURE;
1024 void _ldp_global_add_tunnel(ldp_global * g, ldp_tunnel * t)
1026 ldp_tunnel *tp = NULL;
1028 MPLS_ASSERT(g && t);
1029 MPLS_REFCNT_HOLD(t);
1030 tp = MPLS_LIST_HEAD(&g->tunnel);
1031 while (tp != NULL) {
1032 if (tp->index > t->index) {
1033 MPLS_LIST_INSERT_BEFORE(&g->tunnel, tp, t, _global);
1034 return;
1036 tp = MPLS_LIST_NEXT(&g->tunnel, tp, _global);
1038 MPLS_LIST_ADD_TAIL(&g->tunnel, t, _global, ldp_tunnel);
1041 void _ldp_global_del_tunnel(ldp_global * g, ldp_tunnel * t)
1043 MPLS_ASSERT(g && t);
1044 MPLS_LIST_REMOVE(&g->tunnel, t, _global);
1045 MPLS_REFCNT_RELEASE(t, ldp_tunnel_delete);
1048 void _ldp_global_add_resource(ldp_global * g, ldp_resource * r)
1050 ldp_resource *rp = NULL;
1052 MPLS_ASSERT(g && r);
1053 MPLS_REFCNT_HOLD(r);
1054 rp = MPLS_LIST_HEAD(&g->resource);
1055 while (rp != NULL) {
1056 if (rp->index > r->index) {
1057 MPLS_LIST_INSERT_BEFORE(&g->resource, rp, r, _global);
1058 return;
1060 rp = MPLS_LIST_NEXT(&g->resource, rp, _global);
1062 MPLS_LIST_ADD_TAIL(&g->resource, r, _global, ldp_resource);
1065 void _ldp_global_del_resource(ldp_global * g, ldp_resource * r)
1067 MPLS_ASSERT(g && r);
1068 MPLS_LIST_REMOVE(&g->resource, r, _global);
1069 MPLS_REFCNT_RELEASE(r, ldp_resource_delete);
1072 void _ldp_global_add_hop_list(ldp_global * g, ldp_hop_list * h)
1074 ldp_hop_list *hp = NULL;
1076 MPLS_ASSERT(g && h);
1077 MPLS_REFCNT_HOLD(h);
1078 hp = MPLS_LIST_HEAD(&g->hop_list);
1079 while (hp != NULL) {
1080 if (hp->index > h->index) {
1081 MPLS_LIST_INSERT_BEFORE(&g->hop_list, hp, h, _global);
1082 return;
1084 hp = MPLS_LIST_NEXT(&g->hop_list, hp, _global);
1086 MPLS_LIST_ADD_TAIL(&g->hop_list, h, _global, ldp_hop_list);
1089 void _ldp_global_del_hop_list(ldp_global * g, ldp_hop_list * h)
1091 MPLS_ASSERT(g && h);
1092 MPLS_LIST_REMOVE(&g->hop_list, h, _global);
1093 MPLS_REFCNT_RELEASE(h, ldp_hop_list_delete);
1096 void _ldp_global_add_fec(ldp_global * g, ldp_fec * f)
1098 ldp_fec *fp = NULL;
1100 MPLS_ASSERT(g && f);
1101 MPLS_REFCNT_HOLD(f);
1102 fp = MPLS_LIST_HEAD(&g->fec);
1103 while (fp != NULL) {
1104 if (fp->index > f->index) {
1105 MPLS_LIST_INSERT_BEFORE(&g->fec, fp, f, _global);
1106 return;
1108 fp = MPLS_LIST_NEXT(&g->fec, fp, _global);
1110 MPLS_LIST_ADD_TAIL(&g->fec, f, _global, ldp_fec);
1113 void _ldp_global_del_fec(ldp_global * g, ldp_fec * f)
1115 MPLS_ASSERT(g && f);
1116 MPLS_LIST_REMOVE(&g->fec, f, _global);
1117 MPLS_REFCNT_RELEASE(f, ldp_fec_delete);
1120 void _ldp_global_add_nexthop(ldp_global * g, ldp_nexthop * nh)
1122 ldp_nexthop *nhp = NULL;
1124 MPLS_ASSERT(g && nh);
1125 MPLS_REFCNT_HOLD(nh);
1126 nhp = MPLS_LIST_HEAD(&g->nexthop);
1127 while (nhp != NULL) {
1128 if (nhp->index > nh->index) {
1129 MPLS_LIST_INSERT_BEFORE(&g->nexthop, nhp, nh, _global);
1130 return;
1132 nhp = MPLS_LIST_NEXT(&g->nexthop, nhp, _global);
1134 MPLS_LIST_ADD_TAIL(&g->nexthop, nh, _global, ldp_nexthop);
1137 void _ldp_global_del_nexthop(ldp_global * g, ldp_nexthop * nh)
1139 MPLS_ASSERT(g && nh);
1140 MPLS_LIST_REMOVE(&g->nexthop, nh, _global);
1141 MPLS_REFCNT_RELEASE(nh, ldp_nexthop_delete);