Convert to a generic FEC handling architecture. Part of this change
[mpls-ldp-portable.git] / rsvpte / rsvpte_global.c
blob44b65a66fbe0da4c388c93570b160a8da6195a20
1 /*
2 * Copyright (C) James R. Leu 2003
3 * jleu@mindspring.com
5 * This software is covered under the LGPL, for more
6 * info check out http://www.gnu.org/copyleft/lgpl.html
7 */
9 #include "rsvpte_struct.h"
10 #include "rsvpte_global.h"
11 #include "rsvpte_if.h"
13 #include "mpls_socket_impl.h"
14 #include "mpls_timer_impl.h"
15 #include "mpls_ifmgr_impl.h"
16 #include "mpls_tree_impl.h"
17 #include "mpls_lock_impl.h"
18 #include "mpls_fib_impl.h"
19 #include "mpls_policy_impl.h"
20 #include "mpls_mm_impl.h"
21 #include "mpls_trace_impl.h"
23 #if MPLS_USE_LSR
24 #include "lsr_cfg.h"
25 #else
26 #include "mpls_mpls_impl.h"
27 #endif
29 void _rsvpte_global_fib_callback(mpls_cfg_handle handle, mpls_update_enum type,
30 mpls_fec * dest)
32 rsvpte_global *cfg = (rsvpte_global*)handle;
34 LDP_ENTER(cfg->user_data, "_rsvpte_global_fib_callback");
36 mpls_lock_get(cfg->global_lock);
38 mpls_lock_release(cfg->global_lock);
40 LDP_EXIT(cfg->user_data, "_rsvpte_global_fib_callback");
43 void _rsvpte_global_ifmgr_callback(mpls_cfg_handle handle, const mpls_update_enum type, mpls_inet_addr *addr)
45 rsvpte_global *cfg = (rsvpte_global*)handle;
47 LDP_ENTER(cfg->user_data, "_rsvpte_global_ifmgr_callback");
49 mpls_lock_get(cfg->global_lock);
51 mpls_lock_release(cfg->global_lock);
53 LDP_EXIT(cfg->user_data, "_rsvpte_global_ifmgr_callback");
56 rsvpte_global *rsvpte_global_create(mpls_instance_handle data)
58 rsvpte_global *g = (rsvpte_global *) mpls_malloc(sizeof(rsvpte_global));
60 if (g) {
61 memset(g, 0, sizeof(rsvpte_global));
63 LDP_ENTER(g->user_data, "rsvpte_global_create");
65 g->global_lock = mpls_lock_create("_rsvpte_global_lock_");
66 mpls_lock_get(g->global_lock);
68 MPLS_LIST_INIT(&g->iff, rsvpte_if);
70 g->admin_state = MPLS_ADMIN_DISABLE;
71 g->user_data = data;
73 mpls_lock_release(g->global_lock);
75 LDP_EXIT(g->user_data, "rsvpte_global_create");
78 return g;
81 mpls_return_enum rsvpte_global_startup(rsvpte_global * g)
83 MPLS_ASSERT(g != NULL);
85 LDP_ENTER(g->user_data, "rsvpte_global_startup");
87 if (g->lsr_identifier.type == MPLS_FAMILY_NONE) {
89 * RSVPTE_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, RSVPTE_TRACE_FLAG_ERROR,
90 * "rsvpte_global_startup: invalid LSRID\n");
92 goto rsvpte_global_startup_cleanup;
95 g->timer_handle = mpls_timer_open(g->user_data);
96 if (mpls_timer_mgr_handle_verify(g->timer_handle) == MPLS_BOOL_FALSE) {
97 goto rsvpte_global_startup_cleanup;
100 g->socket_handle = mpls_socket_mgr_open(g->user_data);
101 if (mpls_socket_mgr_handle_verify(g->socket_handle) == MPLS_BOOL_FALSE) {
102 goto rsvpte_global_startup_cleanup;
105 g->ifmgr_handle = mpls_ifmgr_open(g->user_data, g, _rsvpte_global_ifmgr_callback);
106 if (mpls_ifmgr_handle_verify(g->ifmgr_handle) == MPLS_BOOL_FALSE) {
107 goto rsvpte_global_startup_cleanup;
110 g->fib_handle = mpls_fib_open(g->user_data, g);
111 if (mpls_fib_handle_verify(g->fib_handle) == MPLS_BOOL_FALSE) {
112 goto rsvpte_global_startup_cleanup;
115 #if MPLS_USE_LSR
116 if (!g->lsr_handle) {
117 goto rsvpte_global_startup_cleanup;
119 #else
120 g->mpls_handle = mpls_mpls_open(g->user_data);
121 if (mpls_mpls_handle_verify(g->mpls_handle) == MPLS_BOOL_FALSE) {
122 goto rsvpte_global_startup_cleanup;
124 #endif
126 g->ra_socket = mpls_socket_create_raw(g->socket_handle, IPPROTO_RSVP);
127 if (mpls_socket_handle_verify(g->socket_handle, g->ra_socket) == MPLS_BOOL_FALSE) {
129 *RSVPTE_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
130 * RSVPTE_TRACE_FLAG_DEBUG,
131 * "rsvpte_global_startup: error creating UDP socket\n");
133 goto rsvpte_global_startup_cleanup;
136 if (mpls_socket_options(g->socket_handle, g->ra_socket,
137 MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE |
138 MPLS_SOCKOP_ROUTERALERT | MPLS_SOCKOP_HDRINCL) == MPLS_FAILURE) {
140 *RSVPTE_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
141 * RSVPTE_TRACE_FLAG_DEBUG,
142 * "rsvpte_global_startup: error setting RAW socket options\n");
144 goto rsvpte_global_startup_cleanup;
146 mpls_socket_readlist_add(g->socket_handle, g->ra_socket, 0, MPLS_SOCKET_UDP_DATA);
148 g->admin_state = MPLS_ADMIN_ENABLE;
150 LDP_EXIT(g->user_data, "rsvpte_global_startup");
151 return MPLS_SUCCESS;
153 rsvpte_global_startup_cleanup:
154 rsvpte_global_shutdown(g);
155 mpls_socket_close(g->socket_handle, g->ra_socket);
156 g->ra_socket = 0;
158 LDP_EXIT(g->user_data, "rsvpte_global_startup-error");
160 return MPLS_FAILURE;
163 mpls_return_enum rsvpte_global_shutdown(rsvpte_global * g)
165 MPLS_ASSERT(g);
167 LDP_ENTER(g->user_data, "rsvpte_global_shutdown");
169 g->admin_state = MPLS_ADMIN_DISABLE;
171 mpls_socket_readlist_del(g->socket_handle, g->ra_socket);
172 mpls_socket_close(g->socket_handle, g->ra_socket);
174 mpls_lock_release(g->global_lock);
175 mpls_timer_close(g->timer_handle);
176 mpls_lock_get(g->global_lock);
178 mpls_socket_mgr_close(g->socket_handle);
179 mpls_ifmgr_close(g->ifmgr_handle);
180 mpls_fib_close(g->fib_handle);
182 #if MPLS_USE_LSR
183 #else
184 mpls_mpls_close(g->mpls_handle);
185 #endif
187 LDP_EXIT(g->user_data, "rsvpte_global_shutdown");
189 return MPLS_SUCCESS;
192 mpls_return_enum rsvpte_global_delete(rsvpte_global * g)
194 if (g) {
195 mpls_lock_delete(g->global_lock);
196 LDP_PRINT(g->user_data, "global delete\n");
197 mpls_free(g);
199 return MPLS_SUCCESS;
202 void _rsvpte_global_add_if(rsvpte_global * g, rsvpte_if * i)
204 rsvpte_if *ip = NULL;
206 MPLS_ASSERT(g && i);
207 MPLS_REFCNT_HOLD(i);
208 ip = MPLS_LIST_HEAD(&g->iff);
209 while (ip != NULL) {
210 if (ip->index > i->index) {
211 MPLS_LIST_INSERT_BEFORE(&g->iff, ip, i, _global);
212 return;
214 ip = MPLS_LIST_NEXT(&g->iff, ip, _global);
216 MPLS_LIST_ADD_TAIL(&g->iff, i, _global, rsvpte_if);
219 void _rsvpte_global_del_if(rsvpte_global * g, rsvpte_if * i)
221 MPLS_ASSERT(g && i);
222 MPLS_LIST_REMOVE(&g->iff, i, _global);
223 MPLS_REFCNT_RELEASE(i, rsvpte_if_delete);
226 mpls_return_enum rsvpte_global_find_if_index(rsvpte_global * g, uint32_t index,
227 rsvpte_if ** iff)
229 rsvpte_if *i = NULL;
231 if (g && index > 0) {
233 /* because we sort our inserts by index, this lets us know
234 if we've "walked" past the end of the list */
236 i = MPLS_LIST_TAIL(&g->iff);
237 if (i == NULL || i->index < index) {
238 *iff = NULL;
239 return MPLS_END_OF_LIST;
242 i = MPLS_LIST_HEAD(&g->iff);
243 while (i != NULL) {
244 if (i->index == index) {
245 *iff = i;
246 return MPLS_SUCCESS;
248 i = MPLS_LIST_NEXT(&g->iff, i, _global);
251 *iff = NULL;
252 return MPLS_FAILURE;
255 rsvpte_if *rsvpte_global_find_if_handle(rsvpte_global * g, mpls_if_handle handle)
257 rsvpte_if *i = MPLS_LIST_HEAD(&g->iff);
259 if (g) {
260 while (i != NULL) {
261 if (!mpls_if_handle_compare(i->handle, handle))
262 return i;
264 i = MPLS_LIST_NEXT(&g->iff, i, _global);
267 return NULL;