Changed the relationship between entity-adj-sessios (again)
[mpls-ldp-portable.git] / ldp / ldp_entity.c
blob94fe0b92bc77ab3f6ad02828538bd0edb5c955b2
2 /*
3 * Copyright (C) James R. Leu 2000
4 * jleu@mindspring.com
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
8 */
10 #include <stdlib.h>
11 #include <string.h>
12 #include <netinet/in.h>
13 #include <stdio.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"
20 #include "ldp_peer.h"
21 #include "ldp_adj.h"
22 #include "ldp_if.h"
23 #include "ldp_inet_addr.h"
24 #include "ldp_mesg.h"
25 #include "ldp_cfg.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));
68 if (e) {
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();
77 return e;
80 void ldp_entity_delete(ldp_entity * e)
82 fprintf(stderr,"entity delete\n");
83 MPLS_REFCNT_ASSERT(e, 0);
84 mpls_free(e);
87 int ldp_entity_label_space(ldp_entity * e)
89 if (e) {
90 switch (e->entity_type) {
91 case LDP_DIRECT:
92 return e->p.iff->label_space;
93 case LDP_INDIRECT:
94 return e->p.peer->label_space;
95 default:
96 MPLS_ASSERT(0);
99 return -1;
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)
112 if (e) {
113 switch (e->entity_type) {
114 case LDP_DIRECT:
115 if (e->p.iff)
116 return MPLS_BOOL_TRUE;
117 break;
118 case LDP_INDIRECT:
119 if (e->p.peer)
120 return MPLS_BOOL_TRUE;
121 break;
122 default:
123 MPLS_ASSERT(0);
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) {
156 case LDP_DIRECT:
157 retval = ldp_if_startup(g, e->p.iff);
158 break;
159 case LDP_INDIRECT:
160 retval = ldp_peer_startup(g, e->p.peer);
161 break;
162 default:
163 MPLS_ASSERT(0);
166 if (retval == MPLS_SUCCESS) {
167 e->admin_state = MPLS_ADMIN_ENABLE;
170 LDP_EXIT(g->user_data, "ldp_entity_startup");
172 return retval;
175 mpls_return_enum ldp_entity_shutdown(ldp_global * g, ldp_entity * e, int flag)
177 ldp_adj *adj = NULL;
179 MPLS_ASSERT(g && e);
181 LDP_ENTER(g->user_data, "ldp_entity_shutdown");
183 /* flag is only set if the global entity is being disabled */
184 if (!flag) {
185 e->admin_state = MPLS_ADMIN_DISABLE;
188 switch (e->entity_type) {
189 case LDP_DIRECT:
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");
193 break;
194 case LDP_INDIRECT:
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");
198 break;
199 default:
200 MPLS_ASSERT(0);
203 adj = MPLS_LIST_HEAD(&e->adj_root);
204 while (adj) {
205 /* ldp_adj_shutdown() does a ldp_entity_del_adj(e,adj) */
206 ldp_adj_shutdown(g, adj);
207 adj = MPLS_LIST_NEXT(&e->adj_root, adj, _entity);
210 LDP_EXIT(g->user_data, "ldp_entity_shutdown");
212 return MPLS_SUCCESS;
215 uint32_t _ldp_entity_get_next_index()
217 uint32_t retval = _ldp_entity_next_index;
219 _ldp_entity_next_index++;
220 if (retval > _ldp_entity_next_index) {
221 _ldp_entity_next_index = 1;
223 return retval;
226 void ldp_entity_add_if(ldp_entity * e, ldp_if * i)
228 MPLS_ASSERT(e && i && e->entity_type == LDP_UNKNOWN);
230 e->entity_type = LDP_DIRECT;
231 MPLS_REFCNT_HOLD(i);
232 e->p.iff = i;
233 e->sub_index = i->index;
234 _ldp_if_add_entity(i, e);
237 void ldp_entity_del_if(ldp_entity * e)
239 MPLS_ASSERT(e && e->entity_type == LDP_DIRECT && e->p.iff);
240 _ldp_if_del_entity(e->p.iff);
241 MPLS_REFCNT_RELEASE(e->p.iff, ldp_if_delete);
242 e->p.iff = NULL;
243 e->entity_type = LDP_UNKNOWN;
244 e->sub_index = 0;
247 void ldp_entity_add_peer(ldp_entity * e, ldp_peer * p)
249 MPLS_ASSERT(e && e->entity_type == LDP_UNKNOWN);
251 e->entity_type = LDP_INDIRECT;
252 MPLS_REFCNT_HOLD(p);
253 e->p.peer = p;
254 e->sub_index = p->index;
255 _ldp_peer_add_entity(p, e);
258 void ldp_entity_del_peer(ldp_entity * e)
260 MPLS_ASSERT(e && e->entity_type == LDP_INDIRECT && e->p.peer);
261 _ldp_peer_del_entity(e->p.peer);
262 MPLS_REFCNT_RELEASE(e->p.peer, ldp_peer_delete);
263 e->p.peer = NULL;
264 e->entity_type = LDP_UNKNOWN;
265 e->sub_index = 0;
268 void ldp_entity_add_adj(ldp_entity * e, ldp_adj * a)
270 ldp_adj *ap = NULL;
272 MPLS_ASSERT(e && a);
273 MPLS_REFCNT_HOLD(a);
275 _ldp_adj_add_entity(a, e);
276 ap = MPLS_LIST_HEAD(&e->adj_root);
277 while (ap) {
278 if (ap->index > a->index) {
279 MPLS_LIST_INSERT_BEFORE(&e->adj_root, ap, a, _entity);
280 return;
282 ap = MPLS_LIST_NEXT(&e->adj_root, ap, _entity);
284 MPLS_LIST_ADD_TAIL(&e->adj_root, a, _entity, ldp_adj);
287 void ldp_entity_del_adj(ldp_entity * e, ldp_adj * a)
289 MPLS_ASSERT(e && a);
290 MPLS_LIST_REMOVE(&e->adj_root, a, _entity);
291 _ldp_adj_del_entity(a, e);
292 MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
295 ldp_adj *ldp_entity_find_adj(ldp_entity * e, ldp_mesg * msg)
297 ldp_adj *a = NULL;
298 mpls_inet_addr lsraddr;
299 int labelspace;
301 MPLS_ASSERT(e);
303 ldp_mesg_hdr_get_labelspace(msg, &labelspace);
304 ldp_mesg_hdr_get_lsraddr(msg, &lsraddr);
306 a = MPLS_LIST_HEAD(&e->adj_root);
307 while (a != NULL) {
308 if (a->remote_label_space == labelspace &&
309 (!mpls_inet_addr_compare(&lsraddr, &a->remote_lsr_address))) {
310 return a;
312 a = MPLS_LIST_NEXT(&e->adj_root, a, _entity);
315 return NULL;