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 <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"
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
));
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
);
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
;
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
);
65 ldp_if
*ldp_if_insert(ldp_global
*g
, mpls_if_handle handle
)
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");
76 iff
->used_by_fec
= MPLS_BOOL_TRUE
;
78 _ldp_global_add_if(g
, 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
;
96 ldp_nexthop_add_if(n
,i
);
98 np
= MPLS_LIST_HEAD(&i
->nh_root
);
100 if (np
->index
> n
->index
) {
101 MPLS_LIST_INSERT_BEFORE(&i
->nh_root
, np
, n
, _if
);
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
)
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
);
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
);
142 i
->oper_state
= MPLS_OPER_UP
;
144 LDP_EXIT(g
->user_data
, "ldp_if_startup");
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");
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
,
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);
187 ldp_mesg_delete(i
->hello
);
191 LDP_EXIT(g
->user_data
, "ldp_if_shutdown");
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
)
214 ldp_entity
*ldp_if_get_entity(ldp_if
* i
)
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
);
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;