3 * Copyright (C) James R. Leu 2000
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
11 #include <sys/socket.h>
12 #include "ldp_struct.h"
13 #include "ldp_entity.h"
15 #include "ldp_hello.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
));
59 memset(p
, 0, sizeof(ldp_peer
));
60 MPLS_REFCNT_INIT(p
, 0);
61 MPLS_LIST_ELEM_INIT(p
, _global
);
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
;
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
);
82 mpls_return_enum
ldp_peer_startup(ldp_global
* g
, ldp_peer
* p
)
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");
104 ldp_peer_startup_retry
:
106 /* start a timer which will retry peer startup */
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
) ==
114 MPLS_REFCNT_RELEASE(p
, ldp_peer_delete
);
115 LDP_EXIT(g
->user_data
, "ldp_peer_startup-error");
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");
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
) ==
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
) ==
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
);
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");
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
)
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
);
208 ldp_entity
*ldp_peer_get_entity(ldp_peer
* p
)
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;