the mpls_inet_addr member is called 'address' in ldp_addr not 'info'
[mpls-ldp-portable.git] / ldp / ldp_nexthop.c
blob5b0590ab53ed8571c00019143e2b30c2fc27a23a
2 /*
3 * Copyright (C) James R. Leu 2003
4 * jleu@mindspring.com
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
8 */
10 #include "ldp_struct.h"
11 #include "ldp_fec.h"
12 #include "ldp_if.h"
13 #include "ldp_addr.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"
24 #if MPLS_USE_LSR
25 #include "lsr_cfg.h"
26 #else
27 #include "mpls_mpls_impl.h"
28 #endif
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);
41 ldp_session *sp;
42 while (nh) {
43 sp = ldp_session_for_nexthop(nh);
44 if (sp && (sp->index == s->index)) {
45 return nh;
47 nh = MPLS_LIST_NEXT(&fec->nh_root, nh, _fec);
49 return NULL;
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);
58 if (nh->addr) {
59 ldp_addr_del_nexthop(g, nh->addr, nh);
61 if (nh->iff) {
62 ldp_if_del_nexthop(g, nh->iff, nh);
64 if (nh->outlabel) {
65 ldp_outlabel_del_nexthop(g, nh->outlabel, nh);
68 mpls_free(nh);
71 ldp_nexthop *ldp_nexthop_create(ldp_global *g, mpls_nexthop *n)
73 ldp_nexthop *nh = (ldp_nexthop *) mpls_malloc(sizeof(ldp_nexthop));
75 if (nh != NULL) {
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) {
98 ldp_if *iff = NULL;
99 if ((iff = ldp_global_find_if_handle(g, nh->info.if_handle))) {
100 ldp_if_add_nexthop(iff, nh);
101 } else {
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);
115 return nh;
117 ldp_nexthop_create_error:
118 ldp_nexthop_delete(g, nh);
119 return NULL;
122 void ldp_nexthop_add_if(ldp_nexthop * nh, ldp_if * i)
124 MPLS_ASSERT(nh && i);
125 MPLS_REFCNT_HOLD(i);
126 nh->info.if_handle = i->handle;
127 nh->iff = i;
130 void ldp_nexthop_del_if(ldp_global *g, ldp_nexthop * nh)
132 MPLS_ASSERT(nh);
133 MPLS_REFCNT_RELEASE2(g, nh->iff, ldp_if_delete);
134 nh->iff = NULL;
137 void ldp_nexthop_add_addr(ldp_nexthop * nh, ldp_addr * a)
139 MPLS_ASSERT(nh && a);
140 MPLS_REFCNT_HOLD(a);
141 nh->addr = a;
144 void ldp_nexthop_del_addr(ldp_global *g, ldp_nexthop * nh)
146 MPLS_ASSERT(nh);
147 MPLS_REFCNT_RELEASE2(g, nh->addr, ldp_addr_delete);
148 nh->addr = NULL;
151 void ldp_nexthop_add_outlabel(ldp_nexthop * nh, ldp_outlabel * o)
153 MPLS_ASSERT(nh && o);
154 MPLS_REFCNT_HOLD(o);
155 nh->outlabel = o;
158 void ldp_nexthop_del_outlabel(ldp_nexthop * nh)
160 MPLS_ASSERT(nh);
161 MPLS_REFCNT_RELEASE(nh->outlabel, ldp_outlabel_delete);
162 nh->outlabel = NULL;
165 void ldp_nexthop_add_outlabel2(ldp_nexthop * n, ldp_outlabel * o)
167 MPLS_ASSERT(n && o);
168 MPLS_REFCNT_HOLD(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)
175 MPLS_ASSERT(n && 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);
184 MPLS_REFCNT_HOLD(f);
185 nh->fec = f;
188 void ldp_nexthop_del_fec(ldp_global *g, ldp_nexthop * nh)
190 MPLS_ASSERT(nh);
191 MPLS_REFCNT_RELEASE2(g, nh->fec, ldp_fec_delete);
192 nh->fec = NULL;
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;
203 return retval;