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_outlabel.h"
17 #include "ldp_inlabel.h"
18 #include "ldp_session.h"
19 #include "ldp_tunnel.h"
20 #include "ldp_global.h"
22 #include "mpls_mm_impl.h"
23 #include "mpls_trace_impl.h"
25 static uint32_t _ldp_outlabel_next_index
= 1;
27 ldp_outlabel
*ldp_outlabel_create()
29 ldp_outlabel
*o
= (ldp_outlabel
*) mpls_malloc(sizeof(ldp_outlabel
));
32 memset(o
, 0, sizeof(ldp_outlabel
));
33 MPLS_REFCNT_INIT(o
, 0);
34 MPLS_LIST_INIT(&o
->inlabel_root
, ldp_inlabel
);
35 MPLS_LIST_INIT(&o
->tunnel_root
, ldp_tunnel
);
36 MPLS_LIST_INIT(&o
->fec_outlabel_root
, ldp_fec
);
37 MPLS_LIST_ELEM_INIT(o
, _global
);
38 MPLS_LIST_ELEM_INIT(o
, _session
);
39 o
->index
= _ldp_outlabel_get_next_index();
40 o
->info
.label
.type
= MPLS_LABEL_TYPE_NONE
;
41 o
->switching
= MPLS_BOOL_FALSE
;
46 ldp_outlabel
*ldp_outlabel_create_complete(ldp_global
* g
, ldp_session
* s
,
49 ldp_outlabel
*out
= ldp_outlabel_create();
52 ldp_outlabel_add_nexthop(out
, &a
->fec
->nh
);
53 ldp_session_add_outlabel(s
, out
);
55 out
->info
.push_label
= MPLS_BOOL_TRUE
;
56 out
->info
.owner
= MPLS_OWNER_LDP
;
58 ldp_attr2mpls_label_struct(a
, &out
->info
.label
);
59 _ldp_global_add_outlabel(g
, out
);
60 ldp_attr_add_outlabel(a
, out
);
65 void ldp_outlabel_delete(ldp_outlabel
* o
)
67 LDP_PRINT(g
->user_data
,"outlabel delete\n");
68 MPLS_REFCNT_ASSERT(o
, 0);
72 void ldp_outlabel_delete_complete(ldp_global
* g
, ldp_outlabel
* out
)
74 ldp_attr_del_outlabel(out
->attr
);
76 ldp_session_del_outlabel(out
->session
, out
);
78 _ldp_global_del_outlabel(g
, out
);
79 ldp_outlabel_del_nexthop(out
);
82 mpls_return_enum
_ldp_outlabel_add_inlabel(ldp_outlabel
* o
, ldp_inlabel
* i
)
87 MPLS_LIST_ADD_HEAD(&o
->inlabel_root
, i
, _outlabel
, ldp_inlabel
);
93 mpls_return_enum
_ldp_outlabel_del_inlabel(ldp_outlabel
* o
, ldp_inlabel
* i
)
96 MPLS_LIST_REMOVE(&o
->inlabel_root
, i
, _outlabel
);
98 MPLS_REFCNT_RELEASE(i
, ldp_inlabel_delete
);
104 mpls_return_enum
_ldp_outlabel_add_attr(ldp_outlabel
* o
, ldp_attr
* a
)
114 mpls_return_enum
_ldp_outlabel_del_attr(ldp_outlabel
* o
)
117 MPLS_REFCNT_RELEASE(o
->attr
, ldp_attr_delete
);
124 void ldp_outlabel_add_fec(ldp_outlabel
* o
, ldp_fec
* f
)
131 ldp_fec_add_outlabel(f
,o
);
133 fp
= MPLS_LIST_HEAD(&o
->fec_outlabel_root
);
135 if (fp
->index
> f
->index
) {
136 MPLS_LIST_INSERT_BEFORE(&o
->fec_outlabel_root
, fp
, f
, _if
);
139 fp
= MPLS_LIST_NEXT(&o
->fec_outlabel_root
, fp
, _if
);
141 MPLS_LIST_ADD_TAIL(&o
->fec_outlabel_root
, f
, _if
, ldp_fec
);
144 void ldp_outlabel_del_fec(ldp_outlabel
* o
, ldp_fec
* f
)
147 MPLS_LIST_REMOVE(&o
->fec_outlabel_root
, f
, _if
);
148 ldp_fec_del_outlabel(f
);
149 MPLS_REFCNT_RELEASE(f
, ldp_fec_delete
);
152 void ldp_outlabel_add_nexthop(ldp_outlabel
* o
, ldp_nexthop
* nh
)
154 MPLS_ASSERT(o
&& nh
);
156 if (nh
->type
& MPLS_NH_IP
) {
157 MPLS_REFCNT_HOLD(nh
->addr
);
158 o
->nh
.addr
= nh
->addr
;
159 o
->nh
.type
|= MPLS_NH_IP
;
160 memcpy(&o
->info
.nexthop
.ip
, &nh
->addr
->address
, sizeof(mpls_inet_addr
));
161 o
->info
.nexthop
.type
|= MPLS_NH_IP
;
163 if (nh
->type
& MPLS_NH_IF
) {
164 MPLS_REFCNT_HOLD(nh
->iff
);
166 o
->nh
.type
|= MPLS_NH_IF
;
167 memcpy(&o
->info
.nexthop
.if_handle
, &nh
->iff
->handle
,
168 sizeof(mpls_if_handle
));
169 o
->info
.nexthop
.type
|= MPLS_NH_IF
;
171 if (nh
->type
& MPLS_NH_OUTSEGMENT
) {
172 MPLS_REFCNT_HOLD(nh
->outlabel
);
173 o
->nh
.outlabel
= nh
->outlabel
;
174 o
->nh
.type
|= MPLS_NH_OUTSEGMENT
;
175 memcpy(&o
->info
.nexthop
.outsegment_handle
, &nh
->outlabel
->info
.handle
,
176 sizeof(mpls_outsegment_handle
));
177 o
->info
.nexthop
.type
|= MPLS_NH_OUTSEGMENT
;
181 void ldp_outlabel_del_nexthop(ldp_outlabel
* o
)
184 if (o
->nh
.type
& MPLS_NH_IP
) {
185 MPLS_REFCNT_RELEASE(o
->nh
.addr
, ldp_addr_delete
);
187 o
->nh
.type
&= ~MPLS_NH_IP
;
189 if (o
->nh
.type
& MPLS_NH_IF
) {
190 MPLS_REFCNT_RELEASE(o
->nh
.iff
, ldp_if_delete
);
192 o
->nh
.type
&= ~MPLS_NH_IF
;
194 if (o
->nh
.type
& MPLS_NH_OUTSEGMENT
) {
195 MPLS_REFCNT_RELEASE(o
->nh
.outlabel
, ldp_outlabel_delete
);
196 o
->nh
.outlabel
= NULL
;
197 o
->nh
.type
&= ~MPLS_NH_OUTSEGMENT
;
201 mpls_return_enum
_ldp_outlabel_add_session(ldp_outlabel
* o
, ldp_session
* s
)
211 mpls_return_enum
_ldp_outlabel_del_session(ldp_outlabel
* o
)
213 if (o
&& o
->session
) {
214 MPLS_REFCNT_RELEASE(o
->session
, ldp_session_delete
);
221 uint32_t _ldp_outlabel_get_next_index()
223 uint32_t retval
= _ldp_outlabel_next_index
;
225 _ldp_outlabel_next_index
++;
226 if (retval
> _ldp_outlabel_next_index
) {
227 _ldp_outlabel_next_index
= 1;
232 mpls_return_enum
_ldp_outlabel_add_tunnel(ldp_outlabel
* o
, ldp_tunnel
* t
)
237 MPLS_LIST_ADD_HEAD(&o
->tunnel_root
, t
, _outlabel
, ldp_tunnel
);
243 mpls_return_enum
_ldp_outlabel_del_tunnel(ldp_outlabel
* o
, ldp_tunnel
* t
)
246 MPLS_LIST_REMOVE(&o
->tunnel_root
, t
, _outlabel
);
248 MPLS_REFCNT_RELEASE(t
, ldp_tunnel_delete
);