More RSVP packet decode/encode
[mpls-ldp-portable.git] / ldp / ldp_entity.c
blob1415d3a5041c1246badbfca3e4d9bbab472f0bbc
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 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");
210 return MPLS_SUCCESS;
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;
221 return retval;
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;
229 MPLS_REFCNT_HOLD(i);
230 e->p.iff = i;
231 e->sub_index = i->index;
232 _ldp_if_add_entity(i, e);
235 void ldp_entity_del_if(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_RELEASE(e->p.iff, ldp_if_delete);
240 e->p.iff = NULL;
241 e->entity_type = LDP_UNKNOWN;
242 e->sub_index = 0;
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;
250 MPLS_REFCNT_HOLD(p);
251 e->p.peer = p;
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);
261 e->p.peer = NULL;
262 e->entity_type = LDP_UNKNOWN;
263 e->sub_index = 0;
266 void ldp_entity_add_adj(ldp_entity * e, ldp_adj * a)
268 ldp_adj *ap = NULL;
270 MPLS_ASSERT(e && a);
271 MPLS_REFCNT_HOLD(a);
273 _ldp_adj_add_entity(a, e);
274 ap = MPLS_LIST_HEAD(&e->adj_root);
275 while (ap) {
276 if (ap->index > a->index) {
277 MPLS_LIST_INSERT_BEFORE(&e->adj_root, ap, a, _entity);
278 return;
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)
287 MPLS_ASSERT(e && 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)
295 ldp_adj *a = NULL;
296 mpls_inet_addr lsraddr;
297 int labelspace;
299 MPLS_ASSERT(e);
301 ldp_mesg_hdr_get_labelspace(msg, &labelspace);
302 ldp_mesg_hdr_get_lsraddr(msg, &lsraddr);
304 a = MPLS_LIST_HEAD(&e->adj_root);
305 while (a != NULL) {
306 if (a->remote_label_space == labelspace &&
307 (!mpls_inet_addr_compare(&lsraddr, &a->remote_lsr_address))) {
308 return a;
310 a = MPLS_LIST_NEXT(&e->adj_root, a, _entity);
313 return NULL;