3 * Copyright (C) James R. Leu 2002
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
10 #include "lsr_struct.h"
11 #include "lsr_global.h"
12 #include "lsr_outsegment.h"
13 #include "lsr_insegment.h"
14 #include "lsr_xconnect.h"
18 #include "mpls_ifmgr_impl.h"
19 #include "mpls_mpls_impl.h"
20 #include "mpls_lock_impl.h"
21 #include "mpls_mm_impl.h"
22 #include "mpls_trace_impl.h"
24 lsr_global
*lsr_global_create(mpls_instance_handle data
)
26 lsr_global
*g
= (lsr_global
*) mpls_malloc(sizeof(lsr_global
));
29 memset(g
, 0, sizeof(lsr_global
));
31 LDP_ENTER(g
->user_data
, "lsr_global_create");
33 g
->global_lock
= mpls_lock_create("_lsr_global_lock_");
34 mpls_lock_get(g
->global_lock
);
36 MPLS_LIST_INIT(&g
->outsegment
, lsr_outsegment
);
37 MPLS_LIST_INIT(&g
->insegment
, lsr_insegment
);
38 MPLS_LIST_INIT(&g
->xconnect
, lsr_xconnect
);
39 MPLS_LIST_INIT(&g
->ftn
, lsr_ftn
);
40 MPLS_LIST_INIT(&g
->iff
, lsr_if
);
42 g
->admin_state
= MPLS_ADMIN_DISABLE
;
45 mpls_lock_release(g
->global_lock
);
47 LDP_EXIT(g
->user_data
, "lsr_global_create");
53 mpls_return_enum
lsr_global_startup(lsr_global
* g
)
55 MPLS_ASSERT(g
!= NULL
);
57 LDP_ENTER(g
->user_data
, "lsr_global_startup");
59 g
->ifmgr_handle
= mpls_ifmgr_open(g
->user_data
, g
);
60 if (mpls_ifmgr_handle_verify(g
->ifmgr_handle
) == MPLS_BOOL_FALSE
) {
61 goto lsr_global_startup_cleanup
;
64 g
->mpls_handle
= mpls_mpls_open(g
->user_data
);
65 if (mpls_mpls_handle_verify(g
->mpls_handle
) == MPLS_BOOL_FALSE
) {
66 goto lsr_global_startup_cleanup
;
69 g
->admin_state
= MPLS_ADMIN_ENABLE
;
71 LDP_EXIT(g
->user_data
, "lsr_global_startup");
74 lsr_global_startup_cleanup
:
75 lsr_global_shutdown(g
);
77 LDP_EXIT(g
->user_data
, "lsr_global_startup-error");
82 mpls_return_enum
lsr_global_shutdown(lsr_global
* g
)
86 LDP_ENTER(g
->user_data
, "lsr_global_shutdown");
88 g
->admin_state
= MPLS_ADMIN_DISABLE
;
90 mpls_lock_release(g
->global_lock
);
91 mpls_lock_get(g
->global_lock
);
93 mpls_ifmgr_close(g
->ifmgr_handle
);
94 mpls_mpls_close(g
->mpls_handle
);
96 LDP_EXIT(g
->user_data
, "lsr_global_shutdown");
101 mpls_return_enum
lsr_global_delete(lsr_global
* g
)
104 mpls_lock_delete(g
->global_lock
);
105 LDP_PRINT(g
->user_data
, "global delete\n");
113 mpls_return_enum
_lsr_global_add_if(lsr_global
* g
, lsr_if
* i
)
119 ip
= MPLS_LIST_HEAD(&g
->iff
);
121 if (ip
->index
> i
->index
) {
122 MPLS_LIST_INSERT_BEFORE(&g
->iff
, ip
, i
, _global
);
125 ip
= MPLS_LIST_NEXT(&g
->iff
, ip
, _global
);
127 MPLS_LIST_ADD_TAIL(&g
->iff
, i
, _global
, lsr_if
);
133 mpls_return_enum
_lsr_global_del_if(lsr_global
* g
, lsr_if
* i
)
136 MPLS_LIST_REMOVE(&g
->iff
, i
, _global
);
137 MPLS_REFCNT_RELEASE(i
, lsr_if_delete
);
143 mpls_return_enum
lsr_global_find_if_index(lsr_global
* g
, uint32_t index
,
148 if (g
&& index
> 0) {
150 /* because we sort our inserts by index, this lets us know
151 if we've "walked" past the end of the list */
153 i
= MPLS_LIST_TAIL(&g
->iff
);
154 if (i
== NULL
|| i
->index
< index
) {
156 return MPLS_END_OF_LIST
;
159 i
= MPLS_LIST_HEAD(&g
->iff
);
161 if (i
->index
== index
) {
165 i
= MPLS_LIST_NEXT(&g
->iff
, i
, _global
);
172 lsr_if
* lsr_global_find_if_handle(lsr_global
* g
, mpls_if_handle ifhandle
)
176 if (g
&& mpls_if_handle_verify(g
->ifmgr_handle
, ifhandle
) == MPLS_BOOL_TRUE
) {
177 i
= MPLS_LIST_HEAD(&g
->iff
);
179 if (!mpls_if_handle_compare(i
->handle
, ifhandle
)) {
182 i
= MPLS_LIST_NEXT(&g
->iff
, i
, _global
);
188 /* struct outsegment */
190 mpls_return_enum
_lsr_global_add_outsegment(lsr_global
* g
, lsr_outsegment
* o
)
192 lsr_outsegment
*op
= NULL
;
196 op
= MPLS_LIST_HEAD(&g
->outsegment
);
198 if (op
->index
> o
->index
) {
199 MPLS_LIST_INSERT_BEFORE(&g
->outsegment
, op
, o
, _global
);
202 op
= MPLS_LIST_NEXT(&g
->outsegment
, op
, _global
);
204 MPLS_LIST_ADD_TAIL(&g
->outsegment
, o
, _global
, lsr_outsegment
);
210 mpls_return_enum
_lsr_global_del_outsegment(lsr_global
* g
, lsr_outsegment
* o
)
213 MPLS_LIST_REMOVE(&g
->outsegment
, o
, _global
);
214 MPLS_REFCNT_RELEASE(o
, lsr_outsegment_delete
);
220 mpls_return_enum
lsr_global_find_outsegment_index(lsr_global
* g
,
221 uint32_t index
, lsr_outsegment
** outsegment
)
223 lsr_outsegment
*o
= NULL
;
225 if (g
&& index
> 0) {
227 /* because we sort our inserts by index, this lets us know
228 if we've "walked" past the end of the list */
230 o
= MPLS_LIST_TAIL(&g
->outsegment
);
231 if (o
== NULL
|| o
->index
< index
) {
233 return MPLS_END_OF_LIST
;
236 o
= MPLS_LIST_HEAD(&g
->outsegment
);
238 if (o
->index
== index
) {
242 o
= MPLS_LIST_NEXT(&g
->outsegment
, o
, _global
);
249 /* struct insegment */
251 mpls_return_enum
_lsr_global_add_insegment(lsr_global
* g
, lsr_insegment
* i
)
253 lsr_insegment
*ip
= NULL
;
257 ip
= MPLS_LIST_HEAD(&g
->insegment
);
259 if (ip
->index
> i
->index
) {
260 MPLS_LIST_INSERT_BEFORE(&g
->insegment
, ip
, i
, _global
);
263 ip
= MPLS_LIST_NEXT(&g
->insegment
, ip
, _global
);
265 MPLS_LIST_ADD_TAIL(&g
->insegment
, i
, _global
, lsr_insegment
);
271 mpls_return_enum
_lsr_global_del_insegment(lsr_global
* g
, lsr_insegment
* i
)
274 MPLS_LIST_REMOVE(&g
->insegment
, i
, _global
);
275 MPLS_REFCNT_RELEASE(i
, lsr_insegment_delete
);
281 mpls_return_enum
lsr_global_find_insegment_index(lsr_global
* g
,
282 uint32_t index
, lsr_insegment
** insegment
)
284 lsr_insegment
*i
= NULL
;
286 if (g
&& index
> 0) {
288 /* because we sort our inserts by index, this lets us know
289 if we've "walked" past the end of the list */
291 i
= MPLS_LIST_TAIL(&g
->insegment
);
292 if (i
== NULL
|| i
->index
< index
) {
294 return MPLS_END_OF_LIST
;
297 i
= MPLS_LIST_HEAD(&g
->insegment
);
299 if (i
->index
== index
) {
303 i
= MPLS_LIST_NEXT(&g
->insegment
, i
, _global
);
310 /* struct xconnect */
312 mpls_return_enum
_lsr_global_add_xconnect(lsr_global
* g
, lsr_xconnect
* x
)
314 lsr_xconnect
*xp
= NULL
;
318 xp
= MPLS_LIST_HEAD(&g
->xconnect
);
320 if (xp
->index
> x
->index
) {
321 MPLS_LIST_INSERT_BEFORE(&g
->xconnect
, xp
, x
, _global
);
324 xp
= MPLS_LIST_NEXT(&g
->xconnect
, xp
, _global
);
326 MPLS_LIST_ADD_TAIL(&g
->xconnect
, x
, _global
, lsr_xconnect
);
332 mpls_return_enum
_lsr_global_del_xconnect(lsr_global
* g
, lsr_xconnect
* x
)
335 MPLS_LIST_REMOVE(&g
->xconnect
, x
, _global
);
336 MPLS_REFCNT_RELEASE(x
, lsr_xconnect_delete
);
342 mpls_return_enum
lsr_global_find_xconnect_index(lsr_global
* g
,
343 uint32_t index
, lsr_xconnect
** xconnect
)
345 lsr_xconnect
*x
= NULL
;
347 if (g
&& index
> 0) {
349 /* because we sort our inserts by index, this lets us know
350 if we've "walked" past the end of the list */
352 x
= MPLS_LIST_TAIL(&g
->xconnect
);
353 if (x
== NULL
|| x
->index
< index
) {
355 return MPLS_END_OF_LIST
;
358 x
= MPLS_LIST_HEAD(&g
->xconnect
);
360 if (x
->index
== index
) {
364 x
= MPLS_LIST_NEXT(&g
->xconnect
, x
, _global
);
371 mpls_return_enum
lsr_global_find_xconnect_index2(lsr_global
* g
,
372 uint32_t in
, uint32_t out
, lsr_xconnect
** xconnect
)
374 lsr_insegment
*iseg
= NULL
;
375 lsr_xconnect
*x
= NULL
;
377 if (g
&& in
> 0 && out
> 0) {
379 if (lsr_global_find_insegment_index(g
,in
,&iseg
) != MPLS_SUCCESS
) {
383 x
= MPLS_LIST_HEAD(&iseg
->xconnect_root
);
385 if (x
->outsegment
&& x
->outsegment
->index
== out
) {
389 x
= MPLS_LIST_NEXT(&iseg
->xconnect_root
, x
, _insegment
);
398 void _lsr_global_add_ftn(lsr_global
* g
, lsr_ftn
* f
)
405 fp
= MPLS_LIST_HEAD(&g
->ftn
);
407 if (fp
->index
> f
->index
) {
408 MPLS_LIST_INSERT_BEFORE(&g
->ftn
, fp
, f
, _global
);
411 fp
= MPLS_LIST_NEXT(&g
->ftn
, fp
, _global
);
413 MPLS_LIST_ADD_TAIL(&g
->ftn
, f
, _global
, lsr_ftn
);
416 void _lsr_global_del_ftn(lsr_global
* g
, lsr_ftn
* f
)
419 MPLS_LIST_REMOVE(&g
->ftn
, f
, _global
);
420 MPLS_REFCNT_RELEASE(f
, lsr_ftn_delete
);
423 mpls_return_enum
lsr_global_find_ftn_index(lsr_global
* g
,
424 uint32_t index
, lsr_ftn
** ftn
)
428 MPLS_ASSERT(g
&& index
> 0);
430 /* because we sort our inserts by index, this lets us know
431 if we've "walked" past the end of the list */
433 f
= MPLS_LIST_TAIL(&g
->ftn
);
434 if (f
== NULL
|| f
->index
< index
) {
436 return MPLS_END_OF_LIST
;
439 f
= MPLS_LIST_HEAD(&g
->ftn
);
441 if (f
->index
== index
) {
445 f
= MPLS_LIST_NEXT(&g
->ftn
, f
, _global
);
451 mpls_return_enum
lsr_global_find_ftn_index2(lsr_global
* g
,
452 lsr_ftn
* f
, lsr_ftn
** ftn
)
457 fp
= MPLS_LIST_HEAD(&g
->ftn
);
459 if (fp
->outsegment
->index
== f
->outsegment_index
) {
460 if (fp
->fec
.type
== f
->fec
.type
) {
461 switch(fp
->fec
.type
) {
462 case MPLS_FEC_PREFIX
:
463 if (fp
->fec
.u
.prefix
.network
.u
.ipv4
== f
->fec
.u
.prefix
.network
.u
.ipv4
&&
464 fp
->fec
.u
.prefix
.length
== f
->fec
.u
.prefix
.length
) {
470 if (fp
->fec
.u
.host
.u
.ipv4
== f
->fec
.u
.host
.u
.ipv4
) {
476 if (fp
->fec
.u
.l2cc
.connection_id
== f
->fec
.u
.l2cc
.connection_id
&&
477 fp
->fec
.u
.l2cc
.group_id
== f
->fec
.u
.l2cc
.group_id
&&
478 fp
->fec
.u
.l2cc
.type
== f
->fec
.u
.l2cc
.type
) {
488 fp
= MPLS_LIST_NEXT(&g
->ftn
, fp
, _global
);