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(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 fprintf(stderr
,"entity delete\n");
84 MPLS_REFCNT_ASSERT(e
, 0);
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 (e
->inherit_flag
& LDP_ENTITY_CFG_TRANS_ADDR
) {
139 memcpy(&e
->transport_address
,&g
->transport_address
,sizeof(mpls_inet_addr
));
141 if (e
->inherit_flag
& LDP_ENTITY_CFG_KEEPALIVE_TIMER
) {
142 e
->keepalive_timer
= g
->keepalive_timer
;
144 if (e
->inherit_flag
& LDP_ENTITY_CFG_KEEPALIVE_INTERVAL
) {
145 e
->keepalive_interval
= g
->keepalive_interval
;
147 if (e
->inherit_flag
& LDP_ENTITY_CFG_HELLOTIME_TIMER
) {
148 e
->hellotime_timer
= g
->hellotime_timer
;
150 if (e
->inherit_flag
& LDP_ENTITY_CFG_HELLOTIME_INTERVAL
) {
151 e
->hellotime_interval
= g
->hellotime_interval
;
154 e
->loop_detection_mode
= g
->loop_detection_mode
;
156 switch (e
->entity_type
) {
158 retval
= ldp_if_startup(g
, e
->p
.iff
);
161 retval
= ldp_peer_startup(g
, e
->p
.peer
);
167 if (retval
== MPLS_SUCCESS
) {
168 e
->admin_state
= MPLS_ADMIN_ENABLE
;
171 LDP_EXIT(g
->user_data
, "ldp_entity_startup");
176 mpls_return_enum
ldp_entity_shutdown(ldp_global
* g
, ldp_entity
* e
, int flag
)
182 LDP_ENTER(g
->user_data
, "ldp_entity_shutdown");
184 /* flag is only set if the global entity is being disabled */
186 e
->admin_state
= MPLS_ADMIN_DISABLE
;
189 switch (e
->entity_type
) {
191 if (ldp_if_shutdown(g
, e
->p
.iff
) != MPLS_SUCCESS
) {
192 LDP_PRINT(g
->user_data
, "ldp_entity_shutdown: shut down of if failed\n");
196 if (ldp_peer_shutdown(g
, e
->p
.peer
) != MPLS_SUCCESS
) {
197 LDP_PRINT(g
->user_data
, "ldp_entity_shutdown: shut down of peer failed\n");
204 while ((adj
= MPLS_LIST_HEAD(&e
->adj_root
))) {
205 /* ldp_adj_shutdown() does a ldp_entity_del_adj(e,adj) */
206 ldp_adj_shutdown(g
, adj
);
209 LDP_EXIT(g
->user_data
, "ldp_entity_shutdown");
214 uint32_t _ldp_entity_get_next_index()
216 uint32_t retval
= _ldp_entity_next_index
;
218 _ldp_entity_next_index
++;
219 if (retval
> _ldp_entity_next_index
) {
220 _ldp_entity_next_index
= 1;
225 void ldp_entity_add_if(ldp_entity
* e
, ldp_if
* i
)
227 MPLS_ASSERT(e
&& i
&& e
->entity_type
== LDP_UNKNOWN
);
229 e
->entity_type
= LDP_DIRECT
;
232 e
->sub_index
= i
->index
;
233 _ldp_if_add_entity(i
, e
);
236 void ldp_entity_del_if(ldp_global
* g
, ldp_entity
* e
)
238 MPLS_ASSERT(e
&& e
->entity_type
== LDP_DIRECT
&& e
->p
.iff
);
239 _ldp_if_del_entity(e
->p
.iff
);
240 MPLS_REFCNT_RELEASE2(g
, e
->p
.iff
, ldp_if_delete
);
242 e
->entity_type
= LDP_UNKNOWN
;
246 void ldp_entity_add_peer(ldp_entity
* e
, ldp_peer
* p
)
248 MPLS_ASSERT(e
&& e
->entity_type
== LDP_UNKNOWN
);
250 e
->entity_type
= LDP_INDIRECT
;
253 e
->sub_index
= p
->index
;
254 _ldp_peer_add_entity(p
, e
);
257 void ldp_entity_del_peer(ldp_entity
* e
)
259 MPLS_ASSERT(e
&& e
->entity_type
== LDP_INDIRECT
&& e
->p
.peer
);
260 _ldp_peer_del_entity(e
->p
.peer
);
261 MPLS_REFCNT_RELEASE(e
->p
.peer
, ldp_peer_delete
);
263 e
->entity_type
= LDP_UNKNOWN
;
267 void ldp_entity_add_adj(ldp_entity
* e
, ldp_adj
* a
)
274 _ldp_adj_add_entity(a
, e
);
275 ap
= MPLS_LIST_HEAD(&e
->adj_root
);
277 if (ap
->index
> a
->index
) {
278 MPLS_LIST_INSERT_BEFORE(&e
->adj_root
, ap
, a
, _entity
);
281 ap
= MPLS_LIST_NEXT(&e
->adj_root
, ap
, _entity
);
283 MPLS_LIST_ADD_TAIL(&e
->adj_root
, a
, _entity
, ldp_adj
);
286 void ldp_entity_del_adj(ldp_entity
* e
, ldp_adj
* a
)
289 MPLS_LIST_REMOVE(&e
->adj_root
, a
, _entity
);
290 _ldp_adj_del_entity(a
, e
);
291 MPLS_REFCNT_RELEASE(a
, ldp_adj_delete
);
294 ldp_adj
*ldp_entity_find_adj(ldp_entity
* e
, ldp_mesg
* msg
)
297 mpls_inet_addr lsraddr
;
302 ldp_mesg_hdr_get_labelspace(msg
, &labelspace
);
303 ldp_mesg_hdr_get_lsraddr(msg
, &lsraddr
);
305 a
= MPLS_LIST_HEAD(&e
->adj_root
);
307 if (a
->remote_label_space
== labelspace
&&
308 (!mpls_inet_addr_compare(&lsraddr
, &a
->remote_lsr_address
))) {
311 a
= MPLS_LIST_NEXT(&e
->adj_root
, a
, _entity
);