3 * Copyright (C) James R. Leu 2000
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
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"
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"
47 #include "mpls_mpls_impl.h"
50 void _ldp_global_ifmgr_callback(mpls_cfg_handle handle
, const mpls_update_enum type
, mpls_inet_addr
*addr
)
52 ldp_session
*s
= NULL
;
53 ldp_global
*cfg
= (ldp_global
*)handle
;
55 LDP_ENTER(cfg
->user_data
, "_ldp_global_ifmgr_callback");
57 mpls_lock_get(cfg
->global_lock
);
59 if (mpls_policy_address_export_check(cfg
->user_data
, addr
) == MPLS_BOOL_TRUE
) {
60 s
= MPLS_LIST_HEAD(&cfg
->session
);
64 LDP_TRACE_LOG(cfg
->user_data
, MPLS_TRACE_STATE_ALL
,
65 LDP_TRACE_FLAG_EVENT
, "ADD\n");
66 ldp_addr_send(cfg
, s
, addr
);
69 LDP_TRACE_LOG(cfg
->user_data
, MPLS_TRACE_STATE_ALL
,
70 LDP_TRACE_FLAG_EVENT
, "DEL\n");
71 ldp_waddr_send(cfg
, s
, addr
);
76 s
= MPLS_LIST_NEXT(&cfg
->session
, s
, _global
);
80 mpls_lock_release(cfg
->global_lock
);
82 LDP_EXIT(cfg
->user_data
, "_ldp_global_ifmgr_callback");
85 ldp_global
*ldp_global_create(mpls_instance_handle data
)
87 ldp_global
*g
= (ldp_global
*) mpls_malloc(sizeof(ldp_global
));
90 memset(g
, 0, sizeof(ldp_global
));
92 LDP_ENTER(g
->user_data
, "ldp_global_create");
94 g
->global_lock
= mpls_lock_create("_ldp_global_lock_");
95 mpls_lock_get(g
->global_lock
);
97 MPLS_LIST_INIT(&g
->hop_list
, ldp_hop_list
);
98 MPLS_LIST_INIT(&g
->outlabel
, ldp_outlabel
);
99 MPLS_LIST_INIT(&g
->resource
, ldp_resource
);
100 MPLS_LIST_INIT(&g
->inlabel
, ldp_inlabel
);
101 MPLS_LIST_INIT(&g
->session
, ldp_session
);
102 MPLS_LIST_INIT(&g
->nexthop
, ldp_nexthop
);
103 MPLS_LIST_INIT(&g
->tunnel
, ldp_tunnel
);
104 MPLS_LIST_INIT(&g
->entity
, ldp_entity
);
105 MPLS_LIST_INIT(&g
->attr
, ldp_attr
);
106 MPLS_LIST_INIT(&g
->peer
, ldp_peer
);
107 MPLS_LIST_INIT(&g
->fec
, ldp_fec
);
108 MPLS_LIST_INIT(&g
->adj
, ldp_adj
);
109 MPLS_LIST_INIT(&g
->iff
, ldp_if
);
111 g
->message_identifier
= 1;
112 g
->configuration_sequence_number
= 1;
113 g
->lsp_control_mode
= LDP_GLOBAL_DEF_CONTROL_MODE
;
114 g
->label_retention_mode
= LDP_GLOBAL_DEF_RETENTION_MODE
;
115 g
->lsp_repair_mode
= LDP_GLOBAL_DEF_REPAIR_MODE
;
116 g
->propagate_release
= LDP_GLOBAL_DEF_PROPOGATE_RELEASE
;
117 g
->label_merge
= LDP_GLOBAL_DEF_LABEL_MERGE
;
118 g
->loop_detection_mode
= LDP_GLOBAL_DEF_LOOP_DETECTION_MODE
;
119 g
->ttl_less_domain
= LDP_GLOBAL_DEF_TTLLESS_DOMAIN
;
120 g
->local_tcp_port
= LDP_GLOBAL_DEF_LOCAL_TCP_PORT
;
121 g
->local_udp_port
= LDP_GLOBAL_DEF_LOCAL_UDP_PORT
;
122 g
->send_address_messages
= LDP_GLOBAL_DEF_SEND_ADDR_MSG
;
123 g
->backoff_step
= LDP_GLOBAL_DEF_BACKOFF_STEP
;
124 g
->send_lsrid_mapping
= LDP_GLOBAL_DEF_SEND_LSRID_MAPPING
;
125 g
->no_route_to_peer_time
= LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME
;
127 g
->keepalive_timer
= LDP_ENTITY_DEF_KEEPALIVE_TIMER
;
128 g
->keepalive_interval
= LDP_ENTITY_DEF_KEEPALIVE_INTERVAL
;
129 g
->hellotime_timer
= LDP_ENTITY_DEF_HELLOTIME_TIMER
;
130 g
->hellotime_interval
= LDP_ENTITY_DEF_HELLOTIME_INTERVAL
;
132 g
->admin_state
= MPLS_ADMIN_DISABLE
;
135 mpls_lock_release(g
->global_lock
);
137 LDP_EXIT(g
->user_data
, "ldp_global_create");
143 mpls_return_enum
ldp_global_startup(ldp_global
* g
)
145 ldp_entity
*e
= NULL
;
148 MPLS_ASSERT(g
!= NULL
);
150 LDP_ENTER(g
->user_data
, "ldp_global_startup");
152 if (g
->lsr_identifier
.type
== MPLS_FAMILY_NONE
) {
153 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_ERROR
,
154 "ldp_global_startup: invalid LSRID\n");
155 goto ldp_global_startup_cleanup
;
158 g
->timer_handle
= mpls_timer_open(g
->user_data
);
159 if (mpls_timer_mgr_handle_verify(g
->timer_handle
) == MPLS_BOOL_FALSE
) {
160 goto ldp_global_startup_cleanup
;
163 g
->socket_handle
= mpls_socket_mgr_open(g
->user_data
);
164 if (mpls_socket_mgr_handle_verify(g
->socket_handle
) == MPLS_BOOL_FALSE
) {
165 goto ldp_global_startup_cleanup
;
168 g
->ifmgr_handle
= mpls_ifmgr_open(g
->user_data
, g
, _ldp_global_ifmgr_callback
);
169 if (mpls_ifmgr_handle_verify(g
->ifmgr_handle
) == MPLS_BOOL_FALSE
) {
170 goto ldp_global_startup_cleanup
;
173 g
->fib_handle
= mpls_fib_open(g
->user_data
, g
);
174 if (mpls_fib_handle_verify(g
->fib_handle
) == MPLS_BOOL_FALSE
) {
175 goto ldp_global_startup_cleanup
;
179 if (!g
->lsr_handle
) {
180 goto ldp_global_startup_cleanup
;
183 g
->mpls_handle
= mpls_mpls_open(g
->user_data
);
184 if (mpls_mpls_handle_verify(g
->mpls_handle
) == MPLS_BOOL_FALSE
) {
185 goto ldp_global_startup_cleanup
;
189 g
->addr_tree
= mpls_tree_create(32);
190 g
->fec_tree
= mpls_tree_create(32);
192 g
->hello_socket
= mpls_socket_create_udp(g
->socket_handle
);
193 if (mpls_socket_handle_verify(g
->socket_handle
, g
->hello_socket
) == MPLS_BOOL_FALSE
) {
194 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
195 "ldp_global_startup: error creating UDP socket\n");
196 goto ldp_global_startup_cleanup
;
199 dest
.addr
.type
= MPLS_FAMILY_IPV4
;
200 dest
.port
= g
->local_udp_port
;
201 dest
.addr
.u
.ipv4
= INADDR_ANY
;
202 // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
204 if (mpls_socket_bind(g
->socket_handle
, g
->hello_socket
, &dest
) == MPLS_FAILURE
) {
205 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
206 "ldp_global_startup: error binding UDP socket\n");
207 goto ldp_global_startup_cleanup
;
210 if (mpls_socket_options(g
->socket_handle
, g
->hello_socket
,
211 MPLS_SOCKOP_NONBLOCK
| MPLS_SOCKOP_REUSE
) == MPLS_FAILURE
) {
212 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
213 "ldp_global_startup: error setting UDP socket options\n");
214 goto ldp_global_startup_cleanup
;
216 if (mpls_socket_multicast_options(g
->socket_handle
, g
->hello_socket
, 1, 0) ==
218 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
219 "ldp_global_startup: error setting UDP socket multicast options\n");
220 goto ldp_global_startup_cleanup
;
222 mpls_socket_readlist_add(g
->socket_handle
, g
->hello_socket
, 0, MPLS_SOCKET_UDP_DATA
);
224 g
->listen_socket
= mpls_socket_create_tcp(g
->socket_handle
);
225 if (mpls_socket_handle_verify(g
->socket_handle
, g
->listen_socket
) == MPLS_BOOL_FALSE
) {
226 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
227 "ldp_global_startup: error creating TCP socket\n");
228 goto ldp_global_startup_cleanup
;
230 if (mpls_socket_options(g
->socket_handle
, g
->listen_socket
,
231 MPLS_SOCKOP_NONBLOCK
| MPLS_SOCKOP_REUSE
) == MPLS_FAILURE
) {
232 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
233 "ldp_global_startup: error setting TCP socket options\n");
234 goto ldp_global_startup_cleanup
;
237 dest
.addr
.type
= MPLS_FAMILY_IPV4
;
238 dest
.port
= g
->local_tcp_port
;
239 dest
.addr
.u
.ipv4
= INADDR_ANY
;
241 if (mpls_socket_bind(g
->socket_handle
, g
->listen_socket
, &dest
) == MPLS_FAILURE
) {
242 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
243 "ldp_global_startup: error binding TCP socket\n");
244 goto ldp_global_startup_cleanup
;
247 if (mpls_socket_tcp_listen(g
->socket_handle
, g
->listen_socket
, 15) ==
249 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
250 "ldp_global_startup: error setting listen buffer for TCP socket\n");
251 goto ldp_global_startup_cleanup
;
254 mpls_socket_readlist_add(g
->socket_handle
, g
->listen_socket
, 0,
255 MPLS_SOCKET_TCP_LISTEN
);
257 e
= MPLS_LIST_HEAD(&g
->entity
);
259 ldp_entity_startup(g
, e
);
260 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
263 g
->admin_state
= MPLS_ADMIN_ENABLE
;
265 LDP_EXIT(g
->user_data
, "ldp_global_startup");
268 ldp_global_startup_cleanup
:
269 ldp_global_shutdown(g
);
270 mpls_socket_close(g
->socket_handle
, g
->hello_socket
);
271 mpls_socket_close(g
->socket_handle
, g
->listen_socket
);
273 g
->listen_socket
= 0;
275 LDP_EXIT(g
->user_data
, "ldp_global_startup-error");
280 mpls_return_enum
ldp_global_shutdown(ldp_global
* g
)
282 ldp_entity
*e
= NULL
;
286 LDP_ENTER(g
->user_data
, "ldp_global_shutdown");
288 e
= MPLS_LIST_HEAD(&g
->entity
);
290 ldp_entity_shutdown(g
, e
, 1);
291 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
294 g
->admin_state
= MPLS_ADMIN_DISABLE
;
296 mpls_socket_readlist_del(g
->socket_handle
, g
->hello_socket
);
297 mpls_socket_close(g
->socket_handle
, g
->hello_socket
);
299 mpls_socket_readlist_del(g
->socket_handle
, g
->listen_socket
);
300 mpls_socket_close(g
->socket_handle
, g
->listen_socket
);
302 mpls_tree_delete(g
->addr_tree
);
303 mpls_tree_delete(g
->fec_tree
);
305 mpls_lock_release(g
->global_lock
);
306 mpls_timer_close(g
->timer_handle
);
307 mpls_lock_get(g
->global_lock
);
309 mpls_socket_mgr_close(g
->socket_handle
);
310 mpls_ifmgr_close(g
->ifmgr_handle
);
311 mpls_fib_close(g
->fib_handle
);
315 mpls_mpls_close(g
->mpls_handle
);
318 LDP_EXIT(g
->user_data
, "ldp_global_shutdown");
323 mpls_return_enum
ldp_global_delete(ldp_global
* g
)
326 mpls_lock_delete(g
->global_lock
);
327 LDP_PRINT(g
->user_data
, "global delete\n");
333 void _ldp_global_add_attr(ldp_global
* g
, ldp_attr
* a
)
339 ap
= MPLS_LIST_HEAD(&g
->attr
);
341 if (ap
->index
> a
->index
) {
342 MPLS_LIST_INSERT_BEFORE(&g
->attr
, ap
, a
, _global
);
345 ap
= MPLS_LIST_NEXT(&g
->attr
, ap
, _global
);
347 MPLS_LIST_ADD_TAIL(&g
->attr
, a
, _global
, ldp_attr
);
350 void _ldp_global_del_attr(ldp_global
* g
, ldp_attr
* a
)
353 MPLS_LIST_REMOVE(&g
->attr
, a
, _global
);
354 MPLS_REFCNT_RELEASE(a
, ldp_attr_delete
);
357 void _ldp_global_add_peer(ldp_global
* g
, ldp_peer
* p
)
363 pp
= MPLS_LIST_HEAD(&g
->peer
);
365 if (pp
->index
> p
->index
) {
366 MPLS_LIST_INSERT_BEFORE(&g
->peer
, pp
, p
, _global
);
369 pp
= MPLS_LIST_NEXT(&g
->peer
, pp
, _global
);
371 MPLS_LIST_ADD_TAIL(&g
->peer
, p
, _global
, ldp_peer
);
374 void _ldp_global_del_peer(ldp_global
* g
, ldp_peer
* p
)
377 MPLS_LIST_REMOVE(&g
->peer
, p
, _global
);
378 MPLS_REFCNT_RELEASE(p
, ldp_peer_delete
);
381 void _ldp_global_add_if(ldp_global
* g
, ldp_if
* i
)
387 ip
= MPLS_LIST_HEAD(&g
->iff
);
389 if (ip
->index
> i
->index
) {
390 MPLS_LIST_INSERT_BEFORE(&g
->iff
, ip
, i
, _global
);
393 ip
= MPLS_LIST_NEXT(&g
->iff
, ip
, _global
);
395 MPLS_LIST_ADD_TAIL(&g
->iff
, i
, _global
, ldp_if
);
398 void _ldp_global_del_if(ldp_global
* g
, ldp_if
* i
)
401 MPLS_LIST_REMOVE(&g
->iff
, i
, _global
);
402 MPLS_REFCNT_RELEASE(i
, ldp_if_delete
);
405 void _ldp_global_add_adj(ldp_global
* g
, ldp_adj
* a
)
411 ap
= MPLS_LIST_HEAD(&g
->adj
);
413 if (ap
->index
> a
->index
) {
414 MPLS_LIST_INSERT_BEFORE(&g
->adj
, ap
, a
, _global
);
417 ap
= MPLS_LIST_NEXT(&g
->adj
, ap
, _global
);
419 MPLS_LIST_ADD_TAIL(&g
->adj
, a
, _global
, ldp_adj
);
422 void _ldp_global_del_adj(ldp_global
* g
, ldp_adj
* a
)
425 MPLS_LIST_REMOVE(&g
->adj
, a
, _global
);
426 MPLS_REFCNT_RELEASE(a
, ldp_adj_delete
);
429 void _ldp_global_add_entity(ldp_global
* g
, ldp_entity
* e
)
431 ldp_entity
*ep
= NULL
;
435 ep
= MPLS_LIST_HEAD(&g
->entity
);
437 if (ep
->index
> e
->index
) {
438 MPLS_LIST_INSERT_BEFORE(&g
->entity
, ep
, e
, _global
);
441 ep
= MPLS_LIST_NEXT(&g
->entity
, ep
, _global
);
443 MPLS_LIST_ADD_TAIL(&g
->entity
, e
, _global
, ldp_entity
);
446 void _ldp_global_del_entity(ldp_global
* g
, ldp_entity
* e
)
449 MPLS_LIST_REMOVE(&g
->entity
, e
, _global
);
450 MPLS_REFCNT_RELEASE(e
, ldp_entity_delete
);
453 void _ldp_global_add_session(ldp_global
* g
, ldp_session
* s
)
455 ldp_session
*sp
= NULL
;
459 s
->on_global
= MPLS_BOOL_TRUE
;
460 sp
= MPLS_LIST_HEAD(&g
->session
);
462 if (sp
->index
> s
->index
) {
463 MPLS_LIST_INSERT_BEFORE(&g
->session
, sp
, s
, _global
);
466 sp
= MPLS_LIST_NEXT(&g
->session
, sp
, _global
);
468 MPLS_LIST_ADD_TAIL(&g
->session
, s
, _global
, ldp_session
);
471 void _ldp_global_del_session(ldp_global
* g
, ldp_session
* s
)
474 MPLS_ASSERT(s
->on_global
== MPLS_BOOL_TRUE
);
475 MPLS_LIST_REMOVE(&g
->session
, s
, _global
);
476 s
->on_global
= MPLS_BOOL_FALSE
;
477 MPLS_REFCNT_RELEASE(s
, ldp_session_delete
);
480 mpls_return_enum
_ldp_global_add_inlabel(ldp_global
* g
, ldp_inlabel
* i
)
482 ldp_inlabel
*ip
= NULL
;
483 mpls_return_enum result
;
490 memcpy(&iseg
.info
,&i
->info
,sizeof(mpls_insegment
));
491 result
= lsr_cfg_insegment_set(g
->lsr_handle
, &iseg
, LSR_CFG_ADD
|
492 LSR_INSEGMENT_CFG_NPOP
|LSR_INSEGMENT_CFG_FAMILY
|
493 LSR_INSEGMENT_CFG_LABELSPACE
|LSR_INSEGMENT_CFG_LABEL
|
494 LSR_INSEGMENT_CFG_OWNER
);
495 memcpy(&i
->info
, &iseg
.info
, sizeof(mpls_insegment
));
496 i
->info
.handle
= iseg
.index
;
499 result
= mpls_mpls_insegment_add(g
->mpls_handle
, &i
->info
);
501 if (result
!= MPLS_SUCCESS
) {
506 ip
= MPLS_LIST_HEAD(&g
->inlabel
);
508 if (ip
->index
> i
->index
) {
509 MPLS_LIST_INSERT_BEFORE(&g
->inlabel
, ip
, i
, _global
);
512 ip
= MPLS_LIST_NEXT(&g
->inlabel
, ip
, _global
);
514 MPLS_LIST_ADD_TAIL(&g
->inlabel
, i
, _global
, ldp_inlabel
);
518 mpls_return_enum
_ldp_global_del_inlabel(ldp_global
* g
, ldp_inlabel
* i
)
521 MPLS_ASSERT(i
->reuse_count
== 0);
525 iseg
.index
= i
->info
.handle
;
526 lsr_cfg_insegment_set(g
->lsr_handle
, &iseg
, LSR_CFG_DEL
);
529 mpls_mpls_insegment_del(g
->mpls_handle
, &i
->info
);
531 MPLS_LIST_REMOVE(&g
->inlabel
, i
, _global
);
532 MPLS_REFCNT_RELEASE(i
, ldp_inlabel_delete
);
536 mpls_return_enum
_ldp_global_add_outlabel(ldp_global
* g
, ldp_outlabel
* o
)
538 ldp_outlabel
*op
= NULL
;
539 mpls_return_enum result
;
545 memcpy(&oseg
.info
, &o
->info
, sizeof(mpls_outsegment
));
546 result
= lsr_cfg_outsegment_set(g
->lsr_handle
, &oseg
, LSR_CFG_ADD
|
547 LSR_OUTSEGMENT_CFG_PUSH_LABEL
|LSR_OUTSEGMENT_CFG_OWNER
|
548 LSR_OUTSEGMENT_CFG_INTERFACE
|LSR_OUTSEGMENT_CFG_LABEL
|
549 LSR_OUTSEGMENT_CFG_NEXTHOP
);
550 o
->info
.handle
= oseg
.index
;
553 result
= mpls_mpls_outsegment_add(g
->mpls_handle
, &o
->info
);
556 if (result
!= MPLS_SUCCESS
) {
561 o
->switching
= MPLS_BOOL_TRUE
;
562 op
= MPLS_LIST_HEAD(&g
->outlabel
);
564 if (op
->index
> o
->index
) {
565 MPLS_LIST_INSERT_BEFORE(&g
->outlabel
, op
, o
, _global
);
568 op
= MPLS_LIST_NEXT(&g
->outlabel
, op
, _global
);
570 MPLS_LIST_ADD_TAIL(&g
->outlabel
, o
, _global
, ldp_outlabel
);
574 mpls_return_enum
_ldp_global_del_outlabel(ldp_global
* g
, ldp_outlabel
* o
)
580 oseg
.index
= o
->info
.handle
;
581 lsr_cfg_outsegment_set(g
->lsr_handle
, &oseg
, LSR_CFG_DEL
);
584 mpls_mpls_outsegment_del(g
->mpls_handle
, &o
->info
);
587 o
->switching
= MPLS_BOOL_FALSE
;
588 MPLS_ASSERT(o
->merge_count
== 0);
589 MPLS_LIST_REMOVE(&g
->outlabel
, o
, _global
);
590 MPLS_REFCNT_RELEASE(o
, ldp_outlabel_delete
);
594 mpls_return_enum
ldp_global_find_attr_index(ldp_global
* g
, uint32_t index
,
599 if (g
&& index
> 0) {
601 /* because we sort our inserts by index, this lets us know
602 if we've "walked" past the end of the list */
604 a
= MPLS_LIST_TAIL(&g
->attr
);
605 if (a
== NULL
|| a
->index
< index
) {
606 return MPLS_END_OF_LIST
;
610 a
= MPLS_LIST_HEAD(&g
->attr
);
612 if (a
->index
== index
) {
616 a
= MPLS_LIST_NEXT(&g
->attr
, a
, _global
);
623 mpls_return_enum
ldp_global_find_session_index(ldp_global
* g
, uint32_t index
,
624 ldp_session
** session
)
626 ldp_session
*s
= NULL
;
628 if (g
&& index
> 0) {
630 /* because we sort our inserts by index, this lets us know
631 if we've "walked" past the end of the list */
633 s
= MPLS_LIST_TAIL(&g
->session
);
634 if (s
== NULL
|| s
->index
< index
) {
636 return MPLS_END_OF_LIST
;
639 s
= MPLS_LIST_HEAD(&g
->session
);
641 if (s
->index
== index
) {
645 s
= MPLS_LIST_NEXT(&g
->session
, s
, _global
);
652 mpls_return_enum
ldp_global_find_inlabel_index(ldp_global
* g
, uint32_t index
,
653 ldp_inlabel
** inlabel
)
655 ldp_inlabel
*i
= NULL
;
657 if (g
&& index
> 0) {
659 /* because we sort our inserts by index, this lets us know
660 if we've "walked" past the end of the list */
662 i
= MPLS_LIST_TAIL(&g
->inlabel
);
663 if (i
== NULL
|| i
->index
< index
) {
665 return MPLS_END_OF_LIST
;
668 i
= MPLS_LIST_HEAD(&g
->inlabel
);
670 if (i
->index
== index
) {
674 i
= MPLS_LIST_NEXT(&g
->inlabel
, i
, _global
);
681 mpls_return_enum
ldp_global_find_outlabel_index(ldp_global
* g
, uint32_t index
,
682 ldp_outlabel
** outlabel
)
684 ldp_outlabel
*o
= NULL
;
686 if (g
&& index
> 0) {
688 /* because we sort our inserts by index, this lets us know
689 if we've "walked" past the end of the list */
691 o
= MPLS_LIST_TAIL(&g
->outlabel
);
692 if (o
== NULL
|| o
->index
< index
) {
694 return MPLS_END_OF_LIST
;
697 o
= MPLS_LIST_HEAD(&g
->outlabel
);
699 if (o
->index
== index
) {
703 o
= MPLS_LIST_NEXT(&g
->outlabel
, o
, _global
);
710 ldp_outlabel
*ldp_global_find_outlabel_handle(ldp_global
* g
,
711 mpls_outsegment_handle handle
)
713 ldp_outlabel
*o
= MPLS_LIST_HEAD(&g
->outlabel
);
717 if (!mpls_outsegment_handle_compare(o
->info
.handle
, handle
))
720 o
= MPLS_LIST_NEXT(&g
->outlabel
, o
, _global
);
726 mpls_return_enum
ldp_global_find_entity_index(ldp_global
* g
, uint32_t index
,
727 ldp_entity
** entity
)
729 ldp_entity
*e
= NULL
;
731 if (g
&& index
> 0) {
733 /* because we sort our inserts by index, this lets us know
734 if we've "walked" past the end of the list */
736 e
= MPLS_LIST_TAIL(&g
->entity
);
737 if (e
== NULL
|| e
->index
< index
) {
739 return MPLS_END_OF_LIST
;
742 e
= MPLS_LIST_HEAD(&g
->entity
);
744 if (e
->index
== index
) {
748 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
755 ldp_peer
*ldp_global_find_peer_addr(ldp_global
* g
, mpls_inet_addr
* addr
)
759 MPLS_ASSERT(g
&& addr
);
761 /* JLEU: we will need to add a tree to optimize this search,
762 known peers will be in tree, unknown will take a "slow path" to
763 verify them, then be added to tree */
765 p
= MPLS_LIST_HEAD(&g
->peer
);
767 LDP_PRINT(g
->user_data
,
768 "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
769 p
->dest
.addr
.u
.ipv4
, addr
->u
.ipv4
);
770 if (!mpls_inet_addr_compare(&p
->dest
.addr
, addr
)) {
773 p
= MPLS_LIST_NEXT(&g
->peer
, p
, _global
);
778 mpls_return_enum
ldp_global_find_adj_index(ldp_global
* g
, uint32_t index
,
783 if (g
&& index
> 0) {
784 /* because we sort our inserts by index, this lets us know
785 if we've "walked" past the end of the list */
787 a
= MPLS_LIST_TAIL(&g
->adj
);
788 if (a
== NULL
|| a
->index
< index
) {
789 return MPLS_END_OF_LIST
;
793 a
= MPLS_LIST_HEAD(&g
->adj
);
795 if (a
->index
== index
) {
799 a
= MPLS_LIST_NEXT(&g
->adj
, a
, _global
);
806 mpls_return_enum
ldp_global_find_peer_index(ldp_global
* g
, uint32_t index
,
811 if (g
&& index
> 0) {
812 /* because we sort our inserts by index, this lets us know
813 if we've "walked" past the end of the list */
815 p
= MPLS_LIST_TAIL(&g
->peer
);
816 if (p
== NULL
|| p
->index
< index
) {
818 return MPLS_END_OF_LIST
;
821 p
= MPLS_LIST_HEAD(&g
->peer
);
823 if (p
->index
== index
) {
827 p
= MPLS_LIST_NEXT(&g
->peer
, p
, _global
);
834 mpls_return_enum
ldp_global_find_fec_index(ldp_global
* g
, uint32_t index
,
839 if (g
&& index
> 0) {
840 /* because we sort our inserts by index, this lets us know
841 if we've "walked" past the end of the list */
843 f
= MPLS_LIST_TAIL(&g
->fec
);
844 if (f
== NULL
|| f
->index
< index
) {
846 return MPLS_END_OF_LIST
;
849 f
= MPLS_LIST_HEAD(&g
->fec
);
851 if (f
->index
== index
) {
855 f
= MPLS_LIST_NEXT(&g
->fec
, f
, _global
);
862 mpls_return_enum
ldp_global_find_fec(ldp_global
* g
, mpls_fec
* m
,
869 f
= MPLS_LIST_HEAD(&g
->fec
);
871 if (!mpls_fec_compare(m
, &f
->info
)) {
875 } while((f
= MPLS_LIST_NEXT(&g
->fec
, f
, _global
)));
880 mpls_return_enum
ldp_global_find_if_index(ldp_global
* g
, uint32_t index
,
885 if (g
&& index
> 0) {
887 /* because we sort our inserts by index, this lets us know
888 if we've "walked" past the end of the list */
890 i
= MPLS_LIST_TAIL(&g
->iff
);
891 if (i
== NULL
|| i
->index
< index
) {
893 return MPLS_END_OF_LIST
;
896 i
= MPLS_LIST_HEAD(&g
->iff
);
898 if (i
->index
== index
) {
902 i
= MPLS_LIST_NEXT(&g
->iff
, i
, _global
);
909 ldp_if
*ldp_global_find_if_handle(ldp_global
* g
, mpls_if_handle handle
)
911 ldp_if
*i
= MPLS_LIST_HEAD(&g
->iff
);
915 if (!mpls_if_handle_compare(i
->handle
, handle
))
918 i
= MPLS_LIST_NEXT(&g
->iff
, i
, _global
);
924 ldp_adj
*ldp_global_find_adj_ldpid(ldp_global
* g
, mpls_inet_addr
* lsraddr
,
928 ldp_adj
*a
= MPLS_LIST_HEAD(&g
->adj
);
931 if ((!mpls_inet_addr_compare(lsraddr
, &a
->remote_lsr_address
)) &&
932 labelspace
== a
->remote_label_space
)
935 a
= MPLS_LIST_NEXT(&g
->adj
, a
, _global
);
940 mpls_return_enum
ldp_global_find_tunnel_index(ldp_global
* g
, uint32_t index
,
941 ldp_tunnel
** tunnel
)
943 ldp_tunnel
*t
= NULL
;
945 if (g
&& index
> 0) {
946 /* because we sort our inserts by index, this lets us know
947 if we've "walked" past the end of the list */
949 t
= MPLS_LIST_TAIL(&g
->tunnel
);
950 if (t
== NULL
|| t
->index
< index
) {
952 return MPLS_END_OF_LIST
;
955 t
= MPLS_LIST_HEAD(&g
->tunnel
);
957 if (t
->index
== index
) {
961 t
= MPLS_LIST_NEXT(&g
->tunnel
, t
, _global
);
968 mpls_return_enum
ldp_global_find_resource_index(ldp_global
* g
, uint32_t index
,
969 ldp_resource
** resource
)
971 ldp_resource
*r
= NULL
;
973 if (g
&& index
> 0) {
974 /* because we sort our inserts by index, this lets us know
975 if we've "walked" past the end of the list */
977 r
= MPLS_LIST_TAIL(&g
->resource
);
978 if (r
== NULL
|| r
->index
< index
) {
980 return MPLS_END_OF_LIST
;
983 r
= MPLS_LIST_HEAD(&g
->resource
);
985 if (r
->index
== index
) {
989 r
= MPLS_LIST_NEXT(&g
->resource
, r
, _global
);
996 mpls_return_enum
ldp_global_find_hop_list_index(ldp_global
* g
, uint32_t index
,
997 ldp_hop_list
** hop_list
)
999 ldp_hop_list
*h
= NULL
;
1001 if (g
&& index
> 0) {
1002 /* because we sort our inserts by index, this lets us know
1003 if we've "walked" past the end of the list */
1005 h
= MPLS_LIST_TAIL(&g
->hop_list
);
1006 if (h
== NULL
|| h
->index
< index
) {
1008 return MPLS_END_OF_LIST
;
1011 h
= MPLS_LIST_HEAD(&g
->hop_list
);
1013 if (h
->index
== index
) {
1015 return MPLS_SUCCESS
;
1017 h
= MPLS_LIST_NEXT(&g
->hop_list
, h
, _global
);
1021 return MPLS_FAILURE
;
1024 void _ldp_global_add_tunnel(ldp_global
* g
, ldp_tunnel
* t
)
1026 ldp_tunnel
*tp
= NULL
;
1028 MPLS_ASSERT(g
&& t
);
1029 MPLS_REFCNT_HOLD(t
);
1030 tp
= MPLS_LIST_HEAD(&g
->tunnel
);
1031 while (tp
!= NULL
) {
1032 if (tp
->index
> t
->index
) {
1033 MPLS_LIST_INSERT_BEFORE(&g
->tunnel
, tp
, t
, _global
);
1036 tp
= MPLS_LIST_NEXT(&g
->tunnel
, tp
, _global
);
1038 MPLS_LIST_ADD_TAIL(&g
->tunnel
, t
, _global
, ldp_tunnel
);
1041 void _ldp_global_del_tunnel(ldp_global
* g
, ldp_tunnel
* t
)
1043 MPLS_ASSERT(g
&& t
);
1044 MPLS_LIST_REMOVE(&g
->tunnel
, t
, _global
);
1045 MPLS_REFCNT_RELEASE(t
, ldp_tunnel_delete
);
1048 void _ldp_global_add_resource(ldp_global
* g
, ldp_resource
* r
)
1050 ldp_resource
*rp
= NULL
;
1052 MPLS_ASSERT(g
&& r
);
1053 MPLS_REFCNT_HOLD(r
);
1054 rp
= MPLS_LIST_HEAD(&g
->resource
);
1055 while (rp
!= NULL
) {
1056 if (rp
->index
> r
->index
) {
1057 MPLS_LIST_INSERT_BEFORE(&g
->resource
, rp
, r
, _global
);
1060 rp
= MPLS_LIST_NEXT(&g
->resource
, rp
, _global
);
1062 MPLS_LIST_ADD_TAIL(&g
->resource
, r
, _global
, ldp_resource
);
1065 void _ldp_global_del_resource(ldp_global
* g
, ldp_resource
* r
)
1067 MPLS_ASSERT(g
&& r
);
1068 MPLS_LIST_REMOVE(&g
->resource
, r
, _global
);
1069 MPLS_REFCNT_RELEASE(r
, ldp_resource_delete
);
1072 void _ldp_global_add_hop_list(ldp_global
* g
, ldp_hop_list
* h
)
1074 ldp_hop_list
*hp
= NULL
;
1076 MPLS_ASSERT(g
&& h
);
1077 MPLS_REFCNT_HOLD(h
);
1078 hp
= MPLS_LIST_HEAD(&g
->hop_list
);
1079 while (hp
!= NULL
) {
1080 if (hp
->index
> h
->index
) {
1081 MPLS_LIST_INSERT_BEFORE(&g
->hop_list
, hp
, h
, _global
);
1084 hp
= MPLS_LIST_NEXT(&g
->hop_list
, hp
, _global
);
1086 MPLS_LIST_ADD_TAIL(&g
->hop_list
, h
, _global
, ldp_hop_list
);
1089 void _ldp_global_del_hop_list(ldp_global
* g
, ldp_hop_list
* h
)
1091 MPLS_ASSERT(g
&& h
);
1092 MPLS_LIST_REMOVE(&g
->hop_list
, h
, _global
);
1093 MPLS_REFCNT_RELEASE(h
, ldp_hop_list_delete
);
1096 void _ldp_global_add_fec(ldp_global
* g
, ldp_fec
* f
)
1100 MPLS_ASSERT(g
&& f
);
1101 MPLS_REFCNT_HOLD(f
);
1102 fp
= MPLS_LIST_HEAD(&g
->fec
);
1103 while (fp
!= NULL
) {
1104 if (fp
->index
> f
->index
) {
1105 MPLS_LIST_INSERT_BEFORE(&g
->fec
, fp
, f
, _global
);
1108 fp
= MPLS_LIST_NEXT(&g
->fec
, fp
, _global
);
1110 MPLS_LIST_ADD_TAIL(&g
->fec
, f
, _global
, ldp_fec
);
1113 void _ldp_global_del_fec(ldp_global
* g
, ldp_fec
* f
)
1115 MPLS_ASSERT(g
&& f
);
1116 MPLS_LIST_REMOVE(&g
->fec
, f
, _global
);
1117 MPLS_REFCNT_RELEASE(f
, ldp_fec_delete
);
1120 void _ldp_global_add_nexthop(ldp_global
* g
, ldp_nexthop
* nh
)
1122 ldp_nexthop
*nhp
= NULL
;
1124 MPLS_ASSERT(g
&& nh
);
1125 MPLS_REFCNT_HOLD(nh
);
1126 nhp
= MPLS_LIST_HEAD(&g
->nexthop
);
1127 while (nhp
!= NULL
) {
1128 if (nhp
->index
> nh
->index
) {
1129 MPLS_LIST_INSERT_BEFORE(&g
->nexthop
, nhp
, nh
, _global
);
1132 nhp
= MPLS_LIST_NEXT(&g
->nexthop
, nhp
, _global
);
1134 MPLS_LIST_ADD_TAIL(&g
->nexthop
, nh
, _global
, ldp_nexthop
);
1137 void _ldp_global_del_nexthop(ldp_global
* g
, ldp_nexthop
* nh
)
1139 MPLS_ASSERT(g
&& nh
);
1140 MPLS_LIST_REMOVE(&g
->nexthop
, nh
, _global
);
1141 MPLS_REFCNT_RELEASE(nh
, ldp_nexthop_delete
);