In the case of a route being and there is not an alternate
[mpls-ldp-portable.git] / ldp / ldp_peer.c
blob85f867501c3268e1cbfe5c9440a4fb9a22a223aa
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 <sys/socket.h>
12 #include "ldp_struct.h"
13 #include "ldp_entity.h"
14 #include "ldp_peer.h"
15 #include "ldp_hello.h"
16 #include "ldp_buf.h"
17 #include "ldp_mesg.h"
19 #include "mpls_assert.h"
20 #include "mpls_fib_impl.h"
21 #include "mpls_ifmgr_impl.h"
22 #include "mpls_lock_impl.h"
23 #include "mpls_timer_impl.h"
24 #include "mpls_mm_impl.h"
25 #include "mpls_trace_impl.h"
27 uint32_t _ldp_sub_entity_next_index = 1;
29 void ldp_peer_retry_callback(mpls_timer_handle timer, void *extra,
30 mpls_cfg_handle handle)
32 ldp_peer *p = (ldp_peer *) extra;
33 ldp_global *g = (ldp_global*)handle;
35 LDP_ENTER(g->user_data, "ldp_peer_retry_callback");
37 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
38 "Peer Retry Timer fired: peer(%d)\n", p->index);
40 mpls_lock_get(g->global_lock);
42 /* JLEU: should I hold a copy to make sure this doens't fail? */
43 ldp_peer_retry_stop(g, p);
44 if (ldp_peer_startup(g, p) == MPLS_FAILURE) {
45 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
46 "Peer startup retry failure: peer (%d)\n", p->index);
49 mpls_lock_release(g->global_lock);
51 LDP_EXIT(g->user_data, "ldp_peer_retry_callback");
54 ldp_peer *ldp_peer_create()
56 ldp_peer *p = (ldp_peer *) mpls_malloc(sizeof(ldp_peer));
58 if (p) {
59 memset(p, 0, sizeof(ldp_peer));
60 MPLS_REFCNT_INIT(p, 0);
61 MPLS_LIST_ELEM_INIT(p, _global);
62 p->label_space = -1;
63 p->tx_buffer = ldp_buf_create(MPLS_PDUMAXLEN);
64 p->tx_message = ldp_mesg_create();
65 p->index = _ldp_peer_get_next_index();
67 p->oper_state = MPLS_OPER_DOWN;
68 p->target_role = LDP_ACTIVE;
70 return p;
73 void ldp_peer_delete(ldp_peer * p)
75 // LDP_PRINT(g->user_data,"peer delete\n");
76 MPLS_REFCNT_ASSERT(p, 0);
77 mpls_free(p->tx_buffer);
78 mpls_free(p->tx_message);
79 mpls_free(p);
82 mpls_return_enum ldp_peer_startup(ldp_global * g, ldp_peer * p)
84 ldp_entity *e = NULL;
86 MPLS_ASSERT(p != NULL && ((e = p->entity) != NULL));
88 LDP_ENTER(g->user_data, "ldp_peer_startup");
90 p->dest.port = e->remote_udp_port;
92 if (p->target_role == LDP_ACTIVE) {
93 if (ldp_hello_send(g, e) == MPLS_FAILURE) {
94 goto ldp_peer_startup_retry;
98 p->oper_state = MPLS_OPER_UP;
100 LDP_EXIT(g->user_data, "ldp_peer_startup");
102 return MPLS_SUCCESS;
104 ldp_peer_startup_retry:
106 /* start a timer which will retry peer startup */
107 MPLS_REFCNT_HOLD(p);
108 p->oper_state = MPLS_OPER_DOWN;
109 p->no_route_to_peer_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
110 g->no_route_to_peer_time, (void *)p, g, ldp_peer_retry_callback);
112 if (mpls_timer_handle_verify(g->timer_handle, p->no_route_to_peer_timer) ==
113 MPLS_BOOL_FALSE) {
114 MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
115 LDP_EXIT(g->user_data, "ldp_peer_startup-error");
116 return MPLS_FAILURE;
118 mpls_timer_start(g->timer_handle, p->no_route_to_peer_timer, MPLS_TIMER_ONESHOT);
120 LDP_EXIT(g->user_data, "ldp_peer_startup");
122 return MPLS_SUCCESS;
125 void ldp_peer_retry_stop(ldp_global * g, ldp_peer * p)
127 MPLS_ASSERT(p != NULL);
129 LDP_ENTER(g->user_data, "ldp_peer_retry_stop");
131 if (mpls_timer_handle_verify(g->timer_handle, p->no_route_to_peer_timer) ==
132 MPLS_BOOL_TRUE) {
133 mpls_timer_stop(g->timer_handle, p->no_route_to_peer_timer);
134 mpls_timer_delete(g->timer_handle, p->no_route_to_peer_timer);
135 p->no_route_to_peer_timer = 0;
136 MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
137 MPLS_ASSERT(p != NULL);
140 LDP_EXIT(g->user_data, "ldp_peer_retry_stop");
143 void ldp_peer_send_stop(ldp_global * g, ldp_peer * p)
145 ldp_entity *e = NULL;
147 MPLS_ASSERT(p != NULL && (e = p->entity) != NULL);
149 LDP_ENTER(g->user_data, "ldp_peer_send_stop");
151 if (mpls_timer_handle_verify(g->timer_handle, p->hellotime_send_timer) ==
152 MPLS_BOOL_TRUE) {
153 mpls_timer_stop(g->timer_handle, p->hellotime_send_timer);
154 mpls_timer_delete(g->timer_handle, p->hellotime_send_timer);
155 p->hellotime_send_timer_duration = 0;
156 p->hellotime_send_timer = 0;
157 MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
158 MPLS_ASSERT(e != NULL);
160 if (p->hello != NULL) {
161 ldp_mesg_delete(p->hello);
162 p->hello = NULL;
165 LDP_EXIT(g->user_data, "ldp_peer_send_stop");
168 mpls_return_enum ldp_peer_shutdown(ldp_global * g, ldp_peer * p)
170 LDP_ENTER(g->user_data, "ldp_peer_shutdown");
172 p->oper_state = MPLS_OPER_DOWN;
173 ldp_peer_send_stop(g, p);
174 ldp_peer_retry_stop(g, p);
176 LDP_EXIT(g->user_data, "ldp_peer_shutdown");
177 return MPLS_SUCCESS;
180 mpls_bool ldp_peer_is_active(ldp_peer * p)
182 if (p && p->entity && p->entity->admin_state == MPLS_ADMIN_ENABLE)
183 return MPLS_BOOL_TRUE;
185 return MPLS_BOOL_FALSE;
188 mpls_return_enum _ldp_peer_add_entity(ldp_peer * p, ldp_entity * e)
190 if (p && e) {
191 MPLS_REFCNT_HOLD(e);
192 p->entity = e;
193 return MPLS_SUCCESS;
195 return MPLS_FAILURE;
198 mpls_return_enum _ldp_peer_del_entity(ldp_peer * p)
200 if (p && p->entity) {
201 MPLS_REFCNT_RELEASE(p->entity, ldp_entity_delete);
202 p->entity = NULL;
203 return MPLS_SUCCESS;
205 return MPLS_FAILURE;
208 ldp_entity *ldp_peer_get_entity(ldp_peer * p)
210 return p->entity;
213 uint32_t _ldp_peer_get_next_index()
215 uint32_t retval = _ldp_sub_entity_next_index;
217 _ldp_sub_entity_next_index++;
218 if (retval > _ldp_sub_entity_next_index) {
219 _ldp_sub_entity_next_index = 1;
221 return retval;