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
->addr
, ldp_addr
);
106 MPLS_LIST_INIT(&g
->attr
, ldp_attr
);
107 MPLS_LIST_INIT(&g
->peer
, ldp_peer
);
108 MPLS_LIST_INIT(&g
->fec
, ldp_fec
);
109 MPLS_LIST_INIT(&g
->adj
, ldp_adj
);
110 MPLS_LIST_INIT(&g
->iff
, ldp_if
);
112 g
->message_identifier
= 1;
113 g
->configuration_sequence_number
= 1;
114 g
->lsp_control_mode
= LDP_GLOBAL_DEF_CONTROL_MODE
;
115 g
->label_retention_mode
= LDP_GLOBAL_DEF_RETENTION_MODE
;
116 g
->lsp_repair_mode
= LDP_GLOBAL_DEF_REPAIR_MODE
;
117 g
->propagate_release
= LDP_GLOBAL_DEF_PROPOGATE_RELEASE
;
118 g
->label_merge
= LDP_GLOBAL_DEF_LABEL_MERGE
;
119 g
->loop_detection_mode
= LDP_GLOBAL_DEF_LOOP_DETECTION_MODE
;
120 g
->ttl_less_domain
= LDP_GLOBAL_DEF_TTLLESS_DOMAIN
;
121 g
->local_tcp_port
= LDP_GLOBAL_DEF_LOCAL_TCP_PORT
;
122 g
->local_udp_port
= LDP_GLOBAL_DEF_LOCAL_UDP_PORT
;
123 g
->send_address_messages
= LDP_GLOBAL_DEF_SEND_ADDR_MSG
;
124 g
->backoff_step
= LDP_GLOBAL_DEF_BACKOFF_STEP
;
125 g
->send_lsrid_mapping
= LDP_GLOBAL_DEF_SEND_LSRID_MAPPING
;
126 g
->no_route_to_peer_time
= LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME
;
128 g
->keepalive_timer
= LDP_ENTITY_DEF_KEEPALIVE_TIMER
;
129 g
->keepalive_interval
= LDP_ENTITY_DEF_KEEPALIVE_INTERVAL
;
130 g
->hellotime_timer
= LDP_ENTITY_DEF_HELLOTIME_TIMER
;
131 g
->hellotime_interval
= LDP_ENTITY_DEF_HELLOTIME_INTERVAL
;
133 g
->admin_state
= MPLS_ADMIN_DISABLE
;
136 mpls_lock_release(g
->global_lock
);
138 LDP_EXIT(g
->user_data
, "ldp_global_create");
144 mpls_return_enum
ldp_global_startup(ldp_global
* g
)
146 ldp_entity
*e
= NULL
;
149 MPLS_ASSERT(g
!= NULL
);
151 LDP_ENTER(g
->user_data
, "ldp_global_startup");
153 if (g
->lsr_identifier
.type
== MPLS_FAMILY_NONE
) {
154 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_ERROR
,
155 "ldp_global_startup: invalid LSRID\n");
156 goto ldp_global_startup_cleanup
;
159 g
->timer_handle
= mpls_timer_open(g
->user_data
);
160 if (mpls_timer_mgr_handle_verify(g
->timer_handle
) == MPLS_BOOL_FALSE
) {
161 goto ldp_global_startup_cleanup
;
164 g
->socket_handle
= mpls_socket_mgr_open(g
->user_data
);
165 if (mpls_socket_mgr_handle_verify(g
->socket_handle
) == MPLS_BOOL_FALSE
) {
166 goto ldp_global_startup_cleanup
;
169 g
->ifmgr_handle
= mpls_ifmgr_open(g
->user_data
, g
);
170 if (mpls_ifmgr_handle_verify(g
->ifmgr_handle
) == MPLS_BOOL_FALSE
) {
171 goto ldp_global_startup_cleanup
;
174 g
->fib_handle
= mpls_fib_open(g
->user_data
, g
);
175 if (mpls_fib_handle_verify(g
->fib_handle
) == MPLS_BOOL_FALSE
) {
176 goto ldp_global_startup_cleanup
;
180 if (!g
->lsr_handle
) {
181 goto ldp_global_startup_cleanup
;
184 g
->mpls_handle
= mpls_mpls_open(g
->user_data
);
185 if (mpls_mpls_handle_verify(g
->mpls_handle
) == MPLS_BOOL_FALSE
) {
186 goto ldp_global_startup_cleanup
;
190 g
->addr_tree
= mpls_tree_create(32);
191 g
->fec_tree
= mpls_tree_create(32);
193 g
->hello_socket
= mpls_socket_create_udp(g
->socket_handle
);
194 if (mpls_socket_handle_verify(g
->socket_handle
, g
->hello_socket
) == MPLS_BOOL_FALSE
) {
195 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
196 "ldp_global_startup: error creating UDP socket\n");
197 goto ldp_global_startup_cleanup
;
200 dest
.addr
.type
= MPLS_FAMILY_IPV4
;
201 dest
.port
= g
->local_udp_port
;
202 dest
.addr
.u
.ipv4
= INADDR_ANY
;
203 // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
205 if (mpls_socket_bind(g
->socket_handle
, g
->hello_socket
, &dest
) == MPLS_FAILURE
) {
206 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
207 "ldp_global_startup: error binding UDP socket\n");
208 goto ldp_global_startup_cleanup
;
211 if (mpls_socket_options(g
->socket_handle
, g
->hello_socket
,
212 MPLS_SOCKOP_NONBLOCK
| MPLS_SOCKOP_REUSE
) == MPLS_FAILURE
) {
213 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
214 "ldp_global_startup: error setting UDP socket options\n");
215 goto ldp_global_startup_cleanup
;
217 if (mpls_socket_multicast_options(g
->socket_handle
, g
->hello_socket
, 1, 0) ==
219 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
220 "ldp_global_startup: error setting UDP socket multicast options\n");
221 goto ldp_global_startup_cleanup
;
223 mpls_socket_readlist_add(g
->socket_handle
, g
->hello_socket
, 0, MPLS_SOCKET_UDP_DATA
);
225 g
->listen_socket
= mpls_socket_create_tcp(g
->socket_handle
);
226 if (mpls_socket_handle_verify(g
->socket_handle
, g
->listen_socket
) == MPLS_BOOL_FALSE
) {
227 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
228 "ldp_global_startup: error creating TCP socket\n");
229 goto ldp_global_startup_cleanup
;
231 if (mpls_socket_options(g
->socket_handle
, g
->listen_socket
,
232 MPLS_SOCKOP_NONBLOCK
| MPLS_SOCKOP_REUSE
) == MPLS_FAILURE
) {
233 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
234 "ldp_global_startup: error setting TCP socket options\n");
235 goto ldp_global_startup_cleanup
;
238 dest
.addr
.type
= MPLS_FAMILY_IPV4
;
239 dest
.port
= g
->local_tcp_port
;
240 dest
.addr
.u
.ipv4
= INADDR_ANY
;
242 if (mpls_socket_bind(g
->socket_handle
, g
->listen_socket
, &dest
) == MPLS_FAILURE
) {
243 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
244 "ldp_global_startup: error binding TCP socket\n");
245 goto ldp_global_startup_cleanup
;
248 if (mpls_socket_tcp_listen(g
->socket_handle
, g
->listen_socket
, 15) ==
250 LDP_TRACE_LOG(g
->user_data
, MPLS_TRACE_STATE_ALL
, LDP_TRACE_FLAG_DEBUG
,
251 "ldp_global_startup: error setting listen buffer for TCP socket\n");
252 goto ldp_global_startup_cleanup
;
255 mpls_socket_readlist_add(g
->socket_handle
, g
->listen_socket
, 0,
256 MPLS_SOCKET_TCP_LISTEN
);
262 mpls_return_enum retval
;
264 retval
= mpls_ifmgr_getfirst_address(g
->ifmgr_handle
, &iff
, &addr
);
265 if (retval
== MPLS_FATAL
) {
266 goto ldp_global_startup_cleanup
;
268 if (retval
== MPLS_SUCCESS
) {
272 if (!(a
= ldp_addr_create(g
, &addr
))) {
273 goto ldp_global_startup_cleanup
;
276 if ((i
= ldp_global_find_if_handle(g
, iff
))) {
277 ldp_if_add_addr(i
, a
);
279 } while (mpls_ifmgr_getnext_address(g
->ifmgr_handle
, &iff
, &addr
) ==
285 mpls_nexthop nexthop
;
286 mpls_return_enum retval
;
288 retval
= mpls_fib_getfirst_route(g
->fib_handle
, &fec
, &nexthop
);
289 if (retval
== MPLS_FATAL
) {
290 goto ldp_global_startup_cleanup
;
292 if (retval
== MPLS_SUCCESS
) {
297 if (!(f
= ldp_fec_find(g
, &fec
))) {
298 f
= ldp_fec_create(g
, &fec
);
300 goto ldp_global_startup_cleanup
;
304 n
= ldp_nexthop_create();
306 goto ldp_global_startup_cleanup
;
309 memcpy(&n
->info
, &nexthop
, sizeof(mpls_nexthop
));
310 if (ldp_fec_add_nexthop(g
, f
, n
) != MPLS_SUCCESS
) {
311 goto ldp_global_startup_cleanup
;
313 _ldp_global_add_nexthop(g
, n
);
314 } while (mpls_fib_getnext_route(g
->fib_handle
, &fec
, &nexthop
) ==
320 e
= MPLS_LIST_HEAD(&g
->entity
);
322 ldp_entity_startup(g
, e
);
323 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
326 g
->admin_state
= MPLS_ADMIN_ENABLE
;
328 LDP_EXIT(g
->user_data
, "ldp_global_startup");
331 ldp_global_startup_cleanup
:
332 ldp_global_shutdown(g
);
333 mpls_socket_close(g
->socket_handle
, g
->hello_socket
);
334 mpls_socket_close(g
->socket_handle
, g
->listen_socket
);
336 g
->listen_socket
= 0;
338 LDP_EXIT(g
->user_data
, "ldp_global_startup-error");
343 mpls_return_enum
ldp_global_shutdown(ldp_global
* g
)
345 ldp_entity
*e
= NULL
;
353 LDP_ENTER(g
->user_data
, "ldp_global_shutdown");
355 e
= MPLS_LIST_HEAD(&g
->entity
);
357 ldp_entity_shutdown(g
, e
, 1);
358 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
361 g
->admin_state
= MPLS_ADMIN_DISABLE
;
363 while ((f
= MPLS_LIST_HEAD(&g
->fec
))) {
364 while ((n
= MPLS_LIST_HEAD(&f
->nh_root
))) {
365 ldp_fec_del_nexthop(g
, f
, n
);
367 MPLS_REFCNT_RELEASE2(g
, f
, ldp_fec_delete
);
370 while ((i
= MPLS_LIST_HEAD(&g
->iff
))) {
371 while ((a
= MPLS_LIST_HEAD(&i
->addr_root
))) {
372 ldp_if_del_addr(g
, i
, a
);
374 MPLS_REFCNT_RELEASE2(g
, i
, ldp_if_delete
);
377 mpls_socket_readlist_del(g
->socket_handle
, g
->hello_socket
);
378 mpls_socket_close(g
->socket_handle
, g
->hello_socket
);
380 mpls_socket_readlist_del(g
->socket_handle
, g
->listen_socket
);
381 mpls_socket_close(g
->socket_handle
, g
->listen_socket
);
383 mpls_tree_delete(g
->addr_tree
);
384 mpls_tree_delete(g
->fec_tree
);
386 mpls_lock_release(g
->global_lock
);
387 mpls_timer_close(g
->timer_handle
);
388 mpls_lock_get(g
->global_lock
);
390 mpls_socket_mgr_close(g
->socket_handle
);
391 mpls_ifmgr_close(g
->ifmgr_handle
);
392 mpls_fib_close(g
->fib_handle
);
396 mpls_mpls_close(g
->mpls_handle
);
399 LDP_EXIT(g
->user_data
, "ldp_global_shutdown");
404 mpls_return_enum
ldp_global_delete(ldp_global
* g
)
407 mpls_lock_delete(g
->global_lock
);
408 LDP_PRINT(g
->user_data
, "global delete\n");
414 void _ldp_global_add_attr(ldp_global
* g
, ldp_attr
* a
)
420 ap
= MPLS_LIST_HEAD(&g
->attr
);
422 if (ap
->index
> a
->index
) {
423 MPLS_LIST_INSERT_BEFORE(&g
->attr
, ap
, a
, _global
);
426 ap
= MPLS_LIST_NEXT(&g
->attr
, ap
, _global
);
428 MPLS_LIST_ADD_TAIL(&g
->attr
, a
, _global
, ldp_attr
);
431 void _ldp_global_del_attr(ldp_global
* g
, ldp_attr
* a
)
434 MPLS_LIST_REMOVE(&g
->attr
, a
, _global
);
435 MPLS_REFCNT_RELEASE(a
, ldp_attr_delete
);
438 void _ldp_global_add_peer(ldp_global
* g
, ldp_peer
* p
)
444 pp
= MPLS_LIST_HEAD(&g
->peer
);
446 if (pp
->index
> p
->index
) {
447 MPLS_LIST_INSERT_BEFORE(&g
->peer
, pp
, p
, _global
);
450 pp
= MPLS_LIST_NEXT(&g
->peer
, pp
, _global
);
452 MPLS_LIST_ADD_TAIL(&g
->peer
, p
, _global
, ldp_peer
);
455 void _ldp_global_del_peer(ldp_global
* g
, ldp_peer
* p
)
458 MPLS_LIST_REMOVE(&g
->peer
, p
, _global
);
459 MPLS_REFCNT_RELEASE(p
, ldp_peer_delete
);
463 * _ldp_global_add_if/del_if and _ldp_global_add_addr/del_addr are
464 * not the same as the rest of the global_add/del functions. They
465 * do not hold refcnts, they are used as part of the create and delete
466 * process of these structures
469 void _ldp_global_add_if(ldp_global
* g
, ldp_if
* i
)
474 ip
= MPLS_LIST_HEAD(&g
->iff
);
476 if (ip
->index
> i
->index
) {
477 MPLS_LIST_INSERT_BEFORE(&g
->iff
, ip
, i
, _global
);
480 ip
= MPLS_LIST_NEXT(&g
->iff
, ip
, _global
);
482 MPLS_LIST_ADD_TAIL(&g
->iff
, i
, _global
, ldp_if
);
485 void _ldp_global_del_if(ldp_global
* g
, ldp_if
* i
)
488 MPLS_LIST_REMOVE(&g
->iff
, i
, _global
);
491 void _ldp_global_add_addr(ldp_global
* g
, ldp_addr
* a
)
496 ap
= MPLS_LIST_HEAD(&g
->addr
);
498 if (ap
->index
> a
->index
) {
499 MPLS_LIST_INSERT_BEFORE(&g
->addr
, ap
, a
, _global
);
502 ap
= MPLS_LIST_NEXT(&g
->addr
, ap
, _global
);
504 MPLS_LIST_ADD_TAIL(&g
->addr
, a
, _global
, ldp_addr
);
507 void _ldp_global_del_addr(ldp_global
* g
, ldp_addr
* a
)
510 MPLS_LIST_REMOVE(&g
->addr
, a
, _global
);
515 void _ldp_global_add_adj(ldp_global
* g
, ldp_adj
* a
)
521 ap
= MPLS_LIST_HEAD(&g
->adj
);
523 if (ap
->index
> a
->index
) {
524 MPLS_LIST_INSERT_BEFORE(&g
->adj
, ap
, a
, _global
);
527 ap
= MPLS_LIST_NEXT(&g
->adj
, ap
, _global
);
529 MPLS_LIST_ADD_TAIL(&g
->adj
, a
, _global
, ldp_adj
);
532 void _ldp_global_del_adj(ldp_global
* g
, ldp_adj
* a
)
535 MPLS_LIST_REMOVE(&g
->adj
, a
, _global
);
536 MPLS_REFCNT_RELEASE(a
, ldp_adj_delete
);
539 void _ldp_global_add_entity(ldp_global
* g
, ldp_entity
* e
)
541 ldp_entity
*ep
= NULL
;
545 ep
= MPLS_LIST_HEAD(&g
->entity
);
547 if (ep
->index
> e
->index
) {
548 MPLS_LIST_INSERT_BEFORE(&g
->entity
, ep
, e
, _global
);
551 ep
= MPLS_LIST_NEXT(&g
->entity
, ep
, _global
);
553 MPLS_LIST_ADD_TAIL(&g
->entity
, e
, _global
, ldp_entity
);
556 void _ldp_global_del_entity(ldp_global
* g
, ldp_entity
* e
)
559 MPLS_LIST_REMOVE(&g
->entity
, e
, _global
);
560 MPLS_REFCNT_RELEASE(e
, ldp_entity_delete
);
563 void _ldp_global_add_session(ldp_global
* g
, ldp_session
* s
)
565 ldp_session
*sp
= NULL
;
569 s
->on_global
= MPLS_BOOL_TRUE
;
570 sp
= MPLS_LIST_HEAD(&g
->session
);
572 if (sp
->index
> s
->index
) {
573 MPLS_LIST_INSERT_BEFORE(&g
->session
, sp
, s
, _global
);
576 sp
= MPLS_LIST_NEXT(&g
->session
, sp
, _global
);
578 MPLS_LIST_ADD_TAIL(&g
->session
, s
, _global
, ldp_session
);
581 void _ldp_global_del_session(ldp_global
* g
, ldp_session
* s
)
584 MPLS_ASSERT(s
->on_global
== MPLS_BOOL_TRUE
);
585 MPLS_LIST_REMOVE(&g
->session
, s
, _global
);
586 s
->on_global
= MPLS_BOOL_FALSE
;
587 MPLS_REFCNT_RELEASE(s
, ldp_session_delete
);
590 mpls_return_enum
_ldp_global_add_inlabel(ldp_global
* g
, ldp_inlabel
* i
)
592 ldp_inlabel
*ip
= NULL
;
593 mpls_return_enum result
;
600 memcpy(&iseg
.info
,&i
->info
,sizeof(mpls_insegment
));
601 result
= lsr_cfg_insegment_set(g
->lsr_handle
, &iseg
, LSR_CFG_ADD
|
602 LSR_INSEGMENT_CFG_NPOP
|LSR_INSEGMENT_CFG_FAMILY
|
603 LSR_INSEGMENT_CFG_LABELSPACE
|LSR_INSEGMENT_CFG_LABEL
|
604 LSR_INSEGMENT_CFG_OWNER
);
605 memcpy(&i
->info
, &iseg
.info
, sizeof(mpls_insegment
));
606 i
->info
.handle
= iseg
.index
;
609 result
= mpls_mpls_insegment_add(g
->mpls_handle
, &i
->info
);
611 if (result
!= MPLS_SUCCESS
) {
616 ip
= MPLS_LIST_HEAD(&g
->inlabel
);
618 if (ip
->index
> i
->index
) {
619 MPLS_LIST_INSERT_BEFORE(&g
->inlabel
, ip
, i
, _global
);
622 ip
= MPLS_LIST_NEXT(&g
->inlabel
, ip
, _global
);
624 MPLS_LIST_ADD_TAIL(&g
->inlabel
, i
, _global
, ldp_inlabel
);
628 mpls_return_enum
_ldp_global_del_inlabel(ldp_global
* g
, ldp_inlabel
* i
)
631 MPLS_ASSERT(i
->reuse_count
== 0);
635 iseg
.index
= i
->info
.handle
;
636 lsr_cfg_insegment_set(g
->lsr_handle
, &iseg
, LSR_CFG_DEL
);
639 mpls_mpls_insegment_del(g
->mpls_handle
, &i
->info
);
641 MPLS_LIST_REMOVE(&g
->inlabel
, i
, _global
);
642 MPLS_REFCNT_RELEASE(i
, ldp_inlabel_delete
);
646 mpls_return_enum
_ldp_global_add_outlabel(ldp_global
* g
, ldp_outlabel
* o
)
648 ldp_outlabel
*op
= NULL
;
649 mpls_return_enum result
;
655 memcpy(&oseg
.info
, &o
->info
, sizeof(mpls_outsegment
));
656 result
= lsr_cfg_outsegment_set(g
->lsr_handle
, &oseg
, LSR_CFG_ADD
|
657 LSR_OUTSEGMENT_CFG_PUSH_LABEL
|LSR_OUTSEGMENT_CFG_OWNER
|
658 LSR_OUTSEGMENT_CFG_INTERFACE
|LSR_OUTSEGMENT_CFG_LABEL
|
659 LSR_OUTSEGMENT_CFG_NEXTHOP
);
660 o
->info
.handle
= oseg
.index
;
663 result
= mpls_mpls_outsegment_add(g
->mpls_handle
, &o
->info
);
666 if (result
!= MPLS_SUCCESS
) {
671 o
->switching
= MPLS_BOOL_TRUE
;
672 op
= MPLS_LIST_HEAD(&g
->outlabel
);
674 if (op
->index
> o
->index
) {
675 MPLS_LIST_INSERT_BEFORE(&g
->outlabel
, op
, o
, _global
);
678 op
= MPLS_LIST_NEXT(&g
->outlabel
, op
, _global
);
680 MPLS_LIST_ADD_TAIL(&g
->outlabel
, o
, _global
, ldp_outlabel
);
684 mpls_return_enum
_ldp_global_del_outlabel(ldp_global
* g
, ldp_outlabel
* o
)
690 oseg
.index
= o
->info
.handle
;
691 lsr_cfg_outsegment_set(g
->lsr_handle
, &oseg
, LSR_CFG_DEL
);
694 mpls_mpls_outsegment_del(g
->mpls_handle
, &o
->info
);
697 o
->switching
= MPLS_BOOL_FALSE
;
698 MPLS_ASSERT(o
->merge_count
== 0);
699 MPLS_LIST_REMOVE(&g
->outlabel
, o
, _global
);
700 MPLS_REFCNT_RELEASE(o
, ldp_outlabel_delete
);
704 mpls_return_enum
ldp_global_find_attr_index(ldp_global
* g
, uint32_t index
,
709 if (g
&& index
> 0) {
711 /* because we sort our inserts by index, this lets us know
712 if we've "walked" past the end of the list */
714 a
= MPLS_LIST_TAIL(&g
->attr
);
715 if (a
== NULL
|| a
->index
< index
) {
716 return MPLS_END_OF_LIST
;
720 a
= MPLS_LIST_HEAD(&g
->attr
);
722 if (a
->index
== index
) {
726 a
= MPLS_LIST_NEXT(&g
->attr
, a
, _global
);
733 mpls_return_enum
ldp_global_find_session_index(ldp_global
* g
, uint32_t index
,
734 ldp_session
** session
)
736 ldp_session
*s
= NULL
;
738 if (g
&& index
> 0) {
740 /* because we sort our inserts by index, this lets us know
741 if we've "walked" past the end of the list */
743 s
= MPLS_LIST_TAIL(&g
->session
);
744 if (s
== NULL
|| s
->index
< index
) {
746 return MPLS_END_OF_LIST
;
749 s
= MPLS_LIST_HEAD(&g
->session
);
751 if (s
->index
== index
) {
755 s
= MPLS_LIST_NEXT(&g
->session
, s
, _global
);
762 mpls_return_enum
ldp_global_find_inlabel_index(ldp_global
* g
, uint32_t index
,
763 ldp_inlabel
** inlabel
)
765 ldp_inlabel
*i
= NULL
;
767 if (g
&& index
> 0) {
769 /* because we sort our inserts by index, this lets us know
770 if we've "walked" past the end of the list */
772 i
= MPLS_LIST_TAIL(&g
->inlabel
);
773 if (i
== NULL
|| i
->index
< index
) {
775 return MPLS_END_OF_LIST
;
778 i
= MPLS_LIST_HEAD(&g
->inlabel
);
780 if (i
->index
== index
) {
784 i
= MPLS_LIST_NEXT(&g
->inlabel
, i
, _global
);
791 mpls_return_enum
ldp_global_find_outlabel_index(ldp_global
* g
, uint32_t index
,
792 ldp_outlabel
** outlabel
)
794 ldp_outlabel
*o
= NULL
;
796 if (g
&& index
> 0) {
798 /* because we sort our inserts by index, this lets us know
799 if we've "walked" past the end of the list */
801 o
= MPLS_LIST_TAIL(&g
->outlabel
);
802 if (o
== NULL
|| o
->index
< index
) {
804 return MPLS_END_OF_LIST
;
807 o
= MPLS_LIST_HEAD(&g
->outlabel
);
809 if (o
->index
== index
) {
813 o
= MPLS_LIST_NEXT(&g
->outlabel
, o
, _global
);
820 ldp_outlabel
*ldp_global_find_outlabel_handle(ldp_global
* g
,
821 mpls_outsegment_handle handle
)
823 ldp_outlabel
*o
= MPLS_LIST_HEAD(&g
->outlabel
);
827 if (!mpls_outsegment_handle_compare(o
->info
.handle
, handle
))
830 o
= MPLS_LIST_NEXT(&g
->outlabel
, o
, _global
);
836 mpls_return_enum
ldp_global_find_entity_index(ldp_global
* g
, uint32_t index
,
837 ldp_entity
** entity
)
839 ldp_entity
*e
= NULL
;
841 if (g
&& index
> 0) {
843 /* because we sort our inserts by index, this lets us know
844 if we've "walked" past the end of the list */
846 e
= MPLS_LIST_TAIL(&g
->entity
);
847 if (e
== NULL
|| e
->index
< index
) {
849 return MPLS_END_OF_LIST
;
852 e
= MPLS_LIST_HEAD(&g
->entity
);
854 if (e
->index
== index
) {
858 e
= MPLS_LIST_NEXT(&g
->entity
, e
, _global
);
865 ldp_peer
*ldp_global_find_peer_addr(ldp_global
* g
, mpls_inet_addr
* addr
)
869 MPLS_ASSERT(g
&& addr
);
871 /* JLEU: we will need to add a tree to optimize this search,
872 known peers will be in tree, unknown will take a "slow path" to
873 verify them, then be added to tree */
875 p
= MPLS_LIST_HEAD(&g
->peer
);
877 LDP_PRINT(g
->user_data
,
878 "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
879 p
->dest
.addr
.u
.ipv4
, addr
->u
.ipv4
);
880 if (!mpls_inet_addr_compare(&p
->dest
.addr
, addr
)) {
883 p
= MPLS_LIST_NEXT(&g
->peer
, p
, _global
);
888 mpls_return_enum
ldp_global_find_adj_index(ldp_global
* g
, uint32_t index
,
893 if (g
&& index
> 0) {
894 /* because we sort our inserts by index, this lets us know
895 if we've "walked" past the end of the list */
897 a
= MPLS_LIST_TAIL(&g
->adj
);
898 if (a
== NULL
|| a
->index
< index
) {
899 return MPLS_END_OF_LIST
;
903 a
= MPLS_LIST_HEAD(&g
->adj
);
905 if (a
->index
== index
) {
909 a
= MPLS_LIST_NEXT(&g
->adj
, a
, _global
);
916 mpls_return_enum
ldp_global_find_peer_index(ldp_global
* g
, uint32_t index
,
921 if (g
&& index
> 0) {
922 /* because we sort our inserts by index, this lets us know
923 if we've "walked" past the end of the list */
925 p
= MPLS_LIST_TAIL(&g
->peer
);
926 if (p
== NULL
|| p
->index
< index
) {
928 return MPLS_END_OF_LIST
;
931 p
= MPLS_LIST_HEAD(&g
->peer
);
933 if (p
->index
== index
) {
937 p
= MPLS_LIST_NEXT(&g
->peer
, p
, _global
);
944 mpls_return_enum
ldp_global_find_fec_index(ldp_global
* g
, uint32_t index
,
949 if (g
&& index
> 0) {
950 /* because we sort our inserts by index, this lets us know
951 if we've "walked" past the end of the list */
953 f
= MPLS_LIST_TAIL(&g
->fec
);
954 if (f
== NULL
|| f
->index
< index
) {
956 return MPLS_END_OF_LIST
;
959 f
= MPLS_LIST_HEAD(&g
->fec
);
961 if (f
->index
== index
) {
965 f
= MPLS_LIST_NEXT(&g
->fec
, f
, _global
);
972 mpls_return_enum
ldp_global_find_fec(ldp_global
* g
, mpls_fec
* m
,
979 f
= MPLS_LIST_HEAD(&g
->fec
);
981 if (!mpls_fec_compare(m
, &f
->info
)) {
985 } while((f
= MPLS_LIST_NEXT(&g
->fec
, f
, _global
)));
990 mpls_return_enum
ldp_global_find_addr_index(ldp_global
* g
, uint32_t index
,
995 if (g
&& index
> 0) {
997 /* because we sort our inserts by index, this lets us know
998 if we've "walked" past the end of the list */
1000 a
= MPLS_LIST_TAIL(&g
->addr
);
1001 if (a
== NULL
|| a
->index
< index
) {
1003 return MPLS_END_OF_LIST
;
1006 a
= MPLS_LIST_HEAD(&g
->addr
);
1008 if (a
->index
== index
) {
1010 return MPLS_SUCCESS
;
1012 a
= MPLS_LIST_NEXT(&g
->addr
, a
, _global
);
1016 return MPLS_FAILURE
;
1019 mpls_return_enum
ldp_global_find_if_index(ldp_global
* g
, uint32_t index
,
1024 if (g
&& index
> 0) {
1026 /* because we sort our inserts by index, this lets us know
1027 if we've "walked" past the end of the list */
1029 i
= MPLS_LIST_TAIL(&g
->iff
);
1030 if (i
== NULL
|| i
->index
< index
) {
1032 return MPLS_END_OF_LIST
;
1035 i
= MPLS_LIST_HEAD(&g
->iff
);
1037 if (i
->index
== index
) {
1039 return MPLS_SUCCESS
;
1041 i
= MPLS_LIST_NEXT(&g
->iff
, i
, _global
);
1045 return MPLS_FAILURE
;
1048 ldp_if
*ldp_global_find_if_handle(ldp_global
* g
, mpls_if_handle handle
)
1050 ldp_if
*i
= MPLS_LIST_HEAD(&g
->iff
);
1054 if (!mpls_if_handle_compare(i
->handle
, handle
))
1057 i
= MPLS_LIST_NEXT(&g
->iff
, i
, _global
);
1063 ldp_adj
*ldp_global_find_adj_ldpid(ldp_global
* g
, mpls_inet_addr
* lsraddr
,
1067 ldp_adj
*a
= MPLS_LIST_HEAD(&g
->adj
);
1070 if ((!mpls_inet_addr_compare(lsraddr
, &a
->remote_lsr_address
)) &&
1071 labelspace
== a
->remote_label_space
)
1074 a
= MPLS_LIST_NEXT(&g
->adj
, a
, _global
);
1079 mpls_return_enum
ldp_global_find_tunnel_index(ldp_global
* g
, uint32_t index
,
1080 ldp_tunnel
** tunnel
)
1082 ldp_tunnel
*t
= NULL
;
1084 if (g
&& index
> 0) {
1085 /* because we sort our inserts by index, this lets us know
1086 if we've "walked" past the end of the list */
1088 t
= MPLS_LIST_TAIL(&g
->tunnel
);
1089 if (t
== NULL
|| t
->index
< index
) {
1091 return MPLS_END_OF_LIST
;
1094 t
= MPLS_LIST_HEAD(&g
->tunnel
);
1096 if (t
->index
== index
) {
1098 return MPLS_SUCCESS
;
1100 t
= MPLS_LIST_NEXT(&g
->tunnel
, t
, _global
);
1104 return MPLS_FAILURE
;
1107 mpls_return_enum
ldp_global_find_resource_index(ldp_global
* g
, uint32_t index
,
1108 ldp_resource
** resource
)
1110 ldp_resource
*r
= NULL
;
1112 if (g
&& index
> 0) {
1113 /* because we sort our inserts by index, this lets us know
1114 if we've "walked" past the end of the list */
1116 r
= MPLS_LIST_TAIL(&g
->resource
);
1117 if (r
== NULL
|| r
->index
< index
) {
1119 return MPLS_END_OF_LIST
;
1122 r
= MPLS_LIST_HEAD(&g
->resource
);
1124 if (r
->index
== index
) {
1126 return MPLS_SUCCESS
;
1128 r
= MPLS_LIST_NEXT(&g
->resource
, r
, _global
);
1132 return MPLS_FAILURE
;
1135 mpls_return_enum
ldp_global_find_hop_list_index(ldp_global
* g
, uint32_t index
,
1136 ldp_hop_list
** hop_list
)
1138 ldp_hop_list
*h
= NULL
;
1140 if (g
&& index
> 0) {
1141 /* because we sort our inserts by index, this lets us know
1142 if we've "walked" past the end of the list */
1144 h
= MPLS_LIST_TAIL(&g
->hop_list
);
1145 if (h
== NULL
|| h
->index
< index
) {
1147 return MPLS_END_OF_LIST
;
1150 h
= MPLS_LIST_HEAD(&g
->hop_list
);
1152 if (h
->index
== index
) {
1154 return MPLS_SUCCESS
;
1156 h
= MPLS_LIST_NEXT(&g
->hop_list
, h
, _global
);
1160 return MPLS_FAILURE
;
1163 void _ldp_global_add_tunnel(ldp_global
* g
, ldp_tunnel
* t
)
1165 ldp_tunnel
*tp
= NULL
;
1167 MPLS_ASSERT(g
&& t
);
1168 MPLS_REFCNT_HOLD(t
);
1169 tp
= MPLS_LIST_HEAD(&g
->tunnel
);
1170 while (tp
!= NULL
) {
1171 if (tp
->index
> t
->index
) {
1172 MPLS_LIST_INSERT_BEFORE(&g
->tunnel
, tp
, t
, _global
);
1175 tp
= MPLS_LIST_NEXT(&g
->tunnel
, tp
, _global
);
1177 MPLS_LIST_ADD_TAIL(&g
->tunnel
, t
, _global
, ldp_tunnel
);
1180 void _ldp_global_del_tunnel(ldp_global
* g
, ldp_tunnel
* t
)
1182 MPLS_ASSERT(g
&& t
);
1183 MPLS_LIST_REMOVE(&g
->tunnel
, t
, _global
);
1184 MPLS_REFCNT_RELEASE(t
, ldp_tunnel_delete
);
1187 void _ldp_global_add_resource(ldp_global
* g
, ldp_resource
* r
)
1189 ldp_resource
*rp
= NULL
;
1191 MPLS_ASSERT(g
&& r
);
1192 MPLS_REFCNT_HOLD(r
);
1193 rp
= MPLS_LIST_HEAD(&g
->resource
);
1194 while (rp
!= NULL
) {
1195 if (rp
->index
> r
->index
) {
1196 MPLS_LIST_INSERT_BEFORE(&g
->resource
, rp
, r
, _global
);
1199 rp
= MPLS_LIST_NEXT(&g
->resource
, rp
, _global
);
1201 MPLS_LIST_ADD_TAIL(&g
->resource
, r
, _global
, ldp_resource
);
1204 void _ldp_global_del_resource(ldp_global
* g
, ldp_resource
* r
)
1206 MPLS_ASSERT(g
&& r
);
1207 MPLS_LIST_REMOVE(&g
->resource
, r
, _global
);
1208 MPLS_REFCNT_RELEASE(r
, ldp_resource_delete
);
1211 void _ldp_global_add_hop_list(ldp_global
* g
, ldp_hop_list
* h
)
1213 ldp_hop_list
*hp
= NULL
;
1215 MPLS_ASSERT(g
&& h
);
1216 MPLS_REFCNT_HOLD(h
);
1217 hp
= MPLS_LIST_HEAD(&g
->hop_list
);
1218 while (hp
!= NULL
) {
1219 if (hp
->index
> h
->index
) {
1220 MPLS_LIST_INSERT_BEFORE(&g
->hop_list
, hp
, h
, _global
);
1223 hp
= MPLS_LIST_NEXT(&g
->hop_list
, hp
, _global
);
1225 MPLS_LIST_ADD_TAIL(&g
->hop_list
, h
, _global
, ldp_hop_list
);
1228 void _ldp_global_del_hop_list(ldp_global
* g
, ldp_hop_list
* h
)
1230 MPLS_ASSERT(g
&& h
);
1231 MPLS_LIST_REMOVE(&g
->hop_list
, h
, _global
);
1232 MPLS_REFCNT_RELEASE(h
, ldp_hop_list_delete
);
1235 void _ldp_global_add_fec(ldp_global
* g
, ldp_fec
* f
)
1239 MPLS_ASSERT(g
&& f
);
1241 * TESTING: jleu 6/7/2004, since I want the FEC to be cleaned up
1242 * when it no longer has a nexthop, addr, or label, the only things that
1243 * should increment the ref are those (nh, addr, label etc), not global
1244 * nor inserting into the tree. I also added this comment in
1246 MPLS_REFCNT_HOLD(f);
1248 fp
= MPLS_LIST_HEAD(&g
->fec
);
1249 while (fp
!= NULL
) {
1250 if (fp
->index
> f
->index
) {
1251 MPLS_LIST_INSERT_BEFORE(&g
->fec
, fp
, f
, _global
);
1254 fp
= MPLS_LIST_NEXT(&g
->fec
, fp
, _global
);
1256 MPLS_LIST_ADD_TAIL(&g
->fec
, f
, _global
, ldp_fec
);
1259 void _ldp_global_del_fec(ldp_global
* g
, ldp_fec
* f
)
1261 MPLS_ASSERT(g
&& f
);
1262 MPLS_LIST_REMOVE(&g
->fec
, f
, _global
);
1265 void _ldp_global_add_nexthop(ldp_global
* g
, ldp_nexthop
* nh
)
1267 ldp_nexthop
*nhp
= NULL
;
1269 MPLS_ASSERT(g
&& nh
);
1270 nhp
= MPLS_LIST_HEAD(&g
->nexthop
);
1271 while (nhp
!= NULL
) {
1272 if (nhp
->index
> nh
->index
) {
1273 MPLS_LIST_INSERT_BEFORE(&g
->nexthop
, nhp
, nh
, _global
);
1276 nhp
= MPLS_LIST_NEXT(&g
->nexthop
, nhp
, _global
);
1278 MPLS_LIST_ADD_TAIL(&g
->nexthop
, nh
, _global
, ldp_nexthop
);
1281 void _ldp_global_del_nexthop(ldp_global
* g
, ldp_nexthop
* nh
)
1283 MPLS_ASSERT(g
&& nh
);
1284 MPLS_LIST_REMOVE(&g
->nexthop
, nh
, _global
);