From: Vasu Dasari <vdasari@gmail.com>
[mpls-ldp-portable.git] / ldp / ldp_global.c
blobab6ec6dabac367476bc7c1cbdca025eec2c4aae3
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(MTYPE_LDP, 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(MTYPE_LDP, 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 LDP_PRINT(g->user_data,"Here 1");
702 mpls_mpls_outsegment_del(g->mpls_handle, &o->info);
703 #endif
705 LDP_PRINT(g->user_data,"Here 2");
706 o->switching = MPLS_BOOL_FALSE;
707 LDP_PRINT(g->user_data,"Here 3");
708 MPLS_ASSERT(o->merge_count == 0);
709 LDP_PRINT(g->user_data,"Here 4");
710 MPLS_LIST_REMOVE(&g->outlabel, o, _global);
711 LDP_PRINT(g->user_data,"Here 5");
712 return MPLS_SUCCESS;
715 mpls_return_enum ldp_global_find_attr_index(ldp_global * g, uint32_t index,
716 ldp_attr ** attr)
718 ldp_attr *a = NULL;
720 if (g && index > 0) {
722 /* because we sort our inserts by index, this lets us know
723 if we've "walked" past the end of the list */
725 a = MPLS_LIST_TAIL(&g->attr);
726 if (a == NULL || a->index < index) {
727 return MPLS_END_OF_LIST;
728 *attr = NULL;
731 a = MPLS_LIST_HEAD(&g->attr);
732 while (a != NULL) {
733 if (a->index == index) {
734 *attr = a;
735 return MPLS_SUCCESS;
737 a = MPLS_LIST_NEXT(&g->attr, a, _global);
740 *attr = NULL;
741 return MPLS_FAILURE;
744 mpls_return_enum ldp_global_find_session_index(ldp_global * g, uint32_t index,
745 ldp_session ** session)
747 ldp_session *s = NULL;
749 if (g && index > 0) {
751 /* because we sort our inserts by index, this lets us know
752 if we've "walked" past the end of the list */
754 s = MPLS_LIST_TAIL(&g->session);
755 if (s == NULL || s->index < index) {
756 *session = NULL;
757 return MPLS_END_OF_LIST;
760 s = MPLS_LIST_HEAD(&g->session);
761 while (s != NULL) {
762 if (s->index == index) {
763 *session = s;
764 return MPLS_SUCCESS;
766 s = MPLS_LIST_NEXT(&g->session, s, _global);
769 *session = NULL;
770 return MPLS_FAILURE;
773 mpls_return_enum ldp_global_find_inlabel_index(ldp_global * g, uint32_t index,
774 ldp_inlabel ** inlabel)
776 ldp_inlabel *i = NULL;
778 if (g && index > 0) {
780 /* because we sort our inserts by index, this lets us know
781 if we've "walked" past the end of the list */
783 i = MPLS_LIST_TAIL(&g->inlabel);
784 if (i == NULL || i->index < index) {
785 *inlabel = NULL;
786 return MPLS_END_OF_LIST;
789 i = MPLS_LIST_HEAD(&g->inlabel);
790 while (i != NULL) {
791 if (i->index == index) {
792 *inlabel = i;
793 return MPLS_SUCCESS;
795 i = MPLS_LIST_NEXT(&g->inlabel, i, _global);
798 *inlabel = NULL;
799 return MPLS_FAILURE;
802 mpls_return_enum ldp_global_find_outlabel_index(ldp_global * g, uint32_t index,
803 ldp_outlabel ** outlabel)
805 ldp_outlabel *o = NULL;
807 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 o = MPLS_LIST_TAIL(&g->outlabel);
813 if (o == NULL || o->index < index) {
814 *outlabel = NULL;
815 return MPLS_END_OF_LIST;
818 o = MPLS_LIST_HEAD(&g->outlabel);
819 while (o != NULL) {
820 if (o->index == index) {
821 *outlabel = o;
822 return MPLS_SUCCESS;
824 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
827 *outlabel = NULL;
828 return MPLS_FAILURE;
831 ldp_outlabel *ldp_global_find_outlabel_handle(ldp_global * g,
832 mpls_outsegment_handle handle)
834 ldp_outlabel *o = MPLS_LIST_HEAD(&g->outlabel);
836 if (g) {
837 while (o != NULL) {
838 if (!mpls_outsegment_handle_compare(o->info.handle, handle))
839 return o;
841 o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
844 return NULL;
847 mpls_return_enum ldp_global_find_entity_index(ldp_global * g, uint32_t index,
848 ldp_entity ** entity)
850 ldp_entity *e = NULL;
852 if (g && index > 0) {
854 /* because we sort our inserts by index, this lets us know
855 if we've "walked" past the end of the list */
857 e = MPLS_LIST_TAIL(&g->entity);
858 if (e == NULL || e->index < index) {
859 *entity = NULL;
860 return MPLS_END_OF_LIST;
863 e = MPLS_LIST_HEAD(&g->entity);
864 while (e != NULL) {
865 if (e->index == index) {
866 *entity = e;
867 return MPLS_SUCCESS;
869 e = MPLS_LIST_NEXT(&g->entity, e, _global);
872 *entity = NULL;
873 return MPLS_FAILURE;
876 ldp_peer *ldp_global_find_peer_addr(ldp_global * g, mpls_inet_addr * addr)
878 ldp_peer *p;
880 MPLS_ASSERT(g && addr);
882 /* JLEU: we will need to add a tree to optimize this search,
883 known peers will be in tree, unknown will take a "slow path" to
884 verify them, then be added to tree */
886 p = MPLS_LIST_HEAD(&g->peer);
887 while (p) {
888 LDP_PRINT(g->user_data,
889 "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
890 p->dest.addr.u.ipv4, addr->u.ipv4);
891 if (!mpls_inet_addr_compare(&p->dest.addr, addr)) {
892 return p;
894 p = MPLS_LIST_NEXT(&g->peer, p, _global);
896 return NULL;
899 mpls_return_enum ldp_global_find_adj_index(ldp_global * g, uint32_t index,
900 ldp_adj ** adj)
902 ldp_adj *a = NULL;
904 if (g && index > 0) {
905 /* because we sort our inserts by index, this lets us know
906 if we've "walked" past the end of the list */
908 a = MPLS_LIST_TAIL(&g->adj);
909 if (a == NULL || a->index < index) {
910 return MPLS_END_OF_LIST;
911 *adj = NULL;
914 a = MPLS_LIST_HEAD(&g->adj);
915 while (a != NULL) {
916 if (a->index == index) {
917 *adj = a;
918 return MPLS_SUCCESS;
920 a = MPLS_LIST_NEXT(&g->adj, a, _global);
923 *adj = NULL;
924 return MPLS_FAILURE;
927 mpls_return_enum ldp_global_find_peer_index(ldp_global * g, uint32_t index,
928 ldp_peer ** peer)
930 ldp_peer *p = NULL;
932 if (g && index > 0) {
933 /* because we sort our inserts by index, this lets us know
934 if we've "walked" past the end of the list */
936 p = MPLS_LIST_TAIL(&g->peer);
937 if (p == NULL || p->index < index) {
938 *peer = NULL;
939 return MPLS_END_OF_LIST;
942 p = MPLS_LIST_HEAD(&g->peer);
943 while (p != NULL) {
944 if (p->index == index) {
945 *peer = p;
946 return MPLS_SUCCESS;
948 p = MPLS_LIST_NEXT(&g->peer, p, _global);
951 *peer = NULL;
952 return MPLS_FAILURE;
955 mpls_return_enum ldp_global_find_fec_index(ldp_global * g, uint32_t index,
956 ldp_fec ** fec)
958 ldp_fec *f = NULL;
960 if (g && index > 0) {
961 /* because we sort our inserts by index, this lets us know
962 if we've "walked" past the end of the list */
964 f = MPLS_LIST_TAIL(&g->fec);
965 if (f == NULL || f->index < index) {
966 *fec = NULL;
967 return MPLS_END_OF_LIST;
970 f = MPLS_LIST_HEAD(&g->fec);
971 while (f != NULL) {
972 if (f->index == index) {
973 *fec = f;
974 return MPLS_SUCCESS;
976 f = MPLS_LIST_NEXT(&g->fec, f, _global);
979 *fec = NULL;
980 return MPLS_FAILURE;
983 mpls_return_enum ldp_global_find_fec(ldp_global * g, mpls_fec * m,
984 ldp_fec ** fec)
986 ldp_fec *f = NULL;
988 MPLS_ASSERT(g && m);
990 f = MPLS_LIST_HEAD(&g->fec);
991 do {
992 if (!mpls_fec_compare(m, &f->info)) {
993 *fec = f;
994 return MPLS_SUCCESS;
996 } while((f = MPLS_LIST_NEXT(&g->fec, f, _global)));
997 *fec = NULL;
998 return MPLS_FAILURE;
1001 mpls_return_enum ldp_global_find_addr_index(ldp_global * g, uint32_t index,
1002 ldp_addr ** addr)
1004 ldp_addr *a = NULL;
1006 if (g && index > 0) {
1008 /* because we sort our inserts by index, this lets us know
1009 if we've "walked" past the end of the list */
1011 a = MPLS_LIST_TAIL(&g->addr);
1012 if (a == NULL || a->index < index) {
1013 *addr = NULL;
1014 return MPLS_END_OF_LIST;
1017 a = MPLS_LIST_HEAD(&g->addr);
1018 while (a != NULL) {
1019 if (a->index == index) {
1020 *addr = a;
1021 return MPLS_SUCCESS;
1023 a = MPLS_LIST_NEXT(&g->addr, a, _global);
1026 *addr = NULL;
1027 return MPLS_FAILURE;
1030 mpls_return_enum ldp_global_find_if_index(ldp_global * g, uint32_t index,
1031 ldp_if ** iff)
1033 ldp_if *i = NULL;
1035 if (g && index > 0) {
1037 /* because we sort our inserts by index, this lets us know
1038 if we've "walked" past the end of the list */
1040 i = MPLS_LIST_TAIL(&g->iff);
1041 if (i == NULL || i->index < index) {
1042 *iff = NULL;
1043 return MPLS_END_OF_LIST;
1046 i = MPLS_LIST_HEAD(&g->iff);
1047 while (i != NULL) {
1048 if (i->index == index) {
1049 *iff = i;
1050 return MPLS_SUCCESS;
1052 i = MPLS_LIST_NEXT(&g->iff, i, _global);
1055 *iff = NULL;
1056 return MPLS_FAILURE;
1059 ldp_if *ldp_global_find_if_handle(ldp_global * g, mpls_if_handle handle)
1061 ldp_if *i = MPLS_LIST_HEAD(&g->iff);
1063 if (g) {
1064 while (i != NULL) {
1065 if (!mpls_if_handle_compare(i->handle, handle))
1066 return i;
1068 i = MPLS_LIST_NEXT(&g->iff, i, _global);
1071 return NULL;
1074 ldp_adj *ldp_global_find_adj_ldpid(ldp_global * g, mpls_inet_addr * lsraddr,
1075 int labelspace)
1078 ldp_adj *a = MPLS_LIST_HEAD(&g->adj);
1080 while (a != NULL) {
1081 if ((!mpls_inet_addr_compare(lsraddr, &a->remote_lsr_address)) &&
1082 labelspace == a->remote_label_space)
1083 return a;
1085 a = MPLS_LIST_NEXT(&g->adj, a, _global);
1087 return NULL;
1090 mpls_return_enum ldp_global_find_tunnel_index(ldp_global * g, uint32_t index,
1091 ldp_tunnel ** tunnel)
1093 ldp_tunnel *t = NULL;
1095 if (g && index > 0) {
1096 /* because we sort our inserts by index, this lets us know
1097 if we've "walked" past the end of the list */
1099 t = MPLS_LIST_TAIL(&g->tunnel);
1100 if (t == NULL || t->index < index) {
1101 *tunnel = NULL;
1102 return MPLS_END_OF_LIST;
1105 t = MPLS_LIST_HEAD(&g->tunnel);
1106 while (t != NULL) {
1107 if (t->index == index) {
1108 *tunnel = t;
1109 return MPLS_SUCCESS;
1111 t = MPLS_LIST_NEXT(&g->tunnel, t, _global);
1114 *tunnel = NULL;
1115 return MPLS_FAILURE;
1118 mpls_return_enum ldp_global_find_resource_index(ldp_global * g, uint32_t index,
1119 ldp_resource ** resource)
1121 ldp_resource *r = NULL;
1123 if (g && index > 0) {
1124 /* because we sort our inserts by index, this lets us know
1125 if we've "walked" past the end of the list */
1127 r = MPLS_LIST_TAIL(&g->resource);
1128 if (r == NULL || r->index < index) {
1129 *resource = NULL;
1130 return MPLS_END_OF_LIST;
1133 r = MPLS_LIST_HEAD(&g->resource);
1134 while (r != NULL) {
1135 if (r->index == index) {
1136 *resource = r;
1137 return MPLS_SUCCESS;
1139 r = MPLS_LIST_NEXT(&g->resource, r, _global);
1142 *resource = NULL;
1143 return MPLS_FAILURE;
1146 mpls_return_enum ldp_global_find_hop_list_index(ldp_global * g, uint32_t index,
1147 ldp_hop_list ** hop_list)
1149 ldp_hop_list *h = NULL;
1151 if (g && index > 0) {
1152 /* because we sort our inserts by index, this lets us know
1153 if we've "walked" past the end of the list */
1155 h = MPLS_LIST_TAIL(&g->hop_list);
1156 if (h == NULL || h->index < index) {
1157 *hop_list = NULL;
1158 return MPLS_END_OF_LIST;
1161 h = MPLS_LIST_HEAD(&g->hop_list);
1162 while (h != NULL) {
1163 if (h->index == index) {
1164 *hop_list = h;
1165 return MPLS_SUCCESS;
1167 h = MPLS_LIST_NEXT(&g->hop_list, h, _global);
1170 *hop_list = NULL;
1171 return MPLS_FAILURE;
1174 void _ldp_global_add_tunnel(ldp_global * g, ldp_tunnel * t)
1176 ldp_tunnel *tp = NULL;
1178 MPLS_ASSERT(g && t);
1179 MPLS_REFCNT_HOLD(t);
1180 tp = MPLS_LIST_HEAD(&g->tunnel);
1181 while (tp != NULL) {
1182 if (tp->index > t->index) {
1183 MPLS_LIST_INSERT_BEFORE(&g->tunnel, tp, t, _global);
1184 return;
1186 tp = MPLS_LIST_NEXT(&g->tunnel, tp, _global);
1188 MPLS_LIST_ADD_TAIL(&g->tunnel, t, _global, ldp_tunnel);
1191 void _ldp_global_del_tunnel(ldp_global * g, ldp_tunnel * t)
1193 MPLS_ASSERT(g && t);
1194 MPLS_LIST_REMOVE(&g->tunnel, t, _global);
1195 MPLS_REFCNT_RELEASE(t, ldp_tunnel_delete);
1198 void _ldp_global_add_resource(ldp_global * g, ldp_resource * r)
1200 ldp_resource *rp = NULL;
1202 MPLS_ASSERT(g && r);
1203 MPLS_REFCNT_HOLD(r);
1204 rp = MPLS_LIST_HEAD(&g->resource);
1205 while (rp != NULL) {
1206 if (rp->index > r->index) {
1207 MPLS_LIST_INSERT_BEFORE(&g->resource, rp, r, _global);
1208 return;
1210 rp = MPLS_LIST_NEXT(&g->resource, rp, _global);
1212 MPLS_LIST_ADD_TAIL(&g->resource, r, _global, ldp_resource);
1215 void _ldp_global_del_resource(ldp_global * g, ldp_resource * r)
1217 MPLS_ASSERT(g && r);
1218 MPLS_LIST_REMOVE(&g->resource, r, _global);
1219 MPLS_REFCNT_RELEASE(r, ldp_resource_delete);
1222 void _ldp_global_add_hop_list(ldp_global * g, ldp_hop_list * h)
1224 ldp_hop_list *hp = NULL;
1226 MPLS_ASSERT(g && h);
1227 MPLS_REFCNT_HOLD(h);
1228 hp = MPLS_LIST_HEAD(&g->hop_list);
1229 while (hp != NULL) {
1230 if (hp->index > h->index) {
1231 MPLS_LIST_INSERT_BEFORE(&g->hop_list, hp, h, _global);
1232 return;
1234 hp = MPLS_LIST_NEXT(&g->hop_list, hp, _global);
1236 MPLS_LIST_ADD_TAIL(&g->hop_list, h, _global, ldp_hop_list);
1239 void _ldp_global_del_hop_list(ldp_global * g, ldp_hop_list * h)
1241 MPLS_ASSERT(g && h);
1242 MPLS_LIST_REMOVE(&g->hop_list, h, _global);
1243 MPLS_REFCNT_RELEASE(h, ldp_hop_list_delete);
1246 void _ldp_global_add_fec(ldp_global * g, ldp_fec * f)
1248 ldp_fec *fp = NULL;
1250 MPLS_ASSERT(g && f);
1252 * TESTING: jleu 6/7/2004, since I want the FEC to be cleaned up
1253 * when it no longer has a nexthop, addr, or label, the only things that
1254 * should increment the ref are those (nh, addr, label etc), not global
1255 * nor inserting into the tree. I also added this comment in
1256 * ldp_fec_create()
1257 * MPLS_REFCNT_HOLD(f);
1259 fp = MPLS_LIST_HEAD(&g->fec);
1260 while (fp != NULL) {
1261 if (fp->index > f->index) {
1262 MPLS_LIST_INSERT_BEFORE(&g->fec, fp, f, _global);
1263 return;
1265 fp = MPLS_LIST_NEXT(&g->fec, fp, _global);
1267 MPLS_LIST_ADD_TAIL(&g->fec, f, _global, ldp_fec);
1270 void _ldp_global_del_fec(ldp_global * g, ldp_fec * f)
1272 MPLS_ASSERT(g && f);
1273 MPLS_LIST_REMOVE(&g->fec, f, _global);
1276 void _ldp_global_add_nexthop(ldp_global * g, ldp_nexthop * nh)
1278 ldp_nexthop *nhp = NULL;
1280 MPLS_ASSERT(g && nh);
1281 nhp = MPLS_LIST_HEAD(&g->nexthop);
1282 while (nhp != NULL) {
1283 if (nhp->index > nh->index) {
1284 MPLS_LIST_INSERT_BEFORE(&g->nexthop, nhp, nh, _global);
1285 return;
1287 nhp = MPLS_LIST_NEXT(&g->nexthop, nhp, _global);
1289 MPLS_LIST_ADD_TAIL(&g->nexthop, nh, _global, ldp_nexthop);
1292 void _ldp_global_del_nexthop(ldp_global * g, ldp_nexthop * nh)
1294 MPLS_ASSERT(g && nh);
1295 MPLS_LIST_REMOVE(&g->nexthop, nh, _global);