I changed all of the porting layer verify and compare
[mpls-ldp-portable.git] / ldp / ldp_global.c
blob17d35981a7658fe0573b199e63493fa0083339f9
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_outlabel.h"
18 #include "ldp_inlabel.h"
19 #include "ldp_hello.h"
20 #include "ldp_peer.h"
21 #include "ldp_attr.h"
22 #include "ldp_addr.h"
23 #include "ldp_adj.h"
24 #include "ldp_fec.h"
25 #include "ldp_if.h"
26 #include "ldp_label_mapping.h"
27 #include "ldp_tunnel.h"
28 #include "ldp_resource.h"
29 #include "ldp_hop_list.h"
31 #include "mpls_socket_impl.h"
32 #include "mpls_timer_impl.h"
33 #include "mpls_ifmgr_impl.h"
34 #include "mpls_tree_impl.h"
35 #include "mpls_lock_impl.h"
36 #include "mpls_fib_impl.h"
37 #include "mpls_policy_impl.h"
38 #include "mpls_mm_impl.h"
39 #include "mpls_trace_impl.h"
41 #if MPLS_USE_LSR
42 #include "lsr_cfg.h"
43 #else
44 #include "mpls_mpls_impl.h"
45 #endif
47 void _ldp_global_fib_callback(mpls_cfg_handle handle, mpls_update_enum type,
48 mpls_fec * dest)
50 ldp_session *session = NULL;
51 ldp_global *cfg = (ldp_global*)handle;
53 LDP_ENTER(cfg->user_data, "_ldp_global_fib_callback");
55 mpls_lock_get(cfg->global_lock);
57 if (dest->nh.type & MPLS_NH_IP) {
58 session = ldp_get_session_by_next_hop(cfg, &dest->nh, NULL);
61 switch (type) {
62 case MPLS_UPDATE_ADD:
63 Recognize_New_Fec(cfg, dest);
64 break;
65 case MPLS_UPDATE_DEL:
66 case MPLS_UPDATE_MODIFY:
67 if (session)
68 Detect_Change_Fec_Next_Hop(cfg, dest, session);
69 break;
70 default:
71 MPLS_ASSERT(0);
72 break;
75 mpls_lock_release(cfg->global_lock);
77 LDP_EXIT(cfg->user_data, "_ldp_global_fib_callback");
80 void _ldp_global_ifmgr_callback(mpls_cfg_handle handle, const mpls_update_enum type, mpls_inet_addr *addr)
82 ldp_session *s = NULL;
83 ldp_global *cfg = (ldp_global*)handle;
85 LDP_ENTER(cfg->user_data, "_ldp_global_ifmgr_callback");
87 mpls_lock_get(cfg->global_lock);
89 if (mpls_policy_address_export_check(cfg->user_data, addr) == MPLS_BOOL_TRUE) {
90 s = MPLS_LIST_HEAD(&cfg->session);
91 while (s != NULL) {
92 switch (type) {
93 case MPLS_UPDATE_ADD:
94 LDP_TRACE_LOG(cfg->user_data, MPLS_TRACE_STATE_ALL,
95 LDP_TRACE_FLAG_EVENT, "ADD\n");
96 ldp_addr_send(cfg, s, addr);
97 break;
98 case MPLS_UPDATE_DEL:
99 LDP_TRACE_LOG(cfg->user_data, MPLS_TRACE_STATE_ALL,
100 LDP_TRACE_FLAG_EVENT, "DEL\n");
101 ldp_waddr_send(cfg, s, addr);
102 break;
103 default:
104 MPLS_ASSERT(0);
106 s = MPLS_LIST_NEXT(&cfg->session, s, _global);
110 mpls_lock_release(cfg->global_lock);
112 LDP_EXIT(cfg->user_data, "_ldp_global_ifmgr_callback");
115 ldp_global *ldp_global_create(mpls_instance_handle data)
117 ldp_global *g = (ldp_global *) mpls_malloc(sizeof(ldp_global));
119 if (g) {
120 memset(g, 0, sizeof(ldp_global));
122 LDP_ENTER(g->user_data, "ldp_global_create");
124 g->global_lock = mpls_lock_create("_ldp_global_lock_");
125 mpls_lock_get(g->global_lock);
127 MPLS_LIST_INIT(&g->hop_list, ldp_hop_list);
128 MPLS_LIST_INIT(&g->outlabel, ldp_outlabel);
129 MPLS_LIST_INIT(&g->resource, ldp_resource);
130 MPLS_LIST_INIT(&g->inlabel, ldp_inlabel);
131 MPLS_LIST_INIT(&g->session, ldp_session);
132 MPLS_LIST_INIT(&g->tunnel, ldp_tunnel);
133 MPLS_LIST_INIT(&g->entity, ldp_entity);
134 MPLS_LIST_INIT(&g->attr, ldp_attr);
135 MPLS_LIST_INIT(&g->peer, ldp_peer);
136 MPLS_LIST_INIT(&g->adj, ldp_adj);
137 MPLS_LIST_INIT(&g->iff, ldp_if);
139 g->message_identifier = 1;
140 g->configuration_sequence_number = 1;
141 g->lsp_control_mode = LDP_GLOBAL_DEF_CONTROL_MODE;
142 g->label_retention_mode = LDP_GLOBAL_DEF_RETENTION_MODE;
143 g->lsp_repair_mode = LDP_GLOBAL_DEF_REPAIR_MODE;
144 g->propagate_release = LDP_GLOBAL_DEF_PROPOGATE_RELEASE;
145 g->label_merge = LDP_GLOBAL_DEF_LABEL_MERGE;
146 g->loop_detection_mode = LDP_GLOBAL_DEF_LOOP_DETECTION_MODE;
147 g->ttl_less_domain = LDP_GLOBAL_DEF_TTLLESS_DOMAIN;
148 g->local_tcp_port = LDP_GLOBAL_DEF_LOCAL_TCP_PORT;
149 g->local_udp_port = LDP_GLOBAL_DEF_LOCAL_UDP_PORT;
150 g->send_address_messages = LDP_GLOBAL_DEF_SEND_ADDR_MSG;
151 g->backoff_step = LDP_GLOBAL_DEF_BACKOFF_STEP;
152 g->send_lsrid_mapping = LDP_GLOBAL_DEF_SEND_LSRID_MAPPING;
153 g->no_route_to_peer_time = LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME;
155 g->keepalive_timer = LDP_ENTITY_DEF_KEEPALIVE_TIMER;
156 g->keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL;
157 g->hellotime_timer = LDP_ENTITY_DEF_HELLOTIME_TIMER;
158 g->hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL;
160 g->admin_state = MPLS_ADMIN_DISABLE;
161 g->user_data = data;
163 mpls_lock_release(g->global_lock);
165 LDP_EXIT(g->user_data, "ldp_global_create");
168 return g;
171 mpls_return_enum ldp_global_startup(ldp_global * g)
173 ldp_entity *e = NULL;
174 mpls_dest dest;
176 MPLS_ASSERT(g != NULL);
178 LDP_ENTER(g->user_data, "ldp_global_startup");
180 if (g->lsr_identifier.type == MPLS_FAMILY_NONE) {
181 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
182 "ldp_global_startup: invalid LSRID\n");
183 goto ldp_global_startup_cleanup;
186 g->timer_handle = mpls_timer_open(g->user_data);
187 if (mpls_timer_mgr_handle_verify(g->timer_handle) == MPLS_BOOL_FALSE) {
188 goto ldp_global_startup_cleanup;
191 g->socket_handle = mpls_socket_mgr_open(g->user_data);
192 if (mpls_socket_mgr_handle_verify(g->socket_handle) == MPLS_BOOL_FALSE) {
193 goto ldp_global_startup_cleanup;
196 g->ifmgr_handle = mpls_ifmgr_open(g->user_data, g, _ldp_global_ifmgr_callback);
197 if (mpls_ifmgr_handle_verify(g->ifmgr_handle) == MPLS_BOOL_FALSE) {
198 goto ldp_global_startup_cleanup;
201 g->fib_handle = mpls_fib_open(g->user_data, g, _ldp_global_fib_callback);
202 if (mpls_fib_handle_verify(g->fib_handle) == MPLS_BOOL_FALSE) {
203 goto ldp_global_startup_cleanup;
206 #if MPLS_USE_LSR
207 if (!g->lsr_handle) {
208 goto ldp_global_startup_cleanup;
210 #else
211 g->mpls_handle = mpls_mpls_open(g->user_data);
212 if (mpls_mpls_handle_verify(g->mpls_handle) == MPLS_BOOL_FALSE) {
213 goto ldp_global_startup_cleanup;
215 #endif
217 g->addr_tree = mpls_tree_create(32);
218 g->fec_tree = mpls_tree_create(32);
220 g->hello_socket = mpls_socket_create_udp(g->socket_handle);
221 if (mpls_socket_handle_verify(g->socket_handle, g->hello_socket) == MPLS_BOOL_FALSE) {
222 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
223 "ldp_global_startup: error creating UDP socket\n");
224 goto ldp_global_startup_cleanup;
227 dest.addr.type = MPLS_FAMILY_IPV4;
228 dest.port = g->local_udp_port;
229 dest.addr.u.ipv4 = INADDR_ANY;
230 // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
232 if (mpls_socket_bind(g->socket_handle, g->hello_socket, &dest) == MPLS_FAILURE) {
233 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
234 "ldp_global_startup: error binding UDP socket\n");
235 goto ldp_global_startup_cleanup;
238 if (mpls_socket_options(g->socket_handle, g->hello_socket,
239 MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) {
240 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
241 "ldp_global_startup: error setting UDP socket options\n");
242 goto ldp_global_startup_cleanup;
244 if (mpls_socket_multicast_options(g->socket_handle, g->hello_socket, 1, 0) ==
245 MPLS_FAILURE) {
246 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
247 "ldp_global_startup: error setting UDP socket multicast options\n");
248 goto ldp_global_startup_cleanup;
250 mpls_socket_readlist_add(g->socket_handle, g->hello_socket, 0, MPLS_SOCKET_UDP_DATA);
252 g->listen_socket = mpls_socket_create_tcp(g->socket_handle);
253 if (mpls_socket_handle_verify(g->socket_handle, g->listen_socket) == MPLS_BOOL_FALSE) {
254 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
255 "ldp_global_startup: error creating TCP socket\n");
256 goto ldp_global_startup_cleanup;
258 if (mpls_socket_options(g->socket_handle, g->listen_socket,
259 MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) {
260 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
261 "ldp_global_startup: error setting TCP socket options\n");
262 goto ldp_global_startup_cleanup;
265 dest.addr.type = MPLS_FAMILY_IPV4;
266 dest.port = g->local_tcp_port;
267 dest.addr.u.ipv4 = INADDR_ANY;
269 if (mpls_socket_bind(g->socket_handle, g->listen_socket, &dest) == MPLS_FAILURE) {
270 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
271 "ldp_global_startup: error binding TCP socket\n");
272 goto ldp_global_startup_cleanup;
275 if (mpls_socket_tcp_listen(g->socket_handle, g->listen_socket, 15) ==
276 MPLS_FAILURE) {
277 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
278 "ldp_global_startup: error setting listen buffer for TCP socket\n");
279 goto ldp_global_startup_cleanup;
282 mpls_socket_readlist_add(g->socket_handle, g->listen_socket, 0,
283 MPLS_SOCKET_TCP_LISTEN);
285 e = MPLS_LIST_HEAD(&g->entity);
286 while (e != NULL) {
287 ldp_entity_startup(g, e);
288 e = MPLS_LIST_NEXT(&g->entity, e, _global);
291 g->admin_state = MPLS_ADMIN_ENABLE;
293 LDP_EXIT(g->user_data, "ldp_global_startup");
294 return MPLS_SUCCESS;
296 ldp_global_startup_cleanup:
297 ldp_global_shutdown(g);
298 mpls_socket_close(g->socket_handle, g->hello_socket);
299 mpls_socket_close(g->socket_handle, g->listen_socket);
300 g->hello_socket = 0;
301 g->listen_socket = 0;
303 LDP_EXIT(g->user_data, "ldp_global_startup-error");
305 return MPLS_FAILURE;
308 mpls_return_enum ldp_global_shutdown(ldp_global * g)
310 ldp_entity *e = NULL;
312 MPLS_ASSERT(g);
314 LDP_ENTER(g->user_data, "ldp_global_shutdown");
316 e = MPLS_LIST_HEAD(&g->entity);
317 while (e != NULL) {
318 ldp_entity_shutdown(g, e, 1);
319 e = MPLS_LIST_NEXT(&g->entity, e, _global);
322 g->admin_state = MPLS_ADMIN_DISABLE;
324 mpls_socket_readlist_del(g->socket_handle, g->hello_socket);
325 mpls_socket_close(g->socket_handle, g->hello_socket);
327 mpls_socket_readlist_del(g->socket_handle, g->listen_socket);
328 mpls_socket_close(g->socket_handle, g->listen_socket);
330 mpls_tree_delete(g->addr_tree);
331 mpls_tree_delete(g->fec_tree);
333 mpls_lock_release(g->global_lock);
334 mpls_timer_close(g->timer_handle);
335 mpls_lock_get(g->global_lock);
337 mpls_socket_mgr_close(g->socket_handle);
338 mpls_ifmgr_close(g->ifmgr_handle);
339 mpls_fib_close(g->fib_handle);
341 #if MPLS_USE_LSR
342 #else
343 mpls_mpls_close(g->mpls_handle);
344 #endif
346 LDP_EXIT(g->user_data, "ldp_global_shutdown");
348 return MPLS_SUCCESS;
351 mpls_return_enum ldp_global_delete(ldp_global * g)
353 if (g) {
354 mpls_lock_delete(g->global_lock);
355 LDP_PRINT(g->user_data, "global delete\n");
356 mpls_free(g);
358 return MPLS_SUCCESS;
361 void _ldp_global_add_attr(ldp_global * g, ldp_attr * a)
363 ldp_attr *ap = NULL;
365 MPLS_ASSERT(g && a);
366 MPLS_REFCNT_HOLD(a);
367 ap = MPLS_LIST_HEAD(&g->attr);
368 while (ap != NULL) {
369 if (ap->index > a->index) {
370 MPLS_LIST_INSERT_BEFORE(&g->attr, ap, a, _global);
371 return;
373 ap = MPLS_LIST_NEXT(&g->attr, ap, _global);
375 MPLS_LIST_ADD_TAIL(&g->attr, a, _global, ldp_attr);
378 void _ldp_global_del_attr(ldp_global * g, ldp_attr * a)
380 MPLS_ASSERT(g && a);
381 MPLS_LIST_REMOVE(&g->attr, a, _global);
382 MPLS_REFCNT_RELEASE(a, ldp_attr_delete);
385 void _ldp_global_add_peer(ldp_global * g, ldp_peer * p)
387 ldp_peer *pp = NULL;
389 MPLS_ASSERT(g && p);
390 MPLS_REFCNT_HOLD(p);
391 pp = MPLS_LIST_HEAD(&g->peer);
392 while (pp != NULL) {
393 if (pp->index > p->index) {
394 MPLS_LIST_INSERT_BEFORE(&g->peer, pp, p, _global);
395 return;
397 pp = MPLS_LIST_NEXT(&g->peer, pp, _global);
399 MPLS_LIST_ADD_TAIL(&g->peer, p, _global, ldp_peer);
402 void _ldp_global_del_peer(ldp_global * g, ldp_peer * p)
404 MPLS_ASSERT(g && p);
405 MPLS_LIST_REMOVE(&g->peer, p, _global);
406 MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
409 void _ldp_global_add_if(ldp_global * g, ldp_if * i)
411 ldp_if *ip = NULL;
413 MPLS_ASSERT(g && i);
414 MPLS_REFCNT_HOLD(i);
415 ip = MPLS_LIST_HEAD(&g->iff);
416 while (ip != NULL) {
417 if (ip->index > i->index) {
418 MPLS_LIST_INSERT_BEFORE(&g->iff, ip, i, _global);
419 return;
421 ip = MPLS_LIST_NEXT(&g->iff, ip, _global);
423 MPLS_LIST_ADD_TAIL(&g->iff, i, _global, ldp_if);
426 void _ldp_global_del_if(ldp_global * g, ldp_if * i)
428 MPLS_ASSERT(g && i);
429 MPLS_LIST_REMOVE(&g->iff, i, _global);
430 MPLS_REFCNT_RELEASE(i, ldp_if_delete);
433 void _ldp_global_add_adj(ldp_global * g, ldp_adj * a)
435 ldp_adj *ap = NULL;
437 MPLS_ASSERT(g && a);
438 MPLS_REFCNT_HOLD(a);
439 ap = MPLS_LIST_HEAD(&g->adj);
440 while (ap != NULL) {
441 if (ap->index > a->index) {
442 MPLS_LIST_INSERT_BEFORE(&g->adj, ap, a, _global);
443 return;
445 ap = MPLS_LIST_NEXT(&g->adj, ap, _global);
447 MPLS_LIST_ADD_TAIL(&g->adj, a, _global, ldp_adj);
450 void _ldp_global_del_adj(ldp_global * g, ldp_adj * a)
452 MPLS_ASSERT(g && a);
453 MPLS_LIST_REMOVE(&g->adj, a, _global);
454 MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
457 void _ldp_global_add_entity(ldp_global * g, ldp_entity * e)
459 ldp_entity *ep = NULL;
461 MPLS_ASSERT(g && e);
462 MPLS_REFCNT_HOLD(e);
463 ep = MPLS_LIST_HEAD(&g->entity);
464 while (ep != NULL) {
465 if (ep->index > e->index) {
466 MPLS_LIST_INSERT_BEFORE(&g->entity, ep, e, _global);
467 return;
469 ep = MPLS_LIST_NEXT(&g->entity, ep, _global);
471 MPLS_LIST_ADD_TAIL(&g->entity, e, _global, ldp_entity);
474 void _ldp_global_del_entity(ldp_global * g, ldp_entity * e)
476 MPLS_ASSERT(g && e);
477 MPLS_LIST_REMOVE(&g->entity, e, _global);
478 MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
481 void _ldp_global_add_session(ldp_global * g, ldp_session * s)
483 ldp_session *sp = NULL;
485 MPLS_ASSERT(g && s);
486 MPLS_REFCNT_HOLD(s);
487 s->on_global = MPLS_BOOL_TRUE;
488 sp = MPLS_LIST_HEAD(&g->session);
489 while (sp != NULL) {
490 if (sp->index > s->index) {
491 MPLS_LIST_INSERT_BEFORE(&g->session, sp, s, _global);
492 return;
494 sp = MPLS_LIST_NEXT(&g->session, sp, _global);
496 MPLS_LIST_ADD_TAIL(&g->session, s, _global, ldp_session);
499 void _ldp_global_del_session(ldp_global * g, ldp_session * s)
501 MPLS_ASSERT(g && s);
502 MPLS_ASSERT(s->on_global == MPLS_BOOL_TRUE);
503 MPLS_LIST_REMOVE(&g->session, s, _global);
504 s->on_global = MPLS_BOOL_FALSE;
505 MPLS_REFCNT_RELEASE(s, ldp_session_delete);
508 mpls_return_enum _ldp_global_add_inlabel(ldp_global * g, ldp_inlabel * i)
510 ldp_inlabel *ip = NULL;
511 mpls_return_enum result;
513 MPLS_ASSERT(g && i);
515 #if MPLS_USE_LSR
517 lsr_insegment iseg;
518 memcpy(&iseg.info,&i->info,sizeof(mpls_insegment));
519 result = lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_ADD|
520 LSR_INSEGMENT_CFG_NPOP|LSR_INSEGMENT_CFG_FAMILY|
521 LSR_INSEGMENT_CFG_LABELSPACE|LSR_INSEGMENT_CFG_LABEL|
522 LSR_INSEGMENT_CFG_OWNER);
523 memcpy(&i->info, &iseg.info, sizeof(mpls_insegment));
524 i->info.handle = iseg.index;
526 #else
527 result = mpls_mpls_insegment_add(g->mpls_handle, &i->info);
528 #endif
529 if (result != MPLS_SUCCESS) {
530 return result;
533 MPLS_REFCNT_HOLD(i);
534 ip = MPLS_LIST_HEAD(&g->inlabel);
535 while (ip != NULL) {
536 if (ip->index > i->index) {
537 MPLS_LIST_INSERT_BEFORE(&g->inlabel, ip, i, _global);
538 return MPLS_SUCCESS;
540 ip = MPLS_LIST_NEXT(&g->inlabel, ip, _global);
542 MPLS_LIST_ADD_TAIL(&g->inlabel, i, _global, ldp_inlabel);
543 return MPLS_SUCCESS;
546 mpls_return_enum _ldp_global_del_inlabel(ldp_global * g, ldp_inlabel * i)
548 MPLS_ASSERT(g && i);
549 MPLS_ASSERT(i->reuse_count == 0);
550 #if MPLS_USE_LSR
552 lsr_insegment iseg;
553 iseg.index = i->info.handle;
554 lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_DEL);
556 #else
557 mpls_mpls_insegment_del(g->mpls_handle, &i->info);
558 #endif
559 MPLS_LIST_REMOVE(&g->inlabel, i, _global);
560 MPLS_REFCNT_RELEASE(i, ldp_inlabel_delete);
561 return MPLS_SUCCESS;
564 mpls_return_enum _ldp_global_add_outlabel(ldp_global * g, ldp_outlabel * o)
566 ldp_outlabel *op = NULL;
567 mpls_return_enum result;
569 MPLS_ASSERT(g && o);
570 #if MPLS_USE_LSR
572 lsr_outsegment oseg;
573 memcpy(&oseg.info, &o->info, sizeof(mpls_outsegment));
574 result = lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_ADD|
575 LSR_OUTSEGMENT_CFG_PUSH_LABEL|LSR_OUTSEGMENT_CFG_OWNER|
576 LSR_OUTSEGMENT_CFG_INTERFACE|LSR_OUTSEGMENT_CFG_LABEL|
577 LSR_OUTSEGMENT_CFG_NEXTHOP);
578 o->info.handle = oseg.index;
580 #else
581 result = mpls_mpls_outsegment_add(g->mpls_handle, &o->info);
582 #endif
584 if (result != MPLS_SUCCESS) {
585 return result;
588 MPLS_REFCNT_HOLD(o);
589 o->switching = MPLS_BOOL_TRUE;
590 op = MPLS_LIST_HEAD(&g->outlabel);
591 while (op != NULL) {
592 if (op->index > o->index) {
593 MPLS_LIST_INSERT_BEFORE(&g->outlabel, op, o, _global);
594 return MPLS_SUCCESS;
596 op = MPLS_LIST_NEXT(&g->outlabel, op, _global);
598 MPLS_LIST_ADD_TAIL(&g->outlabel, o, _global, ldp_outlabel);
599 return MPLS_SUCCESS;
602 mpls_return_enum _ldp_global_del_outlabel(ldp_global * g, ldp_outlabel * o)
604 MPLS_ASSERT(g && o);
605 #if MPLS_USE_LSR
607 lsr_outsegment oseg;
608 oseg.index = o->info.handle;
609 lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_DEL);
611 #else
612 mpls_mpls_outsegment_del(g->mpls_handle, &o->info);
613 #endif
615 o->switching = MPLS_BOOL_FALSE;
616 MPLS_ASSERT(o->merge_count == 0);
617 MPLS_LIST_REMOVE(&g->outlabel, o, _global);
618 MPLS_REFCNT_RELEASE(o, ldp_outlabel_delete);
619 return MPLS_SUCCESS;
622 mpls_return_enum ldp_global_find_attr_index(ldp_global * g, uint32_t index,
623 ldp_attr ** attr)
625 ldp_attr *a = NULL;
627 if (g && index > 0) {
629 /* because we sort our inserts by index, this lets us know
630 if we've "walked" past the end of the list */
632 a = MPLS_LIST_TAIL(&g->attr);
633 if (a == NULL || a->index < index) {
634 return MPLS_END_OF_LIST;
635 *attr = NULL;
638 a = MPLS_LIST_HEAD(&g->attr);
639 while (a != NULL) {
640 if (a->index == index) {
641 *attr = a;
642 return MPLS_SUCCESS;
644 a = MPLS_LIST_NEXT(&g->attr, a, _global);
647 *attr = NULL;
648 return MPLS_FAILURE;
651 mpls_return_enum ldp_global_find_session_index(ldp_global * g, uint32_t index,
652 ldp_session ** session)
654 ldp_session *s = NULL;
656 if (g && index > 0) {
658 /* because we sort our inserts by index, this lets us know
659 if we've "walked" past the end of the list */
661 s = MPLS_LIST_TAIL(&g->session);
662 if (s == NULL || s->index < index) {
663 *session = NULL;
664 return MPLS_END_OF_LIST;
667 s = MPLS_LIST_HEAD(&g->session);
668 while (s != NULL) {
669 if (s->index == index) {
670 *session = s;
671 return MPLS_SUCCESS;
673 s = MPLS_LIST_NEXT(&g->session, s, _global);
676 *session = NULL;
677 return MPLS_FAILURE;
680 mpls_return_enum ldp_global_find_inlabel_index(ldp_global * g, uint32_t index,
681 ldp_inlabel ** inlabel)
683 ldp_inlabel *i = NULL;
685 if (g && index > 0) {
687 /* because we sort our inserts by index, this lets us know
688 if we've "walked" past the end of the list */
690 i = MPLS_LIST_TAIL(&g->inlabel);
691 if (i == NULL || i->index < index) {
692 *inlabel = NULL;
693 return MPLS_END_OF_LIST;
696 i = MPLS_LIST_HEAD(&g->inlabel);
697 while (i != NULL) {
698 if (i->index == index) {
699 *inlabel = i;
700 return MPLS_SUCCESS;
702 i = MPLS_LIST_NEXT(&g->inlabel, i, _global);
705 *inlabel = NULL;
706 return MPLS_FAILURE;
709 mpls_return_enum ldp_global_find_outlabel_index(ldp_global * g, uint32_t index,
710 ldp_outlabel ** outlabel)
712 ldp_outlabel *o = NULL;
714 if (g && index > 0) {
716 /* because we sort our inserts by index, this lets us know
717 if we've "walked" past the end of the list */
719 o = MPLS_LIST_TAIL(&g->outlabel);
720 if (o == NULL || o->index < index) {
721 *outlabel = NULL;
722 return MPLS_END_OF_LIST;
725 o = MPLS_LIST_HEAD(&g->outlabel);
726 while (o != NULL) {
727 if (o->index == index) {
728 *outlabel = o;
729 return MPLS_SUCCESS;
731 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
734 *outlabel = NULL;
735 return MPLS_FAILURE;
738 mpls_return_enum ldp_global_find_entity_index(ldp_global * g, uint32_t index,
739 ldp_entity ** entity)
741 ldp_entity *e = NULL;
743 if (g && index > 0) {
745 /* because we sort our inserts by index, this lets us know
746 if we've "walked" past the end of the list */
748 e = MPLS_LIST_TAIL(&g->entity);
749 if (e == NULL || e->index < index) {
750 *entity = NULL;
751 return MPLS_END_OF_LIST;
754 e = MPLS_LIST_HEAD(&g->entity);
755 while (e != NULL) {
756 if (e->index == index) {
757 *entity = e;
758 return MPLS_SUCCESS;
760 e = MPLS_LIST_NEXT(&g->entity, e, _global);
763 *entity = NULL;
764 return MPLS_FAILURE;
767 ldp_peer *ldp_global_find_peer_addr(ldp_global * g, mpls_inet_addr * addr)
769 ldp_peer *p;
771 MPLS_ASSERT(g && addr);
773 /* JLEU: we will need to add a tree to optimize this search,
774 known peers will be in tree, unknown will take a "slow path" to
775 verify them, then be added to tree */
777 p = MPLS_LIST_HEAD(&g->peer);
778 while (p) {
779 LDP_PRINT(g->user_data,
780 "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
781 p->dest.addr.u.ipv4, addr->u.ipv4);
782 if (!mpls_inet_addr_compare(&p->dest.addr, addr)) {
783 return p;
785 p = MPLS_LIST_NEXT(&g->peer, p, _global);
787 return NULL;
790 mpls_return_enum ldp_global_find_adj_index(ldp_global * g, uint32_t index,
791 ldp_adj ** adj)
793 ldp_adj *a = NULL;
795 if (g && index > 0) {
796 /* because we sort our inserts by index, this lets us know
797 if we've "walked" past the end of the list */
799 a = MPLS_LIST_TAIL(&g->adj);
800 if (a == NULL || a->index < index) {
801 return MPLS_END_OF_LIST;
802 *adj = NULL;
805 a = MPLS_LIST_HEAD(&g->adj);
806 while (a != NULL) {
807 if (a->index == index) {
808 *adj = a;
809 return MPLS_SUCCESS;
811 a = MPLS_LIST_NEXT(&g->adj, a, _global);
814 *adj = NULL;
815 return MPLS_FAILURE;
818 mpls_return_enum ldp_global_find_peer_index(ldp_global * g, uint32_t index,
819 ldp_peer ** peer)
821 ldp_peer *p = NULL;
823 if (g && index > 0) {
824 /* because we sort our inserts by index, this lets us know
825 if we've "walked" past the end of the list */
827 p = MPLS_LIST_TAIL(&g->peer);
828 if (p == NULL || p->index < index) {
829 *peer = NULL;
830 return MPLS_END_OF_LIST;
833 p = MPLS_LIST_HEAD(&g->peer);
834 while (p != NULL) {
835 if (p->index == index) {
836 *peer = p;
837 return MPLS_SUCCESS;
839 p = MPLS_LIST_NEXT(&g->peer, p, _global);
842 *peer = NULL;
843 return MPLS_FAILURE;
846 mpls_return_enum ldp_global_find_if_index(ldp_global * g, uint32_t index,
847 ldp_if ** iff)
849 ldp_if *i = NULL;
851 if (g && index > 0) {
853 /* because we sort our inserts by index, this lets us know
854 if we've "walked" past the end of the list */
856 i = MPLS_LIST_TAIL(&g->iff);
857 if (i == NULL || i->index < index) {
858 *iff = NULL;
859 return MPLS_END_OF_LIST;
862 i = MPLS_LIST_HEAD(&g->iff);
863 while (i != NULL) {
864 if (i->index == index) {
865 *iff = i;
866 return MPLS_SUCCESS;
868 i = MPLS_LIST_NEXT(&g->iff, i, _global);
871 *iff = NULL;
872 return MPLS_FAILURE;
875 ldp_if *ldp_global_find_if_handle(ldp_global * g, mpls_if_handle handle)
877 ldp_if *i = MPLS_LIST_HEAD(&g->iff);
879 if (g) {
880 while (i != NULL) {
881 if (!mpls_if_handle_compare(i->handle, handle))
882 return i;
884 i = MPLS_LIST_NEXT(&g->iff, i, _global);
887 return NULL;
890 ldp_adj *ldp_global_find_adj_ldpid(ldp_global * g, mpls_inet_addr * lsraddr,
891 int labelspace)
894 ldp_adj *a = MPLS_LIST_HEAD(&g->adj);
896 while (a != NULL) {
897 if ((!mpls_inet_addr_compare(lsraddr, &a->remote_lsr_address)) &&
898 labelspace == a->remote_label_space)
899 return a;
901 a = MPLS_LIST_NEXT(&g->adj, a, _global);
903 return NULL;
906 mpls_return_enum ldp_global_find_tunnel_index(ldp_global * g, uint32_t index,
907 ldp_tunnel ** tunnel)
909 ldp_tunnel *t = NULL;
911 if (g && index > 0) {
912 /* because we sort our inserts by index, this lets us know
913 if we've "walked" past the end of the list */
915 t = MPLS_LIST_TAIL(&g->tunnel);
916 if (t == NULL || t->index < index) {
917 *tunnel = NULL;
918 return MPLS_END_OF_LIST;
921 t = MPLS_LIST_HEAD(&g->tunnel);
922 while (t != NULL) {
923 if (t->index == index) {
924 *tunnel = t;
925 return MPLS_SUCCESS;
927 t = MPLS_LIST_NEXT(&g->tunnel, t, _global);
930 *tunnel = NULL;
931 return MPLS_FAILURE;
934 mpls_return_enum ldp_global_find_resource_index(ldp_global * g, uint32_t index,
935 ldp_resource ** resource)
937 ldp_resource *r = NULL;
939 if (g && index > 0) {
940 /* because we sort our inserts by index, this lets us know
941 if we've "walked" past the end of the list */
943 r = MPLS_LIST_TAIL(&g->resource);
944 if (r == NULL || r->index < index) {
945 *resource = NULL;
946 return MPLS_END_OF_LIST;
949 r = MPLS_LIST_HEAD(&g->resource);
950 while (r != NULL) {
951 if (r->index == index) {
952 *resource = r;
953 return MPLS_SUCCESS;
955 r = MPLS_LIST_NEXT(&g->resource, r, _global);
958 *resource = NULL;
959 return MPLS_FAILURE;
962 mpls_return_enum ldp_global_find_hop_list_index(ldp_global * g, uint32_t index,
963 ldp_hop_list ** hop_list)
965 ldp_hop_list *h = NULL;
967 if (g && index > 0) {
968 /* because we sort our inserts by index, this lets us know
969 if we've "walked" past the end of the list */
971 h = MPLS_LIST_TAIL(&g->hop_list);
972 if (h == NULL || h->index < index) {
973 *hop_list = NULL;
974 return MPLS_END_OF_LIST;
977 h = MPLS_LIST_HEAD(&g->hop_list);
978 while (h != NULL) {
979 if (h->index == index) {
980 *hop_list = h;
981 return MPLS_SUCCESS;
983 h = MPLS_LIST_NEXT(&g->hop_list, h, _global);
986 *hop_list = NULL;
987 return MPLS_FAILURE;
990 void _ldp_global_add_tunnel(ldp_global * g, ldp_tunnel * t)
992 ldp_tunnel *tp = NULL;
994 MPLS_ASSERT(g && t);
995 MPLS_REFCNT_HOLD(t);
996 tp = MPLS_LIST_HEAD(&g->tunnel);
997 while (tp != NULL) {
998 if (tp->index > t->index) {
999 MPLS_LIST_INSERT_BEFORE(&g->tunnel, tp, t, _global);
1000 return;
1002 tp = MPLS_LIST_NEXT(&g->tunnel, tp, _global);
1004 MPLS_LIST_ADD_TAIL(&g->tunnel, t, _global, ldp_tunnel);
1007 void _ldp_global_del_tunnel(ldp_global * g, ldp_tunnel * t)
1009 MPLS_ASSERT(g && t);
1010 MPLS_LIST_REMOVE(&g->tunnel, t, _global);
1011 MPLS_REFCNT_RELEASE(t, ldp_tunnel_delete);
1014 void _ldp_global_add_resource(ldp_global * g, ldp_resource * r)
1016 ldp_resource *rp = NULL;
1018 MPLS_ASSERT(g && r);
1019 MPLS_REFCNT_HOLD(r);
1020 rp = MPLS_LIST_HEAD(&g->resource);
1021 while (rp != NULL) {
1022 if (rp->index > r->index) {
1023 MPLS_LIST_INSERT_BEFORE(&g->resource, rp, r, _global);
1024 return;
1026 rp = MPLS_LIST_NEXT(&g->resource, rp, _global);
1028 MPLS_LIST_ADD_TAIL(&g->resource, r, _global, ldp_resource);
1031 void _ldp_global_del_resource(ldp_global * g, ldp_resource * r)
1033 MPLS_ASSERT(g && r);
1034 MPLS_LIST_REMOVE(&g->resource, r, _global);
1035 MPLS_REFCNT_RELEASE(r, ldp_resource_delete);
1038 void _ldp_global_add_hop_list(ldp_global * g, ldp_hop_list * h)
1040 ldp_hop_list *hp = NULL;
1042 MPLS_ASSERT(g && h);
1043 MPLS_REFCNT_HOLD(h);
1044 hp = MPLS_LIST_HEAD(&g->hop_list);
1045 while (hp != NULL) {
1046 if (hp->index > h->index) {
1047 MPLS_LIST_INSERT_BEFORE(&g->hop_list, hp, h, _global);
1048 return;
1050 hp = MPLS_LIST_NEXT(&g->hop_list, hp, _global);
1052 MPLS_LIST_ADD_TAIL(&g->hop_list, h, _global, ldp_hop_list);
1055 void _ldp_global_del_hop_list(ldp_global * g, ldp_hop_list * h)
1057 MPLS_ASSERT(g && h);
1058 MPLS_LIST_REMOVE(&g->hop_list, h, _global);
1059 MPLS_REFCNT_RELEASE(h, ldp_hop_list_delete);