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 "ldp_struct.h"
16 #include "ldp_nexthop.h"
17 #include "ldp_outlabel.h"
18 #include "ldp_inlabel.h"
19 #include "ldp_session.h"
20 #include "ldp_tunnel.h"
21 #include "ldp_global.h"
23 #include "mpls_mm_impl.h"
24 #include "mpls_trace_impl.h"
26 static uint32_t _ldp_outlabel_next_index
= 1;
28 ldp_outlabel
*ldp_outlabel_create()
30 ldp_outlabel
*o
= (ldp_outlabel
*) mpls_malloc(sizeof(ldp_outlabel
));
33 memset(o
, 0, sizeof(ldp_outlabel
));
34 MPLS_REFCNT_INIT(o
, 0);
35 MPLS_LIST_INIT(&o
->inlabel_root
, ldp_inlabel
);
36 MPLS_LIST_INIT(&o
->tunnel_root
, ldp_tunnel
);
37 MPLS_LIST_INIT(&o
->nh_root
, ldp_nexthop
);
38 MPLS_LIST_ELEM_INIT(o
, _global
);
39 MPLS_LIST_ELEM_INIT(o
, _session
);
40 o
->index
= _ldp_outlabel_get_next_index();
41 o
->info
.label
.type
= MPLS_LABEL_TYPE_NONE
;
42 o
->switching
= MPLS_BOOL_FALSE
;
47 ldp_outlabel
*ldp_outlabel_create_complete(ldp_global
* g
, ldp_session
* s
,
48 ldp_attr
* a
, ldp_nexthop
*nh
)
50 ldp_outlabel
*out
= ldp_outlabel_create();
53 ldp_outlabel_add_nexthop2(out
, nh
);
54 ldp_session_add_outlabel(s
, out
);
56 out
->info
.push_label
= MPLS_BOOL_TRUE
;
57 out
->info
.owner
= MPLS_OWNER_LDP
;
59 ldp_attr2mpls_label_struct(a
, &out
->info
.label
);
60 _ldp_global_add_outlabel(g
, out
);
61 ldp_attr_add_outlabel(a
, out
);
66 void ldp_outlabel_delete(ldp_outlabel
* o
)
68 LDP_PRINT(g
->user_data
,"outlabel delete\n");
69 MPLS_REFCNT_ASSERT(o
, 0);
73 void ldp_outlabel_delete_complete(ldp_global
* g
, ldp_outlabel
* out
)
75 ldp_attr_del_outlabel(out
->attr
);
77 ldp_session_del_outlabel(out
->session
, out
);
79 _ldp_global_del_outlabel(g
, out
);
80 ldp_outlabel_del_nexthop2(out
);
83 mpls_return_enum
_ldp_outlabel_add_inlabel(ldp_outlabel
* o
, ldp_inlabel
* i
)
88 MPLS_LIST_ADD_HEAD(&o
->inlabel_root
, i
, _outlabel
, ldp_inlabel
);
94 mpls_return_enum
_ldp_outlabel_del_inlabel(ldp_outlabel
* o
, ldp_inlabel
* i
)
97 MPLS_LIST_REMOVE(&o
->inlabel_root
, i
, _outlabel
);
99 MPLS_REFCNT_RELEASE(i
, ldp_inlabel_delete
);
105 mpls_return_enum
_ldp_outlabel_add_attr(ldp_outlabel
* o
, ldp_attr
* a
)
115 mpls_return_enum
_ldp_outlabel_del_attr(ldp_outlabel
* o
)
118 MPLS_REFCNT_RELEASE(o
->attr
, ldp_attr_delete
);
125 void ldp_outlabel_add_nexthop(ldp_outlabel
* o
, ldp_nexthop
* nh
)
127 ldp_nexthop
*np
= NULL
;
129 MPLS_ASSERT(o
&& nh
);
130 MPLS_REFCNT_HOLD(nh
);
132 ldp_nexthop_add_outlabel(nh
,o
);
134 np
= MPLS_LIST_HEAD(&o
->nh_root
);
136 if (np
->index
> nh
->index
) {
137 MPLS_LIST_INSERT_BEFORE(&o
->nh_root
, np
, nh
, _outlabel
);
140 np
= MPLS_LIST_NEXT(&o
->nh_root
, np
, _outlabel
);
142 MPLS_LIST_ADD_TAIL(&o
->nh_root
, nh
, _outlabel
, ldp_nexthop
);
145 void ldp_outlabel_del_nexthop(ldp_outlabel
* o
, ldp_nexthop
* nh
)
147 MPLS_ASSERT(o
&& nh
);
148 MPLS_LIST_REMOVE(&o
->nh_root
, nh
, _outlabel
);
149 ldp_nexthop_del_outlabel(nh
);
150 MPLS_REFCNT_RELEASE(nh
, ldp_nexthop_delete
);
153 void ldp_outlabel_add_nexthop2(ldp_outlabel
* o
, ldp_nexthop
* nh
)
155 MPLS_ASSERT(o
&& nh
);
157 if (nh
->type
& MPLS_NH_IP
) {
158 MPLS_REFCNT_HOLD(nh
->addr
);
159 o
->nh
.addr
= nh
->addr
;
160 o
->nh
.type
|= MPLS_NH_IP
;
161 memcpy(&o
->info
.nexthop
.ip
, &nh
->addr
->address
, sizeof(mpls_inet_addr
));
162 o
->info
.nexthop
.type
|= MPLS_NH_IP
;
164 if (nh
->type
& MPLS_NH_IF
) {
165 MPLS_REFCNT_HOLD(nh
->iff
);
167 o
->nh
.type
|= MPLS_NH_IF
;
168 memcpy(&o
->info
.nexthop
.if_handle
, &nh
->iff
->handle
,
169 sizeof(mpls_if_handle
));
170 o
->info
.nexthop
.type
|= MPLS_NH_IF
;
172 if (nh
->type
& MPLS_NH_OUTSEGMENT
) {
173 MPLS_REFCNT_HOLD(nh
->outlabel
);
174 o
->nh
.outlabel
= nh
->outlabel
;
175 o
->nh
.type
|= MPLS_NH_OUTSEGMENT
;
176 memcpy(&o
->info
.nexthop
.outsegment_handle
, &nh
->outlabel
->info
.handle
,
177 sizeof(mpls_outsegment_handle
));
178 o
->info
.nexthop
.type
|= MPLS_NH_OUTSEGMENT
;
182 void ldp_outlabel_del_nexthop2(ldp_outlabel
* o
)
185 if (o
->nh
.type
& MPLS_NH_IP
) {
186 MPLS_REFCNT_RELEASE(o
->nh
.addr
, ldp_addr_delete
);
188 o
->nh
.type
&= ~MPLS_NH_IP
;
190 if (o
->nh
.type
& MPLS_NH_IF
) {
191 MPLS_REFCNT_RELEASE(o
->nh
.iff
, ldp_if_delete
);
193 o
->nh
.type
&= ~MPLS_NH_IF
;
195 if (o
->nh
.type
& MPLS_NH_OUTSEGMENT
) {
196 MPLS_REFCNT_RELEASE(o
->nh
.outlabel
, ldp_outlabel_delete
);
197 o
->nh
.outlabel
= NULL
;
198 o
->nh
.type
&= ~MPLS_NH_OUTSEGMENT
;
202 mpls_return_enum
_ldp_outlabel_add_session(ldp_outlabel
* o
, ldp_session
* s
)
212 mpls_return_enum
_ldp_outlabel_del_session(ldp_outlabel
* o
)
214 if (o
&& o
->session
) {
215 MPLS_REFCNT_RELEASE(o
->session
, ldp_session_delete
);
222 uint32_t _ldp_outlabel_get_next_index()
224 uint32_t retval
= _ldp_outlabel_next_index
;
226 _ldp_outlabel_next_index
++;
227 if (retval
> _ldp_outlabel_next_index
) {
228 _ldp_outlabel_next_index
= 1;
233 mpls_return_enum
_ldp_outlabel_add_tunnel(ldp_outlabel
* o
, ldp_tunnel
* t
)
238 MPLS_LIST_ADD_HEAD(&o
->tunnel_root
, t
, _outlabel
, ldp_tunnel
);
244 mpls_return_enum
_ldp_outlabel_del_tunnel(ldp_outlabel
* o
, ldp_tunnel
* t
)
247 MPLS_LIST_REMOVE(&o
->tunnel_root
, t
, _outlabel
);
249 MPLS_REFCNT_RELEASE(t
, ldp_tunnel_delete
);