Re-work iff, addr, fec, nexthop life cycle.
[mpls-ldp-portable.git] / ldp / ldp_entity.c
blob864563292bf7faafb444f62687f67375e0f83a8e
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 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();
78 return e;
81 void ldp_entity_delete(ldp_entity * e)
83 fprintf(stderr,"entity delete\n");
84 MPLS_REFCNT_ASSERT(e, 0);
85 mpls_free(e);
88 int ldp_entity_label_space(ldp_entity * e)
90 if (e) {
91 switch (e->entity_type) {
92 case LDP_DIRECT:
93 return e->p.iff->label_space;
94 case LDP_INDIRECT:
95 return e->p.peer->label_space;
96 default:
97 MPLS_ASSERT(0);
100 return -1;
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)
113 if (e) {
114 switch (e->entity_type) {
115 case LDP_DIRECT:
116 if (e->p.iff)
117 return MPLS_BOOL_TRUE;
118 break;
119 case LDP_INDIRECT:
120 if (e->p.peer)
121 return MPLS_BOOL_TRUE;
122 break;
123 default:
124 MPLS_ASSERT(0);
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) {
157 case LDP_DIRECT:
158 retval = ldp_if_startup(g, e->p.iff);
159 break;
160 case LDP_INDIRECT:
161 retval = ldp_peer_startup(g, e->p.peer);
162 break;
163 default:
164 MPLS_ASSERT(0);
167 if (retval == MPLS_SUCCESS) {
168 e->admin_state = MPLS_ADMIN_ENABLE;
171 LDP_EXIT(g->user_data, "ldp_entity_startup");
173 return retval;
176 mpls_return_enum ldp_entity_shutdown(ldp_global * g, ldp_entity * e, int flag)
178 ldp_adj *adj = NULL;
180 MPLS_ASSERT(g && e);
182 LDP_ENTER(g->user_data, "ldp_entity_shutdown");
184 /* flag is only set if the global entity is being disabled */
185 if (!flag) {
186 e->admin_state = MPLS_ADMIN_DISABLE;
189 switch (e->entity_type) {
190 case LDP_DIRECT:
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");
194 break;
195 case LDP_INDIRECT:
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");
199 break;
200 default:
201 MPLS_ASSERT(0);
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");
211 return MPLS_SUCCESS;
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;
222 return retval;
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;
230 MPLS_REFCNT_HOLD(i);
231 e->p.iff = i;
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);
241 e->p.iff = NULL;
242 e->entity_type = LDP_UNKNOWN;
243 e->sub_index = 0;
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;
251 MPLS_REFCNT_HOLD(p);
252 e->p.peer = p;
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);
262 e->p.peer = NULL;
263 e->entity_type = LDP_UNKNOWN;
264 e->sub_index = 0;
267 void ldp_entity_add_adj(ldp_entity * e, ldp_adj * a)
269 ldp_adj *ap = NULL;
271 MPLS_ASSERT(e && a);
272 MPLS_REFCNT_HOLD(a);
274 _ldp_adj_add_entity(a, e);
275 ap = MPLS_LIST_HEAD(&e->adj_root);
276 while (ap) {
277 if (ap->index > a->index) {
278 MPLS_LIST_INSERT_BEFORE(&e->adj_root, ap, a, _entity);
279 return;
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)
288 MPLS_ASSERT(e && 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)
296 ldp_adj *a = NULL;
297 mpls_inet_addr lsraddr;
298 int labelspace;
300 MPLS_ASSERT(e);
302 ldp_mesg_hdr_get_labelspace(msg, &labelspace);
303 ldp_mesg_hdr_get_lsraddr(msg, &lsraddr);
305 a = MPLS_LIST_HEAD(&e->adj_root);
306 while (a != NULL) {
307 if (a->remote_label_space == labelspace &&
308 (!mpls_inet_addr_compare(&lsraddr, &a->remote_lsr_address))) {
309 return a;
311 a = MPLS_LIST_NEXT(&e->adj_root, a, _entity);
314 return NULL;