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_outlabel.h"
18 #include "ldp_inlabel.h"
19 #include "ldp_hello.h"
26 #include "ldp_label_mapping.h"
27 #include "ldp_tunnel.h"
28 #include "ldp_resource.h"
29 #include "ldp_hop_list.h"
31 #include "mpls_socket_impl.h"
32 #include "mpls_timer_impl.h"
33 #include "mpls_ifmgr_impl.h"
34 #include "mpls_tree_impl.h"
35 #include "mpls_lock_impl.h"
36 #include "mpls_fib_impl.h"
37 #include "mpls_policy_impl.h"
38 #include "mpls_mm_impl.h"
39 #include "mpls_trace_impl.h"
44 #include "mpls_mpls_impl.h"
47 void _ldp_global_fib_callback(mpls_cfg_handle handle
, mpls_update_enum type
,
50 ldp_session
*session
= NULL
;
51 ldp_global
*cfg
= (ldp_global
*)handle
;
53 LDP_ENTER(cfg
->user_data
, "_ldp_global_fib_callback");
55 mpls_lock_get(cfg
->global_lock
);
57 if (dest
->nh
.type
& MPLS_NH_IP
) {
58 session
= ldp_get_session_by_next_hop(cfg
, &dest
->nh
, NULL
);
63 Recognize_New_Fec(cfg
, dest
);
66 case MPLS_UPDATE_MODIFY
:
68 Detect_Change_Fec_Next_Hop(cfg
, dest
, session
);
75 mpls_lock_release(cfg
->global_lock
);
77 LDP_EXIT(cfg
->user_data
, "_ldp_global_fib_callback");
80 void _ldp_global_ifmgr_callback(mpls_cfg_handle handle
, const mpls_update_enum type
, mpls_inet_addr
*addr
)
82 ldp_session
*s
= NULL
;
83 ldp_global
*cfg
= (ldp_global
*)handle
;
85 LDP_ENTER(cfg
->user_data
, "_ldp_global_ifmgr_callback");
87 mpls_lock_get(cfg
->global_lock
);
89 if (mpls_policy_address_export_check(cfg
->user_data
, addr
) == MPLS_BOOL_TRUE
) {
90 s
= MPLS_LIST_HEAD(&cfg
->session
);
94 LDP_TRACE_LOG(cfg
->user_data
, MPLS_TRACE_STATE_ALL
,
95 LDP_TRACE_FLAG_EVENT
, "ADD\n");
96 ldp_addr_send(cfg
, s
, addr
);
99 LDP_TRACE_LOG(cfg
->user_data
, MPLS_TRACE_STATE_ALL
,
100 LDP_TRACE_FLAG_EVENT
, "DEL\n");
101 ldp_waddr_send(cfg
, s
, addr
);
106 s
= MPLS_LIST_NEXT(&cfg
->session
, s
, _global
);
110 mpls_lock_release(cfg
->global_lock
);
112 LDP_EXIT(cfg
->user_data
, "_ldp_global_ifmgr_callback");
115 ldp_global
*ldp_global_create(mpls_instance_handle data
)
117 ldp_global
*g
= (ldp_global
*) mpls_malloc(sizeof(ldp_global
));
120 memset(g
, 0, sizeof(ldp_global
));
122 LDP_ENTER(g
->user_data
, "ldp_global_create");
124 g
->global_lock
= mpls_lock_create("_ldp_global_lock_");
125 mpls_lock_get(g
->global_lock
);
127 MPLS_LIST_INIT(&g
->hop_list
, ldp_hop_list
);
128 MPLS_LIST_INIT(&g
->outlabel
, ldp_outlabel
);
129 MPLS_LIST_INIT(&g
->resource
, ldp_resource
);
130 MPLS_LIST_INIT(&g
->inlabel
, ldp_inlabel
);
131 MPLS_LIST_INIT(&g
->session
, ldp_session
);
132 MPLS_LIST_INIT(&g
->tunnel
, ldp_tunnel
);
133 MPLS_LIST_INIT(&g
->entity
, ldp_entity
);
134 MPLS_LIST_INIT(&g
->attr
, ldp_attr
);
135 MPLS_LIST_INIT(&g
->peer
, ldp_peer
);
136 MPLS_LIST_INIT(&g
->adj
, ldp_adj
);
137 MPLS_LIST_INIT(&g
->iff
, ldp_if
);
139 g
->message_identifier
= 1;
140 g
->configuration_sequence_number
= 1;
141 g
->lsp_control_mode
= LDP_GLOBAL_DEF_CONTROL_MODE
;
142 g
->label_retention_mode
= LDP_GLOBAL_DEF_RETENTION_MODE
;
143 g
->lsp_repair_mode
= LDP_GLOBAL_DEF_REPAIR_MODE
;
144 g
->propagate_release
= LDP_GLOBAL_DEF_PROPOGATE_RELEASE
;
145 g
->label_merge
= LDP_GLOBAL_DEF_LABEL_MERGE
;
146 g
->loop_detection_mode
= LDP_GLOBAL_DEF_LOOP_DETECTION_MODE
;
147 g
->ttl_less_domain
= LDP_GLOBAL_DEF_TTLLESS_DOMAIN
;
148 g
->local_tcp_port
= LDP_GLOBAL_DEF_LOCAL_TCP_PORT
;
149 g
->local_udp_port
= LDP_GLOBAL_DEF_LOCAL_UDP_PORT
;
150 g
->send_address_messages
= LDP_GLOBAL_DEF_SEND_ADDR_MSG
;
151 g
->backoff_step
= LDP_GLOBAL_DEF_BACKOFF_STEP
;
152 g
->send_lsrid_mapping
= LDP_GLOBAL_DEF_SEND_LSRID_MAPPING
;
153 g
->no_route_to_peer_time
= LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME
;
155 g
->keepalive_timer
= LDP_ENTITY_DEF_KEEPALIVE_TIMER
;
156 g
->keepalive_interval
= LDP_ENTITY_DEF_KEEPALIVE_INTERVAL
;
157 g
->hellotime_timer
= LDP_ENTITY_DEF_HELLOTIME_TIMER
;
158 g
->hellotime_interval
= LDP_ENTITY_DEF_HELLOTIME_INTERVAL
;
160 g
->admin_state
= MPLS_ADMIN_DISABLE
;
163 mpls_lock_release(g
->global_lock
);
165 LDP_EXIT(g
->user_data
, "ldp_global_create");
171 mpls_return_enum
ldp_global_startup(ldp_global
* g
)
173 ldp_entity
*e
= NULL
;
176 MPLS_ASSERT(g
!= NULL
);
178 LDP_ENTER(g
->user_data
, "ldp_global_startup");
180 if (g
->lsr_identifier
.type
== MPLS_FAMILY_NONE
) {
181 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_ERROR
,
182 "ldp_global_startup: invalid LSRID\n");
183 goto ldp_global_startup_cleanup
;
186 g
->timer_handle
= mpls_timer_open(g
->user_data
);
187 if (mpls_timer_mgr_handle_verify(g
->timer_handle
) == MPLS_BOOL_FALSE
) {
188 goto ldp_global_startup_cleanup
;
191 g
->socket_handle
= mpls_socket_mgr_open(g
->user_data
);
192 if (mpls_socket_mgr_handle_verify(g
->socket_handle
) == MPLS_BOOL_FALSE
) {
193 goto ldp_global_startup_cleanup
;
196 g
->ifmgr_handle
= mpls_ifmgr_open(g
->user_data
, g
, _ldp_global_ifmgr_callback
);
197 if (mpls_ifmgr_handle_verify(g
->ifmgr_handle
) == MPLS_BOOL_FALSE
) {
198 goto ldp_global_startup_cleanup
;
201 g
->fib_handle
= mpls_fib_open(g
->user_data
, g
, _ldp_global_fib_callback
);
202 if (mpls_fib_handle_verify(g
->fib_handle
) == MPLS_BOOL_FALSE
) {
203 goto ldp_global_startup_cleanup
;
207 if (!g
->lsr_handle
) {
208 goto ldp_global_startup_cleanup
;
211 g
->mpls_handle
= mpls_mpls_open(g
->user_data
);
212 if (mpls_mpls_handle_verify(g
->mpls_handle
) == MPLS_BOOL_FALSE
) {
213 goto ldp_global_startup_cleanup
;
217 g
->addr_tree
= mpls_tree_create(32);
218 g
->fec_tree
= mpls_tree_create(32);
220 g
->hello_socket
= mpls_socket_create_udp(g
->socket_handle
);
221 if (mpls_socket_handle_verify(g
->socket_handle
, g
->hello_socket
) == MPLS_BOOL_FALSE
) {
222 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
223 "ldp_global_startup: error creating UDP socket\n");
224 goto ldp_global_startup_cleanup
;
227 dest
.addr
.type
= MPLS_FAMILY_IPV4
;
228 dest
.port
= g
->local_udp_port
;
229 dest
.addr
.u
.ipv4
= INADDR_ANY
;
230 // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
232 if (mpls_socket_bind(g
->socket_handle
, g
->hello_socket
, &dest
) == MPLS_FAILURE
) {
233 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
234 "ldp_global_startup: error binding UDP socket\n");
235 goto ldp_global_startup_cleanup
;
238 if (mpls_socket_options(g
->socket_handle
, g
->hello_socket
,
239 MPLS_SOCKOP_NONBLOCK
| MPLS_SOCKOP_REUSE
) == MPLS_FAILURE
) {
240 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
241 "ldp_global_startup: error setting UDP socket options\n");
242 goto ldp_global_startup_cleanup
;
244 if (mpls_socket_multicast_options(g
->socket_handle
, g
->hello_socket
, 1, 0) ==
246 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
247 "ldp_global_startup: error setting UDP socket multicast options\n");
248 goto ldp_global_startup_cleanup
;
250 mpls_socket_readlist_add(g
->socket_handle
, g
->hello_socket
, 0, MPLS_SOCKET_UDP_DATA
);
252 g
->listen_socket
= mpls_socket_create_tcp(g
->socket_handle
);
253 if (mpls_socket_handle_verify(g
->socket_handle
, g
->listen_socket
) == MPLS_BOOL_FALSE
) {
254 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
255 "ldp_global_startup: error creating TCP socket\n");
256 goto ldp_global_startup_cleanup
;
258 if (mpls_socket_options(g
->socket_handle
, g
->listen_socket
,
259 MPLS_SOCKOP_NONBLOCK
| MPLS_SOCKOP_REUSE
) == MPLS_FAILURE
) {
260 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
261 "ldp_global_startup: error setting TCP socket options\n");
262 goto ldp_global_startup_cleanup
;
265 dest
.addr
.type
= MPLS_FAMILY_IPV4
;
266 dest
.port
= g
->local_tcp_port
;
267 dest
.addr
.u
.ipv4
= INADDR_ANY
;
269 if (mpls_socket_bind(g
->socket_handle
, g
->listen_socket
, &dest
) == MPLS_FAILURE
) {
270 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
271 "ldp_global_startup: error binding TCP socket\n");
272 goto ldp_global_startup_cleanup
;
275 if (mpls_socket_tcp_listen(g
->socket_handle
, g
->listen_socket
, 15) ==
277 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
278 "ldp_global_startup: error setting listen buffer for TCP socket\n");
279 goto ldp_global_startup_cleanup
;
282 mpls_socket_readlist_add(g
->socket_handle
, g
->listen_socket
, 0,
283 MPLS_SOCKET_TCP_LISTEN
);
285 e
= MPLS_LIST_HEAD(&g
->entity
);
287 ldp_entity_startup(g
, e
);
288 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
291 g
->admin_state
= MPLS_ADMIN_ENABLE
;
293 LDP_EXIT(g
->user_data
, "ldp_global_startup");
296 ldp_global_startup_cleanup
:
297 ldp_global_shutdown(g
);
298 mpls_socket_close(g
->socket_handle
, g
->hello_socket
);
299 mpls_socket_close(g
->socket_handle
, g
->listen_socket
);
301 g
->listen_socket
= 0;
303 LDP_EXIT(g
->user_data
, "ldp_global_startup-error");
308 mpls_return_enum
ldp_global_shutdown(ldp_global
* g
)
310 ldp_entity
*e
= NULL
;
314 LDP_ENTER(g
->user_data
, "ldp_global_shutdown");
316 e
= MPLS_LIST_HEAD(&g
->entity
);
318 ldp_entity_shutdown(g
, e
, 1);
319 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
322 g
->admin_state
= MPLS_ADMIN_DISABLE
;
324 mpls_socket_readlist_del(g
->socket_handle
, g
->hello_socket
);
325 mpls_socket_close(g
->socket_handle
, g
->hello_socket
);
327 mpls_socket_readlist_del(g
->socket_handle
, g
->listen_socket
);
328 mpls_socket_close(g
->socket_handle
, g
->listen_socket
);
330 mpls_tree_delete(g
->addr_tree
);
331 mpls_tree_delete(g
->fec_tree
);
333 mpls_lock_release(g
->global_lock
);
334 mpls_timer_close(g
->timer_handle
);
335 mpls_lock_get(g
->global_lock
);
337 mpls_socket_mgr_close(g
->socket_handle
);
338 mpls_ifmgr_close(g
->ifmgr_handle
);
339 mpls_fib_close(g
->fib_handle
);
343 mpls_mpls_close(g
->mpls_handle
);
346 LDP_EXIT(g
->user_data
, "ldp_global_shutdown");
351 mpls_return_enum
ldp_global_delete(ldp_global
* g
)
354 mpls_lock_delete(g
->global_lock
);
355 LDP_PRINT(g
->user_data
, "global delete\n");
361 void _ldp_global_add_attr(ldp_global
* g
, ldp_attr
* a
)
367 ap
= MPLS_LIST_HEAD(&g
->attr
);
369 if (ap
->index
> a
->index
) {
370 MPLS_LIST_INSERT_BEFORE(&g
->attr
, ap
, a
, _global
);
373 ap
= MPLS_LIST_NEXT(&g
->attr
, ap
, _global
);
375 MPLS_LIST_ADD_TAIL(&g
->attr
, a
, _global
, ldp_attr
);
378 void _ldp_global_del_attr(ldp_global
* g
, ldp_attr
* a
)
381 MPLS_LIST_REMOVE(&g
->attr
, a
, _global
);
382 MPLS_REFCNT_RELEASE(a
, ldp_attr_delete
);
385 void _ldp_global_add_peer(ldp_global
* g
, ldp_peer
* p
)
391 pp
= MPLS_LIST_HEAD(&g
->peer
);
393 if (pp
->index
> p
->index
) {
394 MPLS_LIST_INSERT_BEFORE(&g
->peer
, pp
, p
, _global
);
397 pp
= MPLS_LIST_NEXT(&g
->peer
, pp
, _global
);
399 MPLS_LIST_ADD_TAIL(&g
->peer
, p
, _global
, ldp_peer
);
402 void _ldp_global_del_peer(ldp_global
* g
, ldp_peer
* p
)
405 MPLS_LIST_REMOVE(&g
->peer
, p
, _global
);
406 MPLS_REFCNT_RELEASE(p
, ldp_peer_delete
);
409 void _ldp_global_add_if(ldp_global
* g
, ldp_if
* i
)
415 ip
= MPLS_LIST_HEAD(&g
->iff
);
417 if (ip
->index
> i
->index
) {
418 MPLS_LIST_INSERT_BEFORE(&g
->iff
, ip
, i
, _global
);
421 ip
= MPLS_LIST_NEXT(&g
->iff
, ip
, _global
);
423 MPLS_LIST_ADD_TAIL(&g
->iff
, i
, _global
, ldp_if
);
426 void _ldp_global_del_if(ldp_global
* g
, ldp_if
* i
)
429 MPLS_LIST_REMOVE(&g
->iff
, i
, _global
);
430 MPLS_REFCNT_RELEASE(i
, ldp_if_delete
);
433 void _ldp_global_add_adj(ldp_global
* g
, ldp_adj
* a
)
439 ap
= MPLS_LIST_HEAD(&g
->adj
);
441 if (ap
->index
> a
->index
) {
442 MPLS_LIST_INSERT_BEFORE(&g
->adj
, ap
, a
, _global
);
445 ap
= MPLS_LIST_NEXT(&g
->adj
, ap
, _global
);
447 MPLS_LIST_ADD_TAIL(&g
->adj
, a
, _global
, ldp_adj
);
450 void _ldp_global_del_adj(ldp_global
* g
, ldp_adj
* a
)
453 MPLS_LIST_REMOVE(&g
->adj
, a
, _global
);
454 MPLS_REFCNT_RELEASE(a
, ldp_adj_delete
);
457 void _ldp_global_add_entity(ldp_global
* g
, ldp_entity
* e
)
459 ldp_entity
*ep
= NULL
;
463 ep
= MPLS_LIST_HEAD(&g
->entity
);
465 if (ep
->index
> e
->index
) {
466 MPLS_LIST_INSERT_BEFORE(&g
->entity
, ep
, e
, _global
);
469 ep
= MPLS_LIST_NEXT(&g
->entity
, ep
, _global
);
471 MPLS_LIST_ADD_TAIL(&g
->entity
, e
, _global
, ldp_entity
);
474 void _ldp_global_del_entity(ldp_global
* g
, ldp_entity
* e
)
477 MPLS_LIST_REMOVE(&g
->entity
, e
, _global
);
478 MPLS_REFCNT_RELEASE(e
, ldp_entity_delete
);
481 void _ldp_global_add_session(ldp_global
* g
, ldp_session
* s
)
483 ldp_session
*sp
= NULL
;
487 s
->on_global
= MPLS_BOOL_TRUE
;
488 sp
= MPLS_LIST_HEAD(&g
->session
);
490 if (sp
->index
> s
->index
) {
491 MPLS_LIST_INSERT_BEFORE(&g
->session
, sp
, s
, _global
);
494 sp
= MPLS_LIST_NEXT(&g
->session
, sp
, _global
);
496 MPLS_LIST_ADD_TAIL(&g
->session
, s
, _global
, ldp_session
);
499 void _ldp_global_del_session(ldp_global
* g
, ldp_session
* s
)
502 MPLS_ASSERT(s
->on_global
== MPLS_BOOL_TRUE
);
503 MPLS_LIST_REMOVE(&g
->session
, s
, _global
);
504 s
->on_global
= MPLS_BOOL_FALSE
;
505 MPLS_REFCNT_RELEASE(s
, ldp_session_delete
);
508 mpls_return_enum
_ldp_global_add_inlabel(ldp_global
* g
, ldp_inlabel
* i
)
510 ldp_inlabel
*ip
= NULL
;
511 mpls_return_enum result
;
518 memcpy(&iseg
.info
,&i
->info
,sizeof(mpls_insegment
));
519 result
= lsr_cfg_insegment_set(g
->lsr_handle
, &iseg
, LSR_CFG_ADD
|
520 LSR_INSEGMENT_CFG_NPOP
|LSR_INSEGMENT_CFG_FAMILY
|
521 LSR_INSEGMENT_CFG_LABELSPACE
|LSR_INSEGMENT_CFG_LABEL
|
522 LSR_INSEGMENT_CFG_OWNER
);
523 memcpy(&i
->info
, &iseg
.info
, sizeof(mpls_insegment
));
524 i
->info
.handle
= iseg
.index
;
527 result
= mpls_mpls_insegment_add(g
->mpls_handle
, &i
->info
);
529 if (result
!= MPLS_SUCCESS
) {
534 ip
= MPLS_LIST_HEAD(&g
->inlabel
);
536 if (ip
->index
> i
->index
) {
537 MPLS_LIST_INSERT_BEFORE(&g
->inlabel
, ip
, i
, _global
);
540 ip
= MPLS_LIST_NEXT(&g
->inlabel
, ip
, _global
);
542 MPLS_LIST_ADD_TAIL(&g
->inlabel
, i
, _global
, ldp_inlabel
);
546 mpls_return_enum
_ldp_global_del_inlabel(ldp_global
* g
, ldp_inlabel
* i
)
549 MPLS_ASSERT(i
->reuse_count
== 0);
553 iseg
.index
= i
->info
.handle
;
554 lsr_cfg_insegment_set(g
->lsr_handle
, &iseg
, LSR_CFG_DEL
);
557 mpls_mpls_insegment_del(g
->mpls_handle
, &i
->info
);
559 MPLS_LIST_REMOVE(&g
->inlabel
, i
, _global
);
560 MPLS_REFCNT_RELEASE(i
, ldp_inlabel_delete
);
564 mpls_return_enum
_ldp_global_add_outlabel(ldp_global
* g
, ldp_outlabel
* o
)
566 ldp_outlabel
*op
= NULL
;
567 mpls_return_enum result
;
573 memcpy(&oseg
.info
, &o
->info
, sizeof(mpls_outsegment
));
574 result
= lsr_cfg_outsegment_set(g
->lsr_handle
, &oseg
, LSR_CFG_ADD
|
575 LSR_OUTSEGMENT_CFG_PUSH_LABEL
|LSR_OUTSEGMENT_CFG_OWNER
|
576 LSR_OUTSEGMENT_CFG_INTERFACE
|LSR_OUTSEGMENT_CFG_LABEL
|
577 LSR_OUTSEGMENT_CFG_NEXTHOP
);
578 o
->info
.handle
= oseg
.index
;
581 result
= mpls_mpls_outsegment_add(g
->mpls_handle
, &o
->info
);
584 if (result
!= MPLS_SUCCESS
) {
589 o
->switching
= MPLS_BOOL_TRUE
;
590 op
= MPLS_LIST_HEAD(&g
->outlabel
);
592 if (op
->index
> o
->index
) {
593 MPLS_LIST_INSERT_BEFORE(&g
->outlabel
, op
, o
, _global
);
596 op
= MPLS_LIST_NEXT(&g
->outlabel
, op
, _global
);
598 MPLS_LIST_ADD_TAIL(&g
->outlabel
, o
, _global
, ldp_outlabel
);
602 mpls_return_enum
_ldp_global_del_outlabel(ldp_global
* g
, ldp_outlabel
* o
)
608 oseg
.index
= o
->info
.handle
;
609 lsr_cfg_outsegment_set(g
->lsr_handle
, &oseg
, LSR_CFG_DEL
);
612 mpls_mpls_outsegment_del(g
->mpls_handle
, &o
->info
);
615 o
->switching
= MPLS_BOOL_FALSE
;
616 MPLS_ASSERT(o
->merge_count
== 0);
617 MPLS_LIST_REMOVE(&g
->outlabel
, o
, _global
);
618 MPLS_REFCNT_RELEASE(o
, ldp_outlabel_delete
);
622 mpls_return_enum
ldp_global_find_attr_index(ldp_global
* g
, uint32_t index
,
627 if (g
&& index
> 0) {
629 /* because we sort our inserts by index, this lets us know
630 if we've "walked" past the end of the list */
632 a
= MPLS_LIST_TAIL(&g
->attr
);
633 if (a
== NULL
|| a
->index
< index
) {
634 return MPLS_END_OF_LIST
;
638 a
= MPLS_LIST_HEAD(&g
->attr
);
640 if (a
->index
== index
) {
644 a
= MPLS_LIST_NEXT(&g
->attr
, a
, _global
);
651 mpls_return_enum
ldp_global_find_session_index(ldp_global
* g
, uint32_t index
,
652 ldp_session
** session
)
654 ldp_session
*s
= NULL
;
656 if (g
&& index
> 0) {
658 /* because we sort our inserts by index, this lets us know
659 if we've "walked" past the end of the list */
661 s
= MPLS_LIST_TAIL(&g
->session
);
662 if (s
== NULL
|| s
->index
< index
) {
664 return MPLS_END_OF_LIST
;
667 s
= MPLS_LIST_HEAD(&g
->session
);
669 if (s
->index
== index
) {
673 s
= MPLS_LIST_NEXT(&g
->session
, s
, _global
);
680 mpls_return_enum
ldp_global_find_inlabel_index(ldp_global
* g
, uint32_t index
,
681 ldp_inlabel
** inlabel
)
683 ldp_inlabel
*i
= NULL
;
685 if (g
&& index
> 0) {
687 /* because we sort our inserts by index, this lets us know
688 if we've "walked" past the end of the list */
690 i
= MPLS_LIST_TAIL(&g
->inlabel
);
691 if (i
== NULL
|| i
->index
< index
) {
693 return MPLS_END_OF_LIST
;
696 i
= MPLS_LIST_HEAD(&g
->inlabel
);
698 if (i
->index
== index
) {
702 i
= MPLS_LIST_NEXT(&g
->inlabel
, i
, _global
);
709 mpls_return_enum
ldp_global_find_outlabel_index(ldp_global
* g
, uint32_t index
,
710 ldp_outlabel
** outlabel
)
712 ldp_outlabel
*o
= NULL
;
714 if (g
&& index
> 0) {
716 /* because we sort our inserts by index, this lets us know
717 if we've "walked" past the end of the list */
719 o
= MPLS_LIST_TAIL(&g
->outlabel
);
720 if (o
== NULL
|| o
->index
< index
) {
722 return MPLS_END_OF_LIST
;
725 o
= MPLS_LIST_HEAD(&g
->outlabel
);
727 if (o
->index
== index
) {
731 o
= MPLS_LIST_NEXT(&g
->outlabel
, o
, _global
);
738 mpls_return_enum
ldp_global_find_entity_index(ldp_global
* g
, uint32_t index
,
739 ldp_entity
** entity
)
741 ldp_entity
*e
= NULL
;
743 if (g
&& index
> 0) {
745 /* because we sort our inserts by index, this lets us know
746 if we've "walked" past the end of the list */
748 e
= MPLS_LIST_TAIL(&g
->entity
);
749 if (e
== NULL
|| e
->index
< index
) {
751 return MPLS_END_OF_LIST
;
754 e
= MPLS_LIST_HEAD(&g
->entity
);
756 if (e
->index
== index
) {
760 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
767 ldp_peer
*ldp_global_find_peer_addr(ldp_global
* g
, mpls_inet_addr
* addr
)
771 MPLS_ASSERT(g
&& addr
);
773 /* JLEU: we will need to add a tree to optimize this search,
774 known peers will be in tree, unknown will take a "slow path" to
775 verify them, then be added to tree */
777 p
= MPLS_LIST_HEAD(&g
->peer
);
779 LDP_PRINT(g
->user_data
,
780 "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
781 p
->dest
.addr
.u
.ipv4
, addr
->u
.ipv4
);
782 if (!mpls_inet_addr_compare(&p
->dest
.addr
, addr
)) {
785 p
= MPLS_LIST_NEXT(&g
->peer
, p
, _global
);
790 mpls_return_enum
ldp_global_find_adj_index(ldp_global
* g
, uint32_t index
,
795 if (g
&& index
> 0) {
796 /* because we sort our inserts by index, this lets us know
797 if we've "walked" past the end of the list */
799 a
= MPLS_LIST_TAIL(&g
->adj
);
800 if (a
== NULL
|| a
->index
< index
) {
801 return MPLS_END_OF_LIST
;
805 a
= MPLS_LIST_HEAD(&g
->adj
);
807 if (a
->index
== index
) {
811 a
= MPLS_LIST_NEXT(&g
->adj
, a
, _global
);
818 mpls_return_enum
ldp_global_find_peer_index(ldp_global
* g
, uint32_t index
,
823 if (g
&& index
> 0) {
824 /* because we sort our inserts by index, this lets us know
825 if we've "walked" past the end of the list */
827 p
= MPLS_LIST_TAIL(&g
->peer
);
828 if (p
== NULL
|| p
->index
< index
) {
830 return MPLS_END_OF_LIST
;
833 p
= MPLS_LIST_HEAD(&g
->peer
);
835 if (p
->index
== index
) {
839 p
= MPLS_LIST_NEXT(&g
->peer
, p
, _global
);
846 mpls_return_enum
ldp_global_find_if_index(ldp_global
* g
, uint32_t index
,
851 if (g
&& index
> 0) {
853 /* because we sort our inserts by index, this lets us know
854 if we've "walked" past the end of the list */
856 i
= MPLS_LIST_TAIL(&g
->iff
);
857 if (i
== NULL
|| i
->index
< index
) {
859 return MPLS_END_OF_LIST
;
862 i
= MPLS_LIST_HEAD(&g
->iff
);
864 if (i
->index
== index
) {
868 i
= MPLS_LIST_NEXT(&g
->iff
, i
, _global
);
875 ldp_if
*ldp_global_find_if_handle(ldp_global
* g
, mpls_if_handle handle
)
877 ldp_if
*i
= MPLS_LIST_HEAD(&g
->iff
);
881 if (!mpls_if_handle_compare(i
->handle
, handle
))
884 i
= MPLS_LIST_NEXT(&g
->iff
, i
, _global
);
890 ldp_adj
*ldp_global_find_adj_ldpid(ldp_global
* g
, mpls_inet_addr
* lsraddr
,
894 ldp_adj
*a
= MPLS_LIST_HEAD(&g
->adj
);
897 if ((!mpls_inet_addr_compare(lsraddr
, &a
->remote_lsr_address
)) &&
898 labelspace
== a
->remote_label_space
)
901 a
= MPLS_LIST_NEXT(&g
->adj
, a
, _global
);
906 mpls_return_enum
ldp_global_find_tunnel_index(ldp_global
* g
, uint32_t index
,
907 ldp_tunnel
** tunnel
)
909 ldp_tunnel
*t
= NULL
;
911 if (g
&& index
> 0) {
912 /* because we sort our inserts by index, this lets us know
913 if we've "walked" past the end of the list */
915 t
= MPLS_LIST_TAIL(&g
->tunnel
);
916 if (t
== NULL
|| t
->index
< index
) {
918 return MPLS_END_OF_LIST
;
921 t
= MPLS_LIST_HEAD(&g
->tunnel
);
923 if (t
->index
== index
) {
927 t
= MPLS_LIST_NEXT(&g
->tunnel
, t
, _global
);
934 mpls_return_enum
ldp_global_find_resource_index(ldp_global
* g
, uint32_t index
,
935 ldp_resource
** resource
)
937 ldp_resource
*r
= NULL
;
939 if (g
&& index
> 0) {
940 /* because we sort our inserts by index, this lets us know
941 if we've "walked" past the end of the list */
943 r
= MPLS_LIST_TAIL(&g
->resource
);
944 if (r
== NULL
|| r
->index
< index
) {
946 return MPLS_END_OF_LIST
;
949 r
= MPLS_LIST_HEAD(&g
->resource
);
951 if (r
->index
== index
) {
955 r
= MPLS_LIST_NEXT(&g
->resource
, r
, _global
);
962 mpls_return_enum
ldp_global_find_hop_list_index(ldp_global
* g
, uint32_t index
,
963 ldp_hop_list
** hop_list
)
965 ldp_hop_list
*h
= NULL
;
967 if (g
&& index
> 0) {
968 /* because we sort our inserts by index, this lets us know
969 if we've "walked" past the end of the list */
971 h
= MPLS_LIST_TAIL(&g
->hop_list
);
972 if (h
== NULL
|| h
->index
< index
) {
974 return MPLS_END_OF_LIST
;
977 h
= MPLS_LIST_HEAD(&g
->hop_list
);
979 if (h
->index
== index
) {
983 h
= MPLS_LIST_NEXT(&g
->hop_list
, h
, _global
);
990 void _ldp_global_add_tunnel(ldp_global
* g
, ldp_tunnel
* t
)
992 ldp_tunnel
*tp
= NULL
;
996 tp
= MPLS_LIST_HEAD(&g
->tunnel
);
998 if (tp
->index
> t
->index
) {
999 MPLS_LIST_INSERT_BEFORE(&g
->tunnel
, tp
, t
, _global
);
1002 tp
= MPLS_LIST_NEXT(&g
->tunnel
, tp
, _global
);
1004 MPLS_LIST_ADD_TAIL(&g
->tunnel
, t
, _global
, ldp_tunnel
);
1007 void _ldp_global_del_tunnel(ldp_global
* g
, ldp_tunnel
* t
)
1009 MPLS_ASSERT(g
&& t
);
1010 MPLS_LIST_REMOVE(&g
->tunnel
, t
, _global
);
1011 MPLS_REFCNT_RELEASE(t
, ldp_tunnel_delete
);
1014 void _ldp_global_add_resource(ldp_global
* g
, ldp_resource
* r
)
1016 ldp_resource
*rp
= NULL
;
1018 MPLS_ASSERT(g
&& r
);
1019 MPLS_REFCNT_HOLD(r
);
1020 rp
= MPLS_LIST_HEAD(&g
->resource
);
1021 while (rp
!= NULL
) {
1022 if (rp
->index
> r
->index
) {
1023 MPLS_LIST_INSERT_BEFORE(&g
->resource
, rp
, r
, _global
);
1026 rp
= MPLS_LIST_NEXT(&g
->resource
, rp
, _global
);
1028 MPLS_LIST_ADD_TAIL(&g
->resource
, r
, _global
, ldp_resource
);
1031 void _ldp_global_del_resource(ldp_global
* g
, ldp_resource
* r
)
1033 MPLS_ASSERT(g
&& r
);
1034 MPLS_LIST_REMOVE(&g
->resource
, r
, _global
);
1035 MPLS_REFCNT_RELEASE(r
, ldp_resource_delete
);
1038 void _ldp_global_add_hop_list(ldp_global
* g
, ldp_hop_list
* h
)
1040 ldp_hop_list
*hp
= NULL
;
1042 MPLS_ASSERT(g
&& h
);
1043 MPLS_REFCNT_HOLD(h
);
1044 hp
= MPLS_LIST_HEAD(&g
->hop_list
);
1045 while (hp
!= NULL
) {
1046 if (hp
->index
> h
->index
) {
1047 MPLS_LIST_INSERT_BEFORE(&g
->hop_list
, hp
, h
, _global
);
1050 hp
= MPLS_LIST_NEXT(&g
->hop_list
, hp
, _global
);
1052 MPLS_LIST_ADD_TAIL(&g
->hop_list
, h
, _global
, ldp_hop_list
);
1055 void _ldp_global_del_hop_list(ldp_global
* g
, ldp_hop_list
* h
)
1057 MPLS_ASSERT(g
&& h
);
1058 MPLS_LIST_REMOVE(&g
->hop_list
, h
, _global
);
1059 MPLS_REFCNT_RELEASE(h
, ldp_hop_list_delete
);