Remove the usage of fprintf from ldp-portable
[mpls-ldp-portable.git] / ldp / ldp_global.c
blob41d105fcb009c7fb813834b199880c15421f3153
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 ldp_fec *fp;
293 ldp_fec *nfp;
294 ldp_if *ifp;
295 ldp_if *nifp;
296 ldp_addr *ap;
297 ldp_addr *nap;
298 ldp_nexthop *nhp;
299 ldp_nexthop *nnhp;
300 ldp_attr *atp;
301 ldp_attr *natp;
302 ldp_inlabel *inp;
303 ldp_inlabel *ninp;
304 ldp_outlabel *outp;
305 ldp_outlabel *noutp;
306 ldp_entity *ep;
307 ldp_entity *nep;
309 if (g) {
310 /* clean up the entities that were configured, sessions and adj should
311 * already have been cleaned up when the entity was shutdown
313 ep = MPLS_LIST_HEAD(&g->entity);
314 while (ep != NULL) {
315 nep = MPLS_LIST_NEXT(&g->entity, ep, _global);
316 switch (ep->entity_type) {
317 case LDP_DIRECT:
318 ldp_entity_del_if(g,ep);
319 break;
320 case LDP_INDIRECT:
321 ldp_entity_del_peer(ep);
322 break;
323 default:
324 MPLS_ASSERT(0);
326 _ldp_global_del_entity(g, ep);
327 ep = nep;
330 /* need to properly purge FECs/nexthops/interfaces/addresses */
332 fp = MPLS_LIST_HEAD(&g->fec);
333 while (fp != NULL) {
334 nfp = MPLS_LIST_NEXT(&g->fec, fp, _global);
336 nhp = MPLS_LIST_HEAD(&fp->nh_root);
337 while (nhp) {
338 nnhp = MPLS_LIST_NEXT(&fp->nh_root, nhp, _fec);
339 ldp_fec_del_nexthop(g, fp, nhp);
340 nhp = nnhp;
342 MPLS_REFCNT_RELEASE2(g, fp, ldp_fec_delete);
344 fp = nfp;
347 ifp = MPLS_LIST_HEAD(&g->iff);
348 while (ifp != NULL) {
349 nifp = MPLS_LIST_NEXT(&g->iff, ifp, _global);
351 ap = MPLS_LIST_HEAD(&ifp->addr_root);
352 while (ap != NULL) {
353 nap = MPLS_LIST_NEXT(&ifp->addr_root, ap, _if);
354 ldp_if_del_addr(g, ifp, ap);
355 ap = nap;
357 MPLS_REFCNT_RELEASE2(g, ifp, ldp_if_delete);
359 ifp = nifp;
362 nhp = MPLS_LIST_HEAD(&g->nexthop);
363 while (nhp != NULL) {
364 LDP_PRINT(g->user_data,"Left over NH: %p type %d ref %d",
365 nhp, nhp->info.type, nhp->_refcnt);
366 switch(nhp->info.type) {
367 case MPLS_NH_IP:
368 LDP_PRINT(g->user_data," IP %08x addr %p",
369 nhp->info.ip.u.ipv4, nhp->addr);
370 break;
371 case MPLS_NH_IF:
372 LDP_PRINT(g->user_data," IF %s handle %p",
373 nhp->info.if_handle->name, nhp->iff);
374 break;
375 case MPLS_NH_OUTSEGMENT:
376 LDP_PRINT(g->user_data," OS %p", nhp->outlabel);
377 break;
378 default:
379 LDP_PRINT(g->user_data," EMPTY");
380 break;
382 nnhp = MPLS_LIST_NEXT(&g->nexthop, nhp, _global);
383 // _ldp_global_del_nexthop(g, nhp);
384 nhp = nnhp;
387 ap = MPLS_LIST_HEAD(&g->addr);
388 while (ap != NULL) {
389 LDP_PRINT(g->user_data, "Left over ADDR: %p address %08x",
390 ap, ap->address.u.ipv4);
391 nap = MPLS_LIST_NEXT(&g->addr, ap, _global);
392 // _ldp_global_del_addr(g, ap);
393 ap = nap;
396 atp = MPLS_LIST_HEAD(&g->attr);
397 while (atp != NULL) {
398 LDP_PRINT(g->user_data, "Left over ATTR: %p %d", atp, atp->_refcnt);
399 natp = MPLS_LIST_NEXT(&g->attr, atp, _global);
400 // _ldp_global_del_attr(g, atp);
401 atp = natp;
404 inp = MPLS_LIST_HEAD(&g->inlabel);
405 while (inp != NULL) {
406 LDP_PRINT(g->user_data,"Left over INLABEL: %p %d", inp, inp->_refcnt);
407 ninp = MPLS_LIST_NEXT(&g->inlabel, inp, _global);
408 inp = ninp;
411 outp = MPLS_LIST_HEAD(&g->outlabel);
412 while (outp != NULL) {
413 LDP_PRINT(g->user_data, "Left over OUTLABEL: %p %d", outp, outp->_refcnt);
414 noutp = MPLS_LIST_NEXT(&g->outlabel, outp, _global);
415 outp = noutp;
418 mpls_tree_delete(g->addr_tree);
419 mpls_tree_delete(g->fec_tree);
421 mpls_lock_delete(g->global_lock);
422 LDP_PRINT(g->user_data, "global delete");
423 mpls_free(g);
425 return MPLS_SUCCESS;
428 void _ldp_global_add_attr(ldp_global * g, ldp_attr * a)
430 ldp_attr *ap = NULL;
432 MPLS_ASSERT(g && a);
433 ap = MPLS_LIST_HEAD(&g->attr);
434 while (ap != NULL) {
435 if (ap->index > a->index) {
436 MPLS_LIST_INSERT_BEFORE(&g->attr, ap, a, _global);
437 return;
439 ap = MPLS_LIST_NEXT(&g->attr, ap, _global);
441 MPLS_LIST_ADD_TAIL(&g->attr, a, _global, ldp_attr);
444 void _ldp_global_del_attr(ldp_global * g, ldp_attr * a)
446 MPLS_ASSERT(g && a);
447 MPLS_LIST_REMOVE(&g->attr, a, _global);
450 void _ldp_global_add_peer(ldp_global * g, ldp_peer * p)
452 ldp_peer *pp = NULL;
454 MPLS_ASSERT(g && p);
455 MPLS_REFCNT_HOLD(p);
456 pp = MPLS_LIST_HEAD(&g->peer);
457 while (pp != NULL) {
458 if (pp->index > p->index) {
459 MPLS_LIST_INSERT_BEFORE(&g->peer, pp, p, _global);
460 return;
462 pp = MPLS_LIST_NEXT(&g->peer, pp, _global);
464 MPLS_LIST_ADD_TAIL(&g->peer, p, _global, ldp_peer);
467 void _ldp_global_del_peer(ldp_global * g, ldp_peer * p)
469 MPLS_ASSERT(g && p);
470 MPLS_LIST_REMOVE(&g->peer, p, _global);
471 MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
475 * _ldp_global_add_if/del_if and _ldp_global_add_addr/del_addr are
476 * not the same as the rest of the global_add/del functions. They
477 * do not hold refcnts, they are used as part of the create and delete
478 * process of these structures
481 void _ldp_global_add_if(ldp_global * g, ldp_if * i)
483 ldp_if *ip = NULL;
485 MPLS_ASSERT(g && i);
486 ip = MPLS_LIST_HEAD(&g->iff);
487 while (ip != NULL) {
488 if (ip->index > i->index) {
489 MPLS_LIST_INSERT_BEFORE(&g->iff, ip, i, _global);
490 return;
492 ip = MPLS_LIST_NEXT(&g->iff, ip, _global);
494 MPLS_LIST_ADD_TAIL(&g->iff, i, _global, ldp_if);
497 void _ldp_global_del_if(ldp_global * g, ldp_if * i)
499 MPLS_ASSERT(g && i);
500 MPLS_LIST_REMOVE(&g->iff, i, _global);
503 void _ldp_global_add_addr(ldp_global * g, ldp_addr * a)
505 ldp_addr *ap = NULL;
507 MPLS_ASSERT(g && a);
508 ap = MPLS_LIST_HEAD(&g->addr);
509 while (ap != NULL) {
510 if (ap->index > a->index) {
511 MPLS_LIST_INSERT_BEFORE(&g->addr, ap, a, _global);
512 return;
514 ap = MPLS_LIST_NEXT(&g->addr, ap, _global);
516 MPLS_LIST_ADD_TAIL(&g->addr, a, _global, ldp_addr);
519 void _ldp_global_del_addr(ldp_global * g, ldp_addr * a)
521 MPLS_ASSERT(g && a);
522 MPLS_LIST_REMOVE(&g->addr, a, _global);
525 void _ldp_global_add_adj(ldp_global * g, ldp_adj * a)
527 ldp_adj *ap = NULL;
529 MPLS_ASSERT(g && a);
530 MPLS_REFCNT_HOLD(a);
531 ap = MPLS_LIST_HEAD(&g->adj);
532 while (ap != NULL) {
533 if (ap->index > a->index) {
534 MPLS_LIST_INSERT_BEFORE(&g->adj, ap, a, _global);
535 return;
537 ap = MPLS_LIST_NEXT(&g->adj, ap, _global);
539 MPLS_LIST_ADD_TAIL(&g->adj, a, _global, ldp_adj);
542 void _ldp_global_del_adj(ldp_global * g, ldp_adj * a)
544 MPLS_ASSERT(g && a);
545 MPLS_LIST_REMOVE(&g->adj, a, _global);
546 MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
549 void _ldp_global_add_entity(ldp_global * g, ldp_entity * e)
551 ldp_entity *ep = NULL;
553 MPLS_ASSERT(g && e);
554 MPLS_REFCNT_HOLD(e);
555 ep = MPLS_LIST_HEAD(&g->entity);
556 while (ep != NULL) {
557 if (ep->index > e->index) {
558 MPLS_LIST_INSERT_BEFORE(&g->entity, ep, e, _global);
559 return;
561 ep = MPLS_LIST_NEXT(&g->entity, ep, _global);
563 MPLS_LIST_ADD_TAIL(&g->entity, e, _global, ldp_entity);
566 void _ldp_global_del_entity(ldp_global * g, ldp_entity * e)
568 MPLS_ASSERT(g && e);
569 MPLS_LIST_REMOVE(&g->entity, e, _global);
570 MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
573 void _ldp_global_add_session(ldp_global * g, ldp_session * s)
575 ldp_session *sp = NULL;
577 MPLS_ASSERT(g && s);
578 MPLS_REFCNT_HOLD(s);
579 s->on_global = MPLS_BOOL_TRUE;
580 sp = MPLS_LIST_HEAD(&g->session);
581 while (sp != NULL) {
582 if (sp->index > s->index) {
583 MPLS_LIST_INSERT_BEFORE(&g->session, sp, s, _global);
584 return;
586 sp = MPLS_LIST_NEXT(&g->session, sp, _global);
588 MPLS_LIST_ADD_TAIL(&g->session, s, _global, ldp_session);
591 void _ldp_global_del_session(ldp_global * g, ldp_session * s)
593 MPLS_ASSERT(g && s);
594 MPLS_ASSERT(s->on_global == MPLS_BOOL_TRUE);
595 MPLS_LIST_REMOVE(&g->session, s, _global);
596 s->on_global = MPLS_BOOL_FALSE;
597 MPLS_REFCNT_RELEASE(s, ldp_session_delete);
600 mpls_return_enum _ldp_global_add_inlabel(ldp_global * g, ldp_inlabel * i)
602 ldp_inlabel *ip = NULL;
603 mpls_return_enum result;
605 MPLS_ASSERT(g && i);
607 #if MPLS_USE_LSR
609 lsr_insegment iseg;
610 memcpy(&iseg.info,&i->info,sizeof(mpls_insegment));
611 result = lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_ADD|
612 LSR_INSEGMENT_CFG_NPOP|LSR_INSEGMENT_CFG_FAMILY|
613 LSR_INSEGMENT_CFG_LABELSPACE|LSR_INSEGMENT_CFG_LABEL|
614 LSR_INSEGMENT_CFG_OWNER);
615 memcpy(&i->info, &iseg.info, sizeof(mpls_insegment));
616 i->info.handle = iseg.index;
618 #else
619 result = mpls_mpls_insegment_add(g->mpls_handle, &i->info);
620 #endif
621 if (result != MPLS_SUCCESS) {
622 return result;
625 ip = MPLS_LIST_HEAD(&g->inlabel);
626 while (ip != NULL) {
627 if (ip->index > i->index) {
628 MPLS_LIST_INSERT_BEFORE(&g->inlabel, ip, i, _global);
629 return MPLS_SUCCESS;
631 ip = MPLS_LIST_NEXT(&g->inlabel, ip, _global);
633 MPLS_LIST_ADD_TAIL(&g->inlabel, i, _global, ldp_inlabel);
634 return MPLS_SUCCESS;
637 mpls_return_enum _ldp_global_del_inlabel(ldp_global * g, ldp_inlabel * i)
639 MPLS_ASSERT(g && i);
640 MPLS_ASSERT(i->reuse_count == 0);
641 #if MPLS_USE_LSR
643 lsr_insegment iseg;
644 iseg.index = i->info.handle;
645 lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_DEL);
647 #else
648 mpls_mpls_insegment_del(g->mpls_handle, &i->info);
649 #endif
650 MPLS_LIST_REMOVE(&g->inlabel, i, _global);
651 return MPLS_SUCCESS;
654 mpls_return_enum _ldp_global_add_outlabel(ldp_global * g, ldp_outlabel * o)
656 ldp_outlabel *op = NULL;
657 mpls_return_enum result;
659 MPLS_ASSERT(g && o);
660 #if MPLS_USE_LSR
662 lsr_outsegment oseg;
663 memcpy(&oseg.info, &o->info, sizeof(mpls_outsegment));
664 result = lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_ADD|
665 LSR_OUTSEGMENT_CFG_PUSH_LABEL|LSR_OUTSEGMENT_CFG_OWNER|
666 LSR_OUTSEGMENT_CFG_INTERFACE|LSR_OUTSEGMENT_CFG_LABEL|
667 LSR_OUTSEGMENT_CFG_NEXTHOP);
668 o->info.handle = oseg.index;
670 #else
671 result = mpls_mpls_outsegment_add(g->mpls_handle, &o->info);
672 #endif
674 if (result != MPLS_SUCCESS) {
675 return result;
678 o->switching = MPLS_BOOL_TRUE;
679 op = MPLS_LIST_HEAD(&g->outlabel);
680 while (op != NULL) {
681 if (op->index > o->index) {
682 MPLS_LIST_INSERT_BEFORE(&g->outlabel, op, o, _global);
683 return MPLS_SUCCESS;
685 op = MPLS_LIST_NEXT(&g->outlabel, op, _global);
687 MPLS_LIST_ADD_TAIL(&g->outlabel, o, _global, ldp_outlabel);
688 return MPLS_SUCCESS;
691 mpls_return_enum _ldp_global_del_outlabel(ldp_global * g, ldp_outlabel * o)
693 MPLS_ASSERT(g && o);
694 #if MPLS_USE_LSR
696 lsr_outsegment oseg;
697 oseg.index = o->info.handle;
698 lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_DEL);
700 #else
701 mpls_mpls_outsegment_del(g->mpls_handle, &o->info);
702 #endif
704 o->switching = MPLS_BOOL_FALSE;
705 MPLS_ASSERT(o->merge_count == 0);
706 MPLS_LIST_REMOVE(&g->outlabel, o, _global);
707 return MPLS_SUCCESS;
710 mpls_return_enum ldp_global_find_attr_index(ldp_global * g, uint32_t index,
711 ldp_attr ** attr)
713 ldp_attr *a = NULL;
715 if (g && index > 0) {
717 /* because we sort our inserts by index, this lets us know
718 if we've "walked" past the end of the list */
720 a = MPLS_LIST_TAIL(&g->attr);
721 if (a == NULL || a->index < index) {
722 return MPLS_END_OF_LIST;
723 *attr = NULL;
726 a = MPLS_LIST_HEAD(&g->attr);
727 while (a != NULL) {
728 if (a->index == index) {
729 *attr = a;
730 return MPLS_SUCCESS;
732 a = MPLS_LIST_NEXT(&g->attr, a, _global);
735 *attr = NULL;
736 return MPLS_FAILURE;
739 mpls_return_enum ldp_global_find_session_index(ldp_global * g, uint32_t index,
740 ldp_session ** session)
742 ldp_session *s = NULL;
744 if (g && index > 0) {
746 /* because we sort our inserts by index, this lets us know
747 if we've "walked" past the end of the list */
749 s = MPLS_LIST_TAIL(&g->session);
750 if (s == NULL || s->index < index) {
751 *session = NULL;
752 return MPLS_END_OF_LIST;
755 s = MPLS_LIST_HEAD(&g->session);
756 while (s != NULL) {
757 if (s->index == index) {
758 *session = s;
759 return MPLS_SUCCESS;
761 s = MPLS_LIST_NEXT(&g->session, s, _global);
764 *session = NULL;
765 return MPLS_FAILURE;
768 mpls_return_enum ldp_global_find_inlabel_index(ldp_global * g, uint32_t index,
769 ldp_inlabel ** inlabel)
771 ldp_inlabel *i = NULL;
773 if (g && index > 0) {
775 /* because we sort our inserts by index, this lets us know
776 if we've "walked" past the end of the list */
778 i = MPLS_LIST_TAIL(&g->inlabel);
779 if (i == NULL || i->index < index) {
780 *inlabel = NULL;
781 return MPLS_END_OF_LIST;
784 i = MPLS_LIST_HEAD(&g->inlabel);
785 while (i != NULL) {
786 if (i->index == index) {
787 *inlabel = i;
788 return MPLS_SUCCESS;
790 i = MPLS_LIST_NEXT(&g->inlabel, i, _global);
793 *inlabel = NULL;
794 return MPLS_FAILURE;
797 mpls_return_enum ldp_global_find_outlabel_index(ldp_global * g, uint32_t index,
798 ldp_outlabel ** outlabel)
800 ldp_outlabel *o = NULL;
802 if (g && index > 0) {
804 /* because we sort our inserts by index, this lets us know
805 if we've "walked" past the end of the list */
807 o = MPLS_LIST_TAIL(&g->outlabel);
808 if (o == NULL || o->index < index) {
809 *outlabel = NULL;
810 return MPLS_END_OF_LIST;
813 o = MPLS_LIST_HEAD(&g->outlabel);
814 while (o != NULL) {
815 if (o->index == index) {
816 *outlabel = o;
817 return MPLS_SUCCESS;
819 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
822 *outlabel = NULL;
823 return MPLS_FAILURE;
826 ldp_outlabel *ldp_global_find_outlabel_handle(ldp_global * g,
827 mpls_outsegment_handle handle)
829 ldp_outlabel *o = MPLS_LIST_HEAD(&g->outlabel);
831 if (g) {
832 while (o != NULL) {
833 if (!mpls_outsegment_handle_compare(o->info.handle, handle))
834 return o;
836 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
839 return NULL;
842 mpls_return_enum ldp_global_find_entity_index(ldp_global * g, uint32_t index,
843 ldp_entity ** entity)
845 ldp_entity *e = NULL;
847 if (g && index > 0) {
849 /* because we sort our inserts by index, this lets us know
850 if we've "walked" past the end of the list */
852 e = MPLS_LIST_TAIL(&g->entity);
853 if (e == NULL || e->index < index) {
854 *entity = NULL;
855 return MPLS_END_OF_LIST;
858 e = MPLS_LIST_HEAD(&g->entity);
859 while (e != NULL) {
860 if (e->index == index) {
861 *entity = e;
862 return MPLS_SUCCESS;
864 e = MPLS_LIST_NEXT(&g->entity, e, _global);
867 *entity = NULL;
868 return MPLS_FAILURE;
871 ldp_peer *ldp_global_find_peer_addr(ldp_global * g, mpls_inet_addr * addr)
873 ldp_peer *p;
875 MPLS_ASSERT(g && addr);
877 /* JLEU: we will need to add a tree to optimize this search,
878 known peers will be in tree, unknown will take a "slow path" to
879 verify them, then be added to tree */
881 p = MPLS_LIST_HEAD(&g->peer);
882 while (p) {
883 LDP_PRINT(g->user_data,
884 "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
885 p->dest.addr.u.ipv4, addr->u.ipv4);
886 if (!mpls_inet_addr_compare(&p->dest.addr, addr)) {
887 return p;
889 p = MPLS_LIST_NEXT(&g->peer, p, _global);
891 return NULL;
894 mpls_return_enum ldp_global_find_adj_index(ldp_global * g, uint32_t index,
895 ldp_adj ** adj)
897 ldp_adj *a = NULL;
899 if (g && index > 0) {
900 /* because we sort our inserts by index, this lets us know
901 if we've "walked" past the end of the list */
903 a = MPLS_LIST_TAIL(&g->adj);
904 if (a == NULL || a->index < index) {
905 return MPLS_END_OF_LIST;
906 *adj = NULL;
909 a = MPLS_LIST_HEAD(&g->adj);
910 while (a != NULL) {
911 if (a->index == index) {
912 *adj = a;
913 return MPLS_SUCCESS;
915 a = MPLS_LIST_NEXT(&g->adj, a, _global);
918 *adj = NULL;
919 return MPLS_FAILURE;
922 mpls_return_enum ldp_global_find_peer_index(ldp_global * g, uint32_t index,
923 ldp_peer ** peer)
925 ldp_peer *p = NULL;
927 if (g && index > 0) {
928 /* because we sort our inserts by index, this lets us know
929 if we've "walked" past the end of the list */
931 p = MPLS_LIST_TAIL(&g->peer);
932 if (p == NULL || p->index < index) {
933 *peer = NULL;
934 return MPLS_END_OF_LIST;
937 p = MPLS_LIST_HEAD(&g->peer);
938 while (p != NULL) {
939 if (p->index == index) {
940 *peer = p;
941 return MPLS_SUCCESS;
943 p = MPLS_LIST_NEXT(&g->peer, p, _global);
946 *peer = NULL;
947 return MPLS_FAILURE;
950 mpls_return_enum ldp_global_find_fec_index(ldp_global * g, uint32_t index,
951 ldp_fec ** fec)
953 ldp_fec *f = NULL;
955 if (g && index > 0) {
956 /* because we sort our inserts by index, this lets us know
957 if we've "walked" past the end of the list */
959 f = MPLS_LIST_TAIL(&g->fec);
960 if (f == NULL || f->index < index) {
961 *fec = NULL;
962 return MPLS_END_OF_LIST;
965 f = MPLS_LIST_HEAD(&g->fec);
966 while (f != NULL) {
967 if (f->index == index) {
968 *fec = f;
969 return MPLS_SUCCESS;
971 f = MPLS_LIST_NEXT(&g->fec, f, _global);
974 *fec = NULL;
975 return MPLS_FAILURE;
978 mpls_return_enum ldp_global_find_fec(ldp_global * g, mpls_fec * m,
979 ldp_fec ** fec)
981 ldp_fec *f = NULL;
983 MPLS_ASSERT(g && m);
985 f = MPLS_LIST_HEAD(&g->fec);
986 do {
987 if (!mpls_fec_compare(m, &f->info)) {
988 *fec = f;
989 return MPLS_SUCCESS;
991 } while((f = MPLS_LIST_NEXT(&g->fec, f, _global)));
992 *fec = NULL;
993 return MPLS_FAILURE;
996 mpls_return_enum ldp_global_find_addr_index(ldp_global * g, uint32_t index,
997 ldp_addr ** addr)
999 ldp_addr *a = NULL;
1001 if (g && index > 0) {
1003 /* because we sort our inserts by index, this lets us know
1004 if we've "walked" past the end of the list */
1006 a = MPLS_LIST_TAIL(&g->addr);
1007 if (a == NULL || a->index < index) {
1008 *addr = NULL;
1009 return MPLS_END_OF_LIST;
1012 a = MPLS_LIST_HEAD(&g->addr);
1013 while (a != NULL) {
1014 if (a->index == index) {
1015 *addr = a;
1016 return MPLS_SUCCESS;
1018 a = MPLS_LIST_NEXT(&g->addr, a, _global);
1021 *addr = NULL;
1022 return MPLS_FAILURE;
1025 mpls_return_enum ldp_global_find_if_index(ldp_global * g, uint32_t index,
1026 ldp_if ** iff)
1028 ldp_if *i = NULL;
1030 if (g && index > 0) {
1032 /* because we sort our inserts by index, this lets us know
1033 if we've "walked" past the end of the list */
1035 i = MPLS_LIST_TAIL(&g->iff);
1036 if (i == NULL || i->index < index) {
1037 *iff = NULL;
1038 return MPLS_END_OF_LIST;
1041 i = MPLS_LIST_HEAD(&g->iff);
1042 while (i != NULL) {
1043 if (i->index == index) {
1044 *iff = i;
1045 return MPLS_SUCCESS;
1047 i = MPLS_LIST_NEXT(&g->iff, i, _global);
1050 *iff = NULL;
1051 return MPLS_FAILURE;
1054 ldp_if *ldp_global_find_if_handle(ldp_global * g, mpls_if_handle handle)
1056 ldp_if *i = MPLS_LIST_HEAD(&g->iff);
1058 if (g) {
1059 while (i != NULL) {
1060 if (!mpls_if_handle_compare(i->handle, handle))
1061 return i;
1063 i = MPLS_LIST_NEXT(&g->iff, i, _global);
1066 return NULL;
1069 ldp_adj *ldp_global_find_adj_ldpid(ldp_global * g, mpls_inet_addr * lsraddr,
1070 int labelspace)
1073 ldp_adj *a = MPLS_LIST_HEAD(&g->adj);
1075 while (a != NULL) {
1076 if ((!mpls_inet_addr_compare(lsraddr, &a->remote_lsr_address)) &&
1077 labelspace == a->remote_label_space)
1078 return a;
1080 a = MPLS_LIST_NEXT(&g->adj, a, _global);
1082 return NULL;
1085 mpls_return_enum ldp_global_find_tunnel_index(ldp_global * g, uint32_t index,
1086 ldp_tunnel ** tunnel)
1088 ldp_tunnel *t = NULL;
1090 if (g && index > 0) {
1091 /* because we sort our inserts by index, this lets us know
1092 if we've "walked" past the end of the list */
1094 t = MPLS_LIST_TAIL(&g->tunnel);
1095 if (t == NULL || t->index < index) {
1096 *tunnel = NULL;
1097 return MPLS_END_OF_LIST;
1100 t = MPLS_LIST_HEAD(&g->tunnel);
1101 while (t != NULL) {
1102 if (t->index == index) {
1103 *tunnel = t;
1104 return MPLS_SUCCESS;
1106 t = MPLS_LIST_NEXT(&g->tunnel, t, _global);
1109 *tunnel = NULL;
1110 return MPLS_FAILURE;
1113 mpls_return_enum ldp_global_find_resource_index(ldp_global * g, uint32_t index,
1114 ldp_resource ** resource)
1116 ldp_resource *r = NULL;
1118 if (g && index > 0) {
1119 /* because we sort our inserts by index, this lets us know
1120 if we've "walked" past the end of the list */
1122 r = MPLS_LIST_TAIL(&g->resource);
1123 if (r == NULL || r->index < index) {
1124 *resource = NULL;
1125 return MPLS_END_OF_LIST;
1128 r = MPLS_LIST_HEAD(&g->resource);
1129 while (r != NULL) {
1130 if (r->index == index) {
1131 *resource = r;
1132 return MPLS_SUCCESS;
1134 r = MPLS_LIST_NEXT(&g->resource, r, _global);
1137 *resource = NULL;
1138 return MPLS_FAILURE;
1141 mpls_return_enum ldp_global_find_hop_list_index(ldp_global * g, uint32_t index,
1142 ldp_hop_list ** hop_list)
1144 ldp_hop_list *h = NULL;
1146 if (g && index > 0) {
1147 /* because we sort our inserts by index, this lets us know
1148 if we've "walked" past the end of the list */
1150 h = MPLS_LIST_TAIL(&g->hop_list);
1151 if (h == NULL || h->index < index) {
1152 *hop_list = NULL;
1153 return MPLS_END_OF_LIST;
1156 h = MPLS_LIST_HEAD(&g->hop_list);
1157 while (h != NULL) {
1158 if (h->index == index) {
1159 *hop_list = h;
1160 return MPLS_SUCCESS;
1162 h = MPLS_LIST_NEXT(&g->hop_list, h, _global);
1165 *hop_list = NULL;
1166 return MPLS_FAILURE;
1169 void _ldp_global_add_tunnel(ldp_global * g, ldp_tunnel * t)
1171 ldp_tunnel *tp = NULL;
1173 MPLS_ASSERT(g && t);
1174 MPLS_REFCNT_HOLD(t);
1175 tp = MPLS_LIST_HEAD(&g->tunnel);
1176 while (tp != NULL) {
1177 if (tp->index > t->index) {
1178 MPLS_LIST_INSERT_BEFORE(&g->tunnel, tp, t, _global);
1179 return;
1181 tp = MPLS_LIST_NEXT(&g->tunnel, tp, _global);
1183 MPLS_LIST_ADD_TAIL(&g->tunnel, t, _global, ldp_tunnel);
1186 void _ldp_global_del_tunnel(ldp_global * g, ldp_tunnel * t)
1188 MPLS_ASSERT(g && t);
1189 MPLS_LIST_REMOVE(&g->tunnel, t, _global);
1190 MPLS_REFCNT_RELEASE(t, ldp_tunnel_delete);
1193 void _ldp_global_add_resource(ldp_global * g, ldp_resource * r)
1195 ldp_resource *rp = NULL;
1197 MPLS_ASSERT(g && r);
1198 MPLS_REFCNT_HOLD(r);
1199 rp = MPLS_LIST_HEAD(&g->resource);
1200 while (rp != NULL) {
1201 if (rp->index > r->index) {
1202 MPLS_LIST_INSERT_BEFORE(&g->resource, rp, r, _global);
1203 return;
1205 rp = MPLS_LIST_NEXT(&g->resource, rp, _global);
1207 MPLS_LIST_ADD_TAIL(&g->resource, r, _global, ldp_resource);
1210 void _ldp_global_del_resource(ldp_global * g, ldp_resource * r)
1212 MPLS_ASSERT(g && r);
1213 MPLS_LIST_REMOVE(&g->resource, r, _global);
1214 MPLS_REFCNT_RELEASE(r, ldp_resource_delete);
1217 void _ldp_global_add_hop_list(ldp_global * g, ldp_hop_list * h)
1219 ldp_hop_list *hp = NULL;
1221 MPLS_ASSERT(g && h);
1222 MPLS_REFCNT_HOLD(h);
1223 hp = MPLS_LIST_HEAD(&g->hop_list);
1224 while (hp != NULL) {
1225 if (hp->index > h->index) {
1226 MPLS_LIST_INSERT_BEFORE(&g->hop_list, hp, h, _global);
1227 return;
1229 hp = MPLS_LIST_NEXT(&g->hop_list, hp, _global);
1231 MPLS_LIST_ADD_TAIL(&g->hop_list, h, _global, ldp_hop_list);
1234 void _ldp_global_del_hop_list(ldp_global * g, ldp_hop_list * h)
1236 MPLS_ASSERT(g && h);
1237 MPLS_LIST_REMOVE(&g->hop_list, h, _global);
1238 MPLS_REFCNT_RELEASE(h, ldp_hop_list_delete);
1241 void _ldp_global_add_fec(ldp_global * g, ldp_fec * f)
1243 ldp_fec *fp = NULL;
1245 MPLS_ASSERT(g && f);
1247 * TESTING: jleu 6/7/2004, since I want the FEC to be cleaned up
1248 * when it no longer has a nexthop, addr, or label, the only things that
1249 * should increment the ref are those (nh, addr, label etc), not global
1250 * nor inserting into the tree. I also added this comment in
1251 * ldp_fec_create()
1252 * MPLS_REFCNT_HOLD(f);
1254 fp = MPLS_LIST_HEAD(&g->fec);
1255 while (fp != NULL) {
1256 if (fp->index > f->index) {
1257 MPLS_LIST_INSERT_BEFORE(&g->fec, fp, f, _global);
1258 return;
1260 fp = MPLS_LIST_NEXT(&g->fec, fp, _global);
1262 MPLS_LIST_ADD_TAIL(&g->fec, f, _global, ldp_fec);
1265 void _ldp_global_del_fec(ldp_global * g, ldp_fec * f)
1267 MPLS_ASSERT(g && f);
1268 MPLS_LIST_REMOVE(&g->fec, f, _global);
1271 void _ldp_global_add_nexthop(ldp_global * g, ldp_nexthop * nh)
1273 ldp_nexthop *nhp = NULL;
1275 MPLS_ASSERT(g && nh);
1276 nhp = MPLS_LIST_HEAD(&g->nexthop);
1277 while (nhp != NULL) {
1278 if (nhp->index > nh->index) {
1279 MPLS_LIST_INSERT_BEFORE(&g->nexthop, nhp, nh, _global);
1280 return;
1282 nhp = MPLS_LIST_NEXT(&g->nexthop, nhp, _global);
1284 MPLS_LIST_ADD_TAIL(&g->nexthop, nh, _global, ldp_nexthop);
1287 void _ldp_global_del_nexthop(ldp_global * g, ldp_nexthop * nh)
1289 MPLS_ASSERT(g && nh);
1290 MPLS_LIST_REMOVE(&g->nexthop, nh, _global);