]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/rfapi/vnc_export_table.c
Merge branch 'frr/pull/550'
[mirror_frr.git] / bgpd / rfapi / vnc_export_table.c
1 /*
2 *
3 * Copyright 2009-2016, LabN Consulting, L.L.C.
4 *
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21
22 #include "lib/zebra.h"
23 #include "lib/prefix.h"
24 #include "lib/table.h"
25 #include "lib/memory.h"
26 #include "lib/vty.h"
27
28 #include "bgpd/bgpd.h"
29 #include "bgpd/bgp_route.h"
30
31 #include "bgpd/rfapi/vnc_export_table.h"
32 #include "bgpd/rfapi/rfapi_private.h"
33 #include "bgpd/rfapi/rfapi_import.h"
34 #include "bgpd/rfapi/vnc_debug.h"
35
36 struct route_node *
37 vnc_etn_get (struct bgp *bgp, vnc_export_type_t type, struct prefix *p)
38 {
39 struct route_table *t = NULL;
40 struct route_node *rn = NULL;
41 afi_t afi;
42
43 if (!bgp || !bgp->rfapi)
44 return NULL;
45
46 afi = family2afi (p->family);
47 assert (afi == AFI_IP || afi == AFI_IP6);
48
49 switch (type)
50 {
51 case EXPORT_TYPE_BGP:
52 if (!bgp->rfapi->rt_export_bgp[afi])
53 bgp->rfapi->rt_export_bgp[afi] = route_table_init ();
54 t = bgp->rfapi->rt_export_bgp[afi];
55 break;
56
57 case EXPORT_TYPE_ZEBRA:
58 if (!bgp->rfapi->rt_export_zebra[afi])
59 bgp->rfapi->rt_export_zebra[afi] = route_table_init ();
60 t = bgp->rfapi->rt_export_zebra[afi];
61 break;
62 }
63
64 if (t)
65 rn = route_node_get (t, p);
66 return rn;
67 }
68
69 struct route_node *
70 vnc_etn_lookup (struct bgp *bgp, vnc_export_type_t type, struct prefix *p)
71 {
72 struct route_table *t = NULL;
73 struct route_node *rn = NULL;
74 afi_t afi;
75
76 if (!bgp || !bgp->rfapi)
77 return NULL;
78
79 afi = family2afi (p->family);
80 assert (afi == AFI_IP || afi == AFI_IP6);
81
82 switch (type)
83 {
84 case EXPORT_TYPE_BGP:
85 if (!bgp->rfapi->rt_export_bgp[afi])
86 bgp->rfapi->rt_export_bgp[afi] = route_table_init ();
87 t = bgp->rfapi->rt_export_bgp[afi];
88 break;
89
90 case EXPORT_TYPE_ZEBRA:
91 if (!bgp->rfapi->rt_export_zebra[afi])
92 bgp->rfapi->rt_export_zebra[afi] = route_table_init ();
93 t = bgp->rfapi->rt_export_zebra[afi];
94 break;
95 }
96
97 if (t)
98 rn = route_node_lookup (t, p);
99 return rn;
100 }
101
102 struct vnc_export_info *
103 vnc_eti_get (
104 struct bgp *bgp,
105 vnc_export_type_t etype,
106 struct prefix *p,
107 struct peer *peer,
108 uint8_t type,
109 uint8_t subtype)
110 {
111 struct route_node *etn;
112 struct vnc_export_info *eti;
113
114 etn = vnc_etn_get (bgp, etype, p);
115 assert (etn);
116
117 for (eti = etn->info; eti; eti = eti->next)
118 {
119 if (peer == eti->peer && type == eti->type && subtype == eti->subtype)
120 {
121
122 break;
123 }
124 }
125
126 if (eti)
127 {
128 route_unlock_node (etn);
129 }
130 else
131 {
132 eti = XCALLOC (MTYPE_RFAPI_ETI, sizeof (struct vnc_export_info));
133 assert (eti);
134 eti->node = etn;
135 eti->peer = peer;
136 peer_lock (peer);
137 eti->type = type;
138 eti->subtype = subtype;
139 eti->next = etn->info;
140 etn->info = eti;
141 }
142
143 return eti;
144 }
145
146 void
147 vnc_eti_delete (struct vnc_export_info *goner)
148 {
149 struct route_node *etn;
150 struct vnc_export_info *eti;
151 struct vnc_export_info *eti_prev = NULL;
152
153 etn = goner->node;
154
155 for (eti = etn->info; eti; eti_prev = eti, eti = eti->next)
156 {
157 if (eti == goner)
158 break;
159 }
160
161 if (!eti)
162 {
163 vnc_zlog_debug_verbose ("%s: COULDN'T FIND ETI", __func__);
164 return;
165 }
166
167 if (eti_prev)
168 {
169 eti_prev->next = goner->next;
170 }
171 else
172 {
173 etn->info = goner->next;
174 }
175
176 peer_unlock (eti->peer);
177 goner->node = NULL;
178 XFREE (MTYPE_RFAPI_ETI, goner);
179
180 route_unlock_node (etn);
181 }
182
183 struct vnc_export_info *
184 vnc_eti_checktimer (
185 struct bgp *bgp,
186 vnc_export_type_t etype,
187 struct prefix *p,
188 struct peer *peer,
189 uint8_t type,
190 uint8_t subtype)
191 {
192 struct route_node *etn;
193 struct vnc_export_info *eti;
194
195 etn = vnc_etn_lookup (bgp, etype, p);
196 if (!etn)
197 return NULL;
198
199 for (eti = etn->info; eti; eti = eti->next)
200 {
201 if (peer == eti->peer && type == eti->type && subtype == eti->subtype)
202 {
203
204 break;
205 }
206 }
207
208 route_unlock_node (etn);
209
210 if (eti && eti->timer)
211 return eti;
212
213 return NULL;
214 }