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 ldp_entity_set_defaults(e
);
71 MPLS_REFCNT_INIT(e
, 0);
72 MPLS_LIST_INIT(&e
->adj_root
, ldp_adj
);
73 MPLS_LIST_ELEM_INIT(e
, _global
);
75 e
->index
= _ldp_entity_get_next_index();
80 void ldp_entity_delete(ldp_entity
* e
)
82 fprintf(stderr
,"entity delete\n");
83 MPLS_REFCNT_ASSERT(e
, 0);
87 int ldp_entity_label_space(ldp_entity
* e
)
90 switch (e
->entity_type
) {
92 return e
->p
.iff
->label_space
;
94 return e
->p
.peer
->label_space
;
102 mpls_bool
ldp_entity_is_active(ldp_entity
* e
)
104 if (e
&& e
->admin_state
== MPLS_ADMIN_ENABLE
)
105 return MPLS_BOOL_TRUE
;
107 return MPLS_BOOL_FALSE
;
110 mpls_bool
ldp_entity_is_ready(ldp_entity
* e
)
113 switch (e
->entity_type
) {
116 return MPLS_BOOL_TRUE
;
120 return MPLS_BOOL_TRUE
;
126 return MPLS_BOOL_FALSE
;
129 mpls_return_enum
ldp_entity_startup(ldp_global
* g
, ldp_entity
* e
)
131 mpls_return_enum retval
= MPLS_FAILURE
;
133 MPLS_ASSERT(g
&& e
&& e
->p
.iff
);
135 LDP_ENTER(g
->user_data
, "ldp_entity_startup");
137 if (e
->inherit_flag
& LDP_ENTITY_CFG_TRANS_ADDR
) {
138 memcpy(&e
->transport_address
,&g
->transport_address
,sizeof(mpls_inet_addr
));
140 if (e
->inherit_flag
& LDP_ENTITY_CFG_KEEPALIVE_TIMER
) {
141 e
->keepalive_timer
= g
->keepalive_timer
;
143 if (e
->inherit_flag
& LDP_ENTITY_CFG_KEEPALIVE_INTERVAL
) {
144 e
->keepalive_interval
= g
->keepalive_interval
;
146 if (e
->inherit_flag
& LDP_ENTITY_CFG_HELLOTIME_TIMER
) {
147 e
->hellotime_timer
= g
->hellotime_timer
;
149 if (e
->inherit_flag
& LDP_ENTITY_CFG_HELLOTIME_INTERVAL
) {
150 e
->hellotime_interval
= g
->hellotime_interval
;
153 e
->loop_detection_mode
= g
->loop_detection_mode
;
155 switch (e
->entity_type
) {
157 retval
= ldp_if_startup(g
, e
->p
.iff
);
160 retval
= ldp_peer_startup(g
, e
->p
.peer
);
166 if (retval
== MPLS_SUCCESS
) {
167 e
->admin_state
= MPLS_ADMIN_ENABLE
;
170 LDP_EXIT(g
->user_data
, "ldp_entity_startup");
175 mpls_return_enum
ldp_entity_shutdown(ldp_global
* g
, ldp_entity
* e
, int flag
)
181 LDP_ENTER(g
->user_data
, "ldp_entity_shutdown");
183 /* flag is only set if the global entity is being disabled */
185 e
->admin_state
= MPLS_ADMIN_DISABLE
;
188 switch (e
->entity_type
) {
190 if (ldp_if_shutdown(g
, e
->p
.iff
) != MPLS_SUCCESS
) {
191 LDP_PRINT(g
->user_data
, "ldp_entity_shutdown: shut down of if failed\n");
195 if (ldp_peer_shutdown(g
, e
->p
.peer
) != MPLS_SUCCESS
) {
196 LDP_PRINT(g
->user_data
, "ldp_entity_shutdown: shut down of peer failed\n");
203 while ((adj
= MPLS_LIST_HEAD(&e
->adj_root
))) {
204 /* ldp_adj_shutdown() does a ldp_entity_del_adj(e,adj) */
205 ldp_adj_shutdown(g
, adj
);
208 LDP_EXIT(g
->user_data
, "ldp_entity_shutdown");
213 uint32_t _ldp_entity_get_next_index()
215 uint32_t retval
= _ldp_entity_next_index
;
217 _ldp_entity_next_index
++;
218 if (retval
> _ldp_entity_next_index
) {
219 _ldp_entity_next_index
= 1;
224 void ldp_entity_add_if(ldp_entity
* e
, ldp_if
* i
)
226 MPLS_ASSERT(e
&& i
&& e
->entity_type
== LDP_UNKNOWN
);
228 e
->entity_type
= LDP_DIRECT
;
231 e
->sub_index
= i
->index
;
232 _ldp_if_add_entity(i
, e
);
235 void ldp_entity_del_if(ldp_global
* g
, ldp_entity
* e
)
237 MPLS_ASSERT(e
&& e
->entity_type
== LDP_DIRECT
&& e
->p
.iff
);
238 _ldp_if_del_entity(e
->p
.iff
);
239 MPLS_REFCNT_RELEASE2(g
, e
->p
.iff
, ldp_if_delete
);
241 e
->entity_type
= LDP_UNKNOWN
;
245 void ldp_entity_add_peer(ldp_entity
* e
, ldp_peer
* p
)
247 MPLS_ASSERT(e
&& e
->entity_type
== LDP_UNKNOWN
);
249 e
->entity_type
= LDP_INDIRECT
;
252 e
->sub_index
= p
->index
;
253 _ldp_peer_add_entity(p
, e
);
256 void ldp_entity_del_peer(ldp_entity
* e
)
258 MPLS_ASSERT(e
&& e
->entity_type
== LDP_INDIRECT
&& e
->p
.peer
);
259 _ldp_peer_del_entity(e
->p
.peer
);
260 MPLS_REFCNT_RELEASE(e
->p
.peer
, ldp_peer_delete
);
262 e
->entity_type
= LDP_UNKNOWN
;
266 void ldp_entity_add_adj(ldp_entity
* e
, ldp_adj
* a
)
273 _ldp_adj_add_entity(a
, e
);
274 ap
= MPLS_LIST_HEAD(&e
->adj_root
);
276 if (ap
->index
> a
->index
) {
277 MPLS_LIST_INSERT_BEFORE(&e
->adj_root
, ap
, a
, _entity
);
280 ap
= MPLS_LIST_NEXT(&e
->adj_root
, ap
, _entity
);
282 MPLS_LIST_ADD_TAIL(&e
->adj_root
, a
, _entity
, ldp_adj
);
285 void ldp_entity_del_adj(ldp_entity
* e
, ldp_adj
* a
)
288 MPLS_LIST_REMOVE(&e
->adj_root
, a
, _entity
);
289 _ldp_adj_del_entity(a
, e
);
290 MPLS_REFCNT_RELEASE(a
, ldp_adj_delete
);
293 ldp_adj
*ldp_entity_find_adj(ldp_entity
* e
, ldp_mesg
* msg
)
296 mpls_inet_addr lsraddr
;
301 ldp_mesg_hdr_get_labelspace(msg
, &labelspace
);
302 ldp_mesg_hdr_get_lsraddr(msg
, &lsraddr
);
304 a
= MPLS_LIST_HEAD(&e
->adj_root
);
306 if (a
->remote_label_space
== labelspace
&&
307 (!mpls_inet_addr_compare(&lsraddr
, &a
->remote_lsr_address
))) {
310 a
= MPLS_LIST_NEXT(&e
->adj_root
, a
, _entity
);