3 * Copyright (C) James R. Leu 2003
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
10 #include "ldp_struct.h"
14 #include "ldp_session.h"
15 #include "ldp_outlabel.h"
16 #include "ldp_global.h"
17 #include "mpls_assert.h"
18 #include "mpls_compare.h"
19 #include "mpls_mm_impl.h"
20 #include "mpls_tree_impl.h"
21 #include "mpls_policy_impl.h"
22 #include "mpls_trace_impl.h"
27 #include "mpls_mpls_impl.h"
30 static uint32_t _ldp_nexthop_next_index
= 1;
31 static uint32_t _ldp_nexthop_get_next_index();
33 void mpls_nexthop2ldp_nexthop(mpls_nexthop
*mnh
, ldp_nexthop
*lnh
)
35 memcpy(&lnh
->info
, mnh
, sizeof(mpls_nexthop
));
38 ldp_nexthop
*ldp_nexthop_for_fec_session(ldp_fec
*fec
, ldp_session
*s
)
40 ldp_nexthop
*nh
= MPLS_LIST_HEAD(&fec
->nh_root
);
43 sp
= ldp_session_for_nexthop(nh
);
44 if (sp
&& (sp
->index
== s
->index
)) {
47 nh
= MPLS_LIST_NEXT(&fec
->nh_root
, nh
, _fec
);
52 void ldp_nexthop_delete(ldp_global
*g
, ldp_nexthop
*nh
)
54 fprintf(stderr
, "nexthop delete: %p\n", nh
);
55 MPLS_REFCNT_ASSERT(nh
, 0);
56 _ldp_global_del_nexthop(g
, nh
);
59 ldp_addr_del_nexthop(g
, nh
->addr
, nh
);
62 ldp_if_del_nexthop(g
, nh
->iff
, nh
);
65 ldp_outlabel_del_nexthop(g
, nh
->outlabel
, nh
);
71 ldp_nexthop
*ldp_nexthop_create(ldp_global
*g
, mpls_nexthop
*n
)
73 ldp_nexthop
*nh
= (ldp_nexthop
*) mpls_malloc(sizeof(ldp_nexthop
));
76 memset(nh
, 0, sizeof(ldp_nexthop
));
77 MPLS_REFCNT_INIT(nh
, 0);
78 MPLS_LIST_INIT(&nh
->outlabel_root
, ldp_outlabel
);
79 MPLS_LIST_ELEM_INIT(nh
, _global
);
80 MPLS_LIST_ELEM_INIT(nh
, _fec
);
81 MPLS_LIST_ELEM_INIT(nh
, _addr
);
82 MPLS_LIST_ELEM_INIT(nh
, _if
);
83 MPLS_LIST_ELEM_INIT(nh
, _outlabel
);
84 nh
->index
= _ldp_nexthop_get_next_index();
85 mpls_nexthop2ldp_nexthop(n
, nh
);
87 if (nh
->info
.type
& MPLS_NH_IP
) {
88 ldp_addr
*addr
= NULL
;
89 if (!(addr
= ldp_addr_find(g
, &nh
->info
.ip
))) {
90 if (!(addr
= ldp_addr_insert(g
, &nh
->info
.ip
))) {
91 goto ldp_nexthop_create_error
;
94 ldp_addr_add_nexthop(addr
, nh
);
97 if (nh
->info
.type
& MPLS_NH_IF
) {
99 if ((iff
= ldp_global_find_if_handle(g
, nh
->info
.if_handle
))) {
100 ldp_if_add_nexthop(iff
, nh
);
102 goto ldp_nexthop_create_error
;
106 if (nh
->info
.type
& MPLS_NH_OUTSEGMENT
) {
107 ldp_outlabel
*out
= NULL
;
108 MPLS_ASSERT((out
= ldp_global_find_outlabel_handle(g
,
109 nh
->info
.outsegment_handle
)));
110 ldp_outlabel_add_nexthop(out
, nh
);
113 _ldp_global_add_nexthop(g
, nh
);
117 ldp_nexthop_create_error
:
118 ldp_nexthop_delete(g
, nh
);
122 void ldp_nexthop_add_if(ldp_nexthop
* nh
, ldp_if
* i
)
124 MPLS_ASSERT(nh
&& i
);
126 nh
->info
.if_handle
= i
->handle
;
130 void ldp_nexthop_del_if(ldp_global
*g
, ldp_nexthop
* nh
)
133 MPLS_REFCNT_RELEASE2(g
, nh
->iff
, ldp_if_delete
);
137 void ldp_nexthop_add_addr(ldp_nexthop
* nh
, ldp_addr
* a
)
139 MPLS_ASSERT(nh
&& a
);
144 void ldp_nexthop_del_addr(ldp_global
*g
, ldp_nexthop
* nh
)
147 MPLS_REFCNT_RELEASE2(g
, nh
->addr
, ldp_addr_delete
);
151 void ldp_nexthop_add_outlabel(ldp_nexthop
* nh
, ldp_outlabel
* o
)
153 MPLS_ASSERT(nh
&& o
);
158 void ldp_nexthop_del_outlabel(ldp_nexthop
* nh
)
161 MPLS_REFCNT_RELEASE(nh
->outlabel
, ldp_outlabel_delete
);
165 void ldp_nexthop_add_outlabel2(ldp_nexthop
* n
, ldp_outlabel
* o
)
169 MPLS_LIST_ADD_HEAD(&n
->outlabel_root
, o
, _nexthop
, ldp_outlabel
);
170 memcpy(&o
->info
.nexthop
, &n
->info
, sizeof(mpls_nexthop
));
173 void ldp_nexthop_del_outlabel2(ldp_global
*g
, ldp_nexthop
* n
, ldp_outlabel
* o
)
176 MPLS_LIST_REMOVE(&n
->outlabel_root
, o
, _nexthop
);
177 ldp_outlabel_del_nexthop2(g
, o
);
178 MPLS_REFCNT_RELEASE(o
, ldp_outlabel_delete
);
181 void ldp_nexthop_add_fec(ldp_nexthop
*nh
, ldp_fec
*f
)
183 MPLS_ASSERT(nh
&& f
);
188 void ldp_nexthop_del_fec(ldp_global
*g
, ldp_nexthop
* nh
)
191 MPLS_REFCNT_RELEASE2(g
, nh
->fec
, ldp_fec_delete
);
195 static uint32_t _ldp_nexthop_get_next_index()
197 uint32_t retval
= _ldp_nexthop_next_index
;
199 _ldp_nexthop_next_index
++;
200 if (retval
> _ldp_nexthop_next_index
) {
201 _ldp_nexthop_next_index
= 1;