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
12 #include <netinet/in.h>
14 #include "ldp_struct.h"
15 #include "mpls_assert.h"
16 #include "ldp_session.h"
17 #include "ldp_global.h"
18 #include "ldp_entity.h"
19 #include "ldp_hello.h"
23 #include "ldp_inet_addr.h"
27 #include "mpls_mm_impl.h"
28 #include "mpls_timer_impl.h"
29 #include "mpls_socket_impl.h"
30 #include "mpls_trace_impl.h"
32 static uint32_t _ldp_entity_next_index
= 1;
34 void ldp_entity_set_defaults(ldp_entity
*e
) {
35 memset(e
, 0, sizeof(ldp_entity
));
37 e
->entity_type
= LDP_UNKNOWN
;
39 if (LDP_ENTITY_DEF_TRANS_ADDR
!= 0) {
40 e
->transport_address
.type
= MPLS_FAMILY_IPV4
;
41 e
->transport_address
.u
.ipv4
= LDP_ENTITY_DEF_TRANS_ADDR
;
43 e
->protocol_version
= LDP_ENTITY_DEF_PROTO_VER
;
44 e
->remote_tcp_port
= LDP_ENTITY_DEF_REMOTE_TCP
;
45 e
->remote_udp_port
= LDP_ENTITY_DEF_REMOTE_UDP
;
46 e
->max_pdu
= LDP_ENTITY_DEF_MAX_PDU
;
47 e
->keepalive_timer
= LDP_ENTITY_DEF_KEEPALIVE_TIMER
;
48 e
->keepalive_interval
= LDP_ENTITY_DEF_KEEPALIVE_INTERVAL
;
49 e
->hellotime_timer
= LDP_ENTITY_DEF_HELLOTIME_TIMER
;
50 e
->hellotime_interval
= LDP_ENTITY_DEF_HELLOTIME_INTERVAL
;
51 e
->session_setup_count
= LDP_ENTITY_DEF_SESSIONSETUP_COUNT
;
52 e
->session_backoff_timer
= LDP_ENTITY_DEF_SESSION_BACKOFF_TIMER
;
53 e
->label_distribution_mode
= LDP_ENTITY_DEF_DISTRIBUTION_MODE
;
54 e
->path_vector_limit
= LDP_ENTITY_DEF_PATHVECTOR_LIMIT
;
55 e
->hop_count_limit
= LDP_ENTITY_DEF_HOPCOUNT_LIMIT
;
56 e
->label_request_timer
= LDP_ENTITY_DEF_REQUEST_TIMER
;
57 e
->label_request_count
= LDP_ENTITY_DEF_REQUEST_COUNT
;
58 e
->inherit_flag
= LDP_ENTITY_DEF_INHERIT_FLAG
;
59 e
->admin_state
= MPLS_ADMIN_DISABLE
;
60 e
->remote_in_ttl_less_domain
= MPLS_BOOL_FALSE
;
61 e
->request_retry
= LDP_ENTITY_DEF_REQUEST_RETRY
;
64 ldp_entity
*ldp_entity_create()
66 ldp_entity
*e
= (ldp_entity
*) mpls_malloc(MTYPE_LDP_ENTITY
, sizeof(ldp_entity
));
69 memset(e
, 0, sizeof(ldp_entity
));
70 ldp_entity_set_defaults(e
);
72 MPLS_REFCNT_INIT(e
, 0);
73 MPLS_LIST_ELEM_INIT(e
, _global
);
74 MPLS_LIST_INIT(&e
->adj_root
, ldp_adj
);
76 e
->index
= _ldp_entity_get_next_index();
81 void ldp_entity_delete(ldp_entity
* e
)
83 LDP_PRINT(NULL
, "entity delete %p", e
);
84 MPLS_REFCNT_ASSERT(e
, 0);
85 mpls_free(MTYPE_LDP_ENTITY
, e
);
88 int ldp_entity_label_space(ldp_entity
* e
)
91 switch (e
->entity_type
) {
93 return e
->p
.iff
->label_space
;
95 return e
->p
.peer
->label_space
;
103 mpls_bool
ldp_entity_is_active(ldp_entity
* e
)
105 if (e
&& e
->admin_state
== MPLS_ADMIN_ENABLE
)
106 return MPLS_BOOL_TRUE
;
108 return MPLS_BOOL_FALSE
;
111 mpls_bool
ldp_entity_is_ready(ldp_entity
* e
)
114 switch (e
->entity_type
) {
117 return MPLS_BOOL_TRUE
;
121 return MPLS_BOOL_TRUE
;
127 return MPLS_BOOL_FALSE
;
130 mpls_return_enum
ldp_entity_startup(ldp_global
* g
, ldp_entity
* e
)
132 mpls_return_enum retval
= MPLS_FAILURE
;
134 MPLS_ASSERT(g
&& e
&& e
->p
.iff
);
136 LDP_ENTER(g
->user_data
, "ldp_entity_startup");
138 if (g
->admin_state
== MPLS_ADMIN_ENABLE
) {
139 if (e
->inherit_flag
& LDP_ENTITY_CFG_TRANS_ADDR
) {
140 memcpy(&e
->transport_address
, &g
->transport_address
,
141 sizeof(mpls_inet_addr
));
143 if (e
->inherit_flag
& LDP_ENTITY_CFG_KEEPALIVE_TIMER
) {
144 e
->keepalive_timer
= g
->keepalive_timer
;
146 if (e
->inherit_flag
& LDP_ENTITY_CFG_KEEPALIVE_INTERVAL
) {
147 e
->keepalive_interval
= g
->keepalive_interval
;
149 if (e
->inherit_flag
& LDP_ENTITY_CFG_HELLOTIME_TIMER
) {
150 e
->hellotime_timer
= g
->hellotime_timer
;
152 if (e
->inherit_flag
& LDP_ENTITY_CFG_HELLOTIME_INTERVAL
) {
153 e
->hellotime_interval
= g
->hellotime_interval
;
156 e
->loop_detection_mode
= g
->loop_detection_mode
;
158 switch (e
->entity_type
) {
160 retval
= ldp_if_startup(g
, e
->p
.iff
);
163 retval
= ldp_peer_startup(g
, e
->p
.peer
);
169 LDP_PRINT(g
->user_data
, "ldp_entity_startup: global not enabled\n");
170 retval
= MPLS_SUCCESS
;
173 if (retval
== MPLS_SUCCESS
) {
174 e
->admin_state
= MPLS_ADMIN_ENABLE
;
177 LDP_EXIT(g
->user_data
, "ldp_entity_startup");
182 mpls_return_enum
ldp_entity_shutdown(ldp_global
* g
, ldp_entity
* e
,
189 LDP_ENTER(g
->user_data
, "ldp_entity_shutdown");
191 if (g
->admin_state
== MPLS_ADMIN_ENABLE
) {
192 if (!global_shutdown
) {
193 e
->admin_state
= MPLS_ADMIN_DISABLE
;
196 switch (e
->entity_type
) {
198 if (ldp_if_shutdown(g
, e
->p
.iff
) != MPLS_SUCCESS
) {
199 LDP_PRINT(g
->user_data
,
200 "ldp_entity_shutdown: shut down of if failed\n");
204 if (ldp_peer_shutdown(g
, e
->p
.peer
) != MPLS_SUCCESS
) {
205 LDP_PRINT(g
->user_data
,
206 "ldp_entity_shutdown: shut down of peer failed\n");
213 while ((adj
= MPLS_LIST_HEAD(&e
->adj_root
))) {
214 /* ldp_adj_shutdown() does a ldp_entity_del_adj(e,adj) */
215 ldp_adj_shutdown(g
, adj
);
218 LDP_PRINT(g
->user_data
, "ldp_entity_shutdown: global not enabled\n");
219 e
->admin_state
= MPLS_ADMIN_DISABLE
;
222 LDP_EXIT(g
->user_data
, "ldp_entity_shutdown");
227 uint32_t _ldp_entity_get_next_index()
229 uint32_t retval
= _ldp_entity_next_index
;
231 _ldp_entity_next_index
++;
232 if (retval
> _ldp_entity_next_index
) {
233 _ldp_entity_next_index
= 1;
238 void ldp_entity_add_if(ldp_entity
* e
, ldp_if
* i
)
240 MPLS_ASSERT(e
&& i
&& e
->entity_type
== LDP_UNKNOWN
);
242 e
->entity_type
= LDP_DIRECT
;
245 e
->sub_index
= i
->index
;
246 _ldp_if_add_entity(i
, e
);
249 void ldp_entity_del_if(ldp_global
* g
, ldp_entity
* e
)
251 MPLS_ASSERT(e
&& e
->entity_type
== LDP_DIRECT
&& e
->p
.iff
);
252 _ldp_if_del_entity(e
->p
.iff
);
253 MPLS_REFCNT_RELEASE2(g
, e
->p
.iff
, ldp_if_delete
);
255 e
->entity_type
= LDP_UNKNOWN
;
259 void ldp_entity_add_peer(ldp_entity
* e
, ldp_peer
* p
)
261 MPLS_ASSERT(e
&& e
->entity_type
== LDP_UNKNOWN
);
263 e
->entity_type
= LDP_INDIRECT
;
266 e
->sub_index
= p
->index
;
267 _ldp_peer_add_entity(p
, e
);
270 void ldp_entity_del_peer(ldp_entity
* e
)
272 MPLS_ASSERT(e
&& e
->entity_type
== LDP_INDIRECT
&& e
->p
.peer
);
273 _ldp_peer_del_entity(e
->p
.peer
);
274 MPLS_REFCNT_RELEASE(e
->p
.peer
, ldp_peer_delete
);
276 e
->entity_type
= LDP_UNKNOWN
;
280 void ldp_entity_add_adj(ldp_entity
* e
, ldp_adj
* a
)
287 _ldp_adj_add_entity(a
, e
);
288 ap
= MPLS_LIST_HEAD(&e
->adj_root
);
290 if (ap
->index
> a
->index
) {
291 MPLS_LIST_INSERT_BEFORE(&e
->adj_root
, ap
, a
, _entity
);
294 ap
= MPLS_LIST_NEXT(&e
->adj_root
, ap
, _entity
);
296 MPLS_LIST_ADD_TAIL(&e
->adj_root
, a
, _entity
, ldp_adj
);
299 void ldp_entity_del_adj(ldp_entity
* e
, ldp_adj
* a
)
302 MPLS_LIST_REMOVE(&e
->adj_root
, a
, _entity
);
303 _ldp_adj_del_entity(a
, e
);
304 MPLS_REFCNT_RELEASE(a
, ldp_adj_delete
);
307 ldp_adj
*ldp_entity_find_adj(ldp_entity
* e
, ldp_mesg
* msg
)
310 mpls_inet_addr lsraddr
;
315 ldp_mesg_hdr_get_labelspace(msg
, &labelspace
);
316 ldp_mesg_hdr_get_lsraddr(msg
, &lsraddr
);
318 a
= MPLS_LIST_HEAD(&e
->adj_root
);
320 if (a
->remote_label_space
== labelspace
&&
321 (!mpls_inet_addr_compare(&lsraddr
, &a
->remote_lsr_address
))) {
324 a
= MPLS_LIST_NEXT(&e
->adj_root
, a
, _entity
);