Convertion to a ECMP capable infrastructure compiles (no testing
[mpls-ldp-portable.git] / ldp / ldp_if.c
blobd1de02ffeae7c575654f3b8e0eebf2e7f19288d8
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 <netinet/in.h>
12 #include <sys/socket.h>
13 #include "ldp_struct.h"
14 #include "ldp_global.h"
15 #include "ldp_entity.h"
16 #include "ldp_nexthop.h"
17 #include "ldp_nortel.h"
18 #include "ldp_if.h"
19 #include "ldp_fec.h"
20 #include "ldp_mesg.h"
21 #include "ldp_buf.h"
22 #include "ldp_hello.h"
24 #include "mpls_assert.h"
25 #include "mpls_mm_impl.h"
26 #include "mpls_socket_impl.h"
27 #include "mpls_timer_impl.h"
28 #include "mpls_ifmgr_impl.h"
29 #include "mpls_trace_impl.h"
31 extern uint32_t _ldp_sub_entity_next_index;
33 ldp_if *ldp_if_create()
35 ldp_if *i = (ldp_if *) mpls_malloc(sizeof(ldp_if));
37 if (i) {
38 memset(i, 0, sizeof(ldp_if));
39 MPLS_REFCNT_INIT(i, 0);
40 MPLS_LIST_ELEM_INIT(i, _global);
41 MPLS_LIST_INIT(&i->nh_root, ldp_nexthop);
42 i->label_space = -1;
43 i->dest.addr.type = MPLS_FAMILY_IPV4;
44 i->dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
45 i->tx_buffer = ldp_buf_create(MPLS_PDUMAXLEN);
46 i->tx_message = ldp_mesg_create();
47 i->index = _ldp_if_get_next_index();
48 i->oper_state = MPLS_OPER_DOWN;
49 i->used_by_ldp = MPLS_BOOL_FALSE;
50 i->used_by_fec = MPLS_BOOL_FALSE;
51 i->is_p2p = MPLS_BOOL_FALSE;
53 return i;
56 void ldp_if_delete(ldp_if * i)
58 LDP_PRINT(g->user_data,"if delete\n");
59 MPLS_REFCNT_ASSERT(i, 0);
60 mpls_free(i->tx_buffer);
61 mpls_free(i->tx_message);
62 mpls_free(i);
65 ldp_if *ldp_if_insert(ldp_global *g, mpls_if_handle handle)
67 ldp_if *iff = NULL;
69 MPLS_ASSERT(g);
70 MPLS_ASSERT(mpls_if_handle_verify(g->ifmgr_handle, handle) == MPLS_BOOL_TRUE);
72 if ((iff = ldp_if_create()) == NULL) {
73 LDP_PRINT(g->user_data,"ldp_if_insert: unable to alloc ldp_if\n");
74 return NULL;
76 iff->used_by_fec = MPLS_BOOL_TRUE;
77 iff->handle = handle;
78 _ldp_global_add_if(g, iff);
79 return iff;
82 void ldp_if_remove(ldp_global *g, ldp_if *iff)
84 MPLS_ASSERT(g && iff);
85 iff->used_by_fec = MPLS_BOOL_FALSE;
86 _ldp_global_del_if(g, iff);
89 void ldp_if_add_nexthop(ldp_if * i, ldp_nexthop * n)
91 ldp_nexthop *np = NULL;
93 MPLS_ASSERT(i && n);
94 MPLS_REFCNT_HOLD(n);
96 ldp_nexthop_add_if(n,i);
98 np = MPLS_LIST_HEAD(&i->nh_root);
99 while (np != NULL) {
100 if (np->index > n->index) {
101 MPLS_LIST_INSERT_BEFORE(&i->nh_root, np, n, _if);
102 return;
104 np = MPLS_LIST_NEXT(&i->nh_root, np, _if);
106 MPLS_LIST_ADD_TAIL(&i->nh_root, n, _if, ldp_nexthop);
109 void ldp_if_del_nexthop(ldp_if * i, ldp_nexthop * n)
111 MPLS_ASSERT(i && n);
112 MPLS_LIST_REMOVE(&i->nh_root, n, _if);
113 ldp_nexthop_del_if(n);
114 MPLS_REFCNT_RELEASE(n, ldp_nexthop_delete);
117 mpls_return_enum ldp_if_startup(ldp_global * g, ldp_if * i)
119 ldp_entity *e = NULL;
121 LDP_ENTER(g->user_data, "ldp_if_startup");
123 MPLS_ASSERT(i != NULL);
124 e = i->entity;
125 MPLS_ASSERT(e != NULL);
126 MPLS_ASSERT(e->p.iff != NULL);
128 if (mpls_ifmgr_get_address(g->ifmgr_handle, i->handle,
129 &i->local_source_address, NULL, NULL) == MPLS_FAILURE) {
130 goto ldp_if_startup_delay;
132 if (mpls_socket_multicast_if_join(g->socket_handle, g->hello_socket, i,
133 &i->dest.addr) == MPLS_FAILURE) {
134 goto ldp_if_startup_delay;
137 i->dest.port = e->remote_udp_port;
138 if (ldp_hello_send(g, e) == MPLS_FAILURE) {
139 ldp_if_shutdown(g, i);
140 return MPLS_FAILURE;
142 i->oper_state = MPLS_OPER_UP;
144 LDP_EXIT(g->user_data, "ldp_if_startup");
146 return MPLS_SUCCESS;
148 ldp_if_startup_delay:
151 * when a interface update comes in, it will search the global
152 * list of interfaces, and start up the interface then
154 i->oper_state = MPLS_OPER_DOWN;
156 LDP_EXIT(g->user_data, "ldp_if_startup-delayed");
158 return MPLS_SUCCESS;
161 mpls_return_enum ldp_if_shutdown(ldp_global * g, ldp_if * i)
163 ldp_entity *e = NULL;
165 MPLS_ASSERT(i != NULL && ((e = i->entity) != NULL));
167 LDP_ENTER(g->user_data, "ldp_if_shutdown");
169 i->oper_state = MPLS_OPER_DOWN;
171 mpls_socket_multicast_if_drop(g->socket_handle, g->hello_socket, i,
172 &i->dest.addr);
174 mpls_timer_stop(g->timer_handle, i->hellotime_send_timer);
175 mpls_timer_delete(g->timer_handle, i->hellotime_send_timer);
176 i->hellotime_send_timer_duration = 0;
177 i->hellotime_send_timer = 0;
180 * jleu: I'm not sure why these were here, I'm commenting them out,
181 * because I do not see a corresponding HOLD in ldp_if_startup
182 MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
183 MPLS_ASSERT(e != NULL);
186 if (i->hello) {
187 ldp_mesg_delete(i->hello);
188 i->hello = NULL;
191 LDP_EXIT(g->user_data, "ldp_if_shutdown");
193 return MPLS_SUCCESS;
196 mpls_bool ldp_if_is_active(ldp_if * i)
198 if (i && i->entity && i->entity->admin_state == MPLS_ADMIN_ENABLE)
199 return MPLS_BOOL_TRUE;
201 return MPLS_BOOL_FALSE;
204 mpls_return_enum _ldp_if_add_entity(ldp_if * i, ldp_entity * e)
206 if (i && e) {
207 MPLS_REFCNT_HOLD(e);
208 i->entity = e;
209 return MPLS_SUCCESS;
211 return MPLS_FAILURE;
214 ldp_entity *ldp_if_get_entity(ldp_if * i)
216 return i->entity;
219 mpls_return_enum _ldp_if_del_entity(ldp_if * i)
221 if (i && i->entity) {
222 MPLS_REFCNT_RELEASE(i->entity, ldp_entity_delete);
223 i->entity = NULL;
224 return MPLS_SUCCESS;
226 return MPLS_FAILURE;
229 uint32_t _ldp_if_get_next_index()
231 uint32_t retval = _ldp_sub_entity_next_index;
233 _ldp_sub_entity_next_index++;
234 if (retval > _ldp_sub_entity_next_index) {
235 _ldp_sub_entity_next_index = 1;
237 return retval;