Change inlabel outlabel/nexthop, and attr accounting. Specically
[mpls-ldp-portable.git] / ldp / ldp_entity.c
blob804a6a75a6c138d920d98a27d603f624b71922d1
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 (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) {
159 case LDP_DIRECT:
160 retval = ldp_if_startup(g, e->p.iff);
161 break;
162 case LDP_INDIRECT:
163 retval = ldp_peer_startup(g, e->p.peer);
164 break;
165 default:
166 MPLS_ASSERT(0);
168 } else {
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");
179 return retval;
182 mpls_return_enum ldp_entity_shutdown(ldp_global * g, ldp_entity * e,
183 int global_shutdown)
185 ldp_adj *adj = NULL;
187 MPLS_ASSERT(g && 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) {
197 case LDP_DIRECT:
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");
202 break;
203 case LDP_INDIRECT:
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");
208 break;
209 default:
210 MPLS_ASSERT(0);
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);
217 } else {
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");
224 return MPLS_SUCCESS;
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;
235 return retval;
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;
243 MPLS_REFCNT_HOLD(i);
244 e->p.iff = i;
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);
254 e->p.iff = NULL;
255 e->entity_type = LDP_UNKNOWN;
256 e->sub_index = 0;
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;
264 MPLS_REFCNT_HOLD(p);
265 e->p.peer = p;
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);
275 e->p.peer = NULL;
276 e->entity_type = LDP_UNKNOWN;
277 e->sub_index = 0;
280 void ldp_entity_add_adj(ldp_entity * e, ldp_adj * a)
282 ldp_adj *ap = NULL;
284 MPLS_ASSERT(e && a);
285 MPLS_REFCNT_HOLD(a);
287 _ldp_adj_add_entity(a, e);
288 ap = MPLS_LIST_HEAD(&e->adj_root);
289 while (ap) {
290 if (ap->index > a->index) {
291 MPLS_LIST_INSERT_BEFORE(&e->adj_root, ap, a, _entity);
292 return;
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)
301 MPLS_ASSERT(e && 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)
309 ldp_adj *a = NULL;
310 mpls_inet_addr lsraddr;
311 int labelspace;
313 MPLS_ASSERT(e);
315 ldp_mesg_hdr_get_labelspace(msg, &labelspace);
316 ldp_mesg_hdr_get_lsraddr(msg, &lsraddr);
318 a = MPLS_LIST_HEAD(&e->adj_root);
319 while (a != NULL) {
320 if (a->remote_label_space == labelspace &&
321 (!mpls_inet_addr_compare(&lsraddr, &a->remote_lsr_address))) {
322 return a;
324 a = MPLS_LIST_NEXT(&e->adj_root, a, _entity);
327 return NULL;