]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vrf.c
zebra: Add code to add/remove statics from the rib
[mirror_frr.git] / zebra / zebra_vrf.c
1 /*
2 * Copyright (C) 2016 CumulusNetworks
3 * Donald Sharp
4 *
5 * This file is part of Quagga
6 *
7 * Quagga is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * Quagga is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22 #include <zebra.h>
23
24 #include "log.h"
25 #include "linklist.h"
26
27 #include "zebra/debug.h"
28 #include "zebra/zserv.h"
29 #include "zebra/rib.h"
30 #include "zebra/zebra_vrf.h"
31 #include "zebra/router-id.h"
32
33 extern struct zebra_t zebrad;
34
35 /* VRF information update. */
36 static void
37 zebra_vrf_add_update (struct zebra_vrf *zvrf)
38 {
39 struct listnode *node, *nnode;
40 struct zserv *client;
41
42 if (IS_ZEBRA_DEBUG_EVENT)
43 zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf->name);
44
45 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
46 zsend_vrf_add (client, zvrf);
47 }
48
49 static void
50 zebra_vrf_delete_update (struct zebra_vrf *zvrf)
51 {
52 struct listnode *node, *nnode;
53 struct zserv *client;
54
55 if (IS_ZEBRA_DEBUG_EVENT)
56 zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf->name);
57
58 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
59 zsend_vrf_delete (client, zvrf);
60 }
61
62 void
63 zebra_vrf_update_all (struct zserv *client)
64 {
65 struct vrf *vrf;
66 vrf_iter_t iter;
67
68 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
69 {
70 if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id)
71 zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id));
72 }
73 }
74
75 /* Callback upon creating a new VRF. */
76 static int
77 zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
78 {
79 struct zebra_vrf *zvrf = *info;
80
81 zlog_info ("ZVRF %s with id %u", name, vrf_id);
82
83 if (! zvrf)
84 {
85 zvrf = zebra_vrf_alloc (vrf_id, name);
86 zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */
87 *info = (void *)zvrf;
88 router_id_init (zvrf);
89 }
90
91 if (zvrf->vrf_id == VRF_UNKNOWN)
92 zvrf->vrf_id = vrf_id;
93
94 return 0;
95 }
96
97 /*
98 * Moving an interface amongst different vrf's
99 * causes the interface to get a new ifindex
100 * so we need to find static routes with
101 * the old ifindex and replace with new
102 * ifindex to insert back into the table
103 */
104 void
105 zebra_vrf_static_route_interface_fixup (struct interface *ifp)
106 {
107 afi_t afi;
108 safi_t safi;
109 struct zebra_vrf *zvrf = zebra_vrf_lookup (ifp->vrf_id);
110 struct route_table *stable = NULL;
111 struct route_node *rn = NULL;
112 struct static_route *si = NULL;
113
114 if (!zvrf)
115 return;
116
117 for (afi = AFI_IP; afi < AFI_MAX; afi++)
118 {
119 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
120 {
121 stable = zvrf->stable[afi][safi];
122 if (stable)
123 for (rn = route_top (stable); rn; rn = route_next (rn))
124 {
125 if (rn->info)
126 {
127 si = rn->info;
128 if ((strcmp (si->ifname, ifp->name) == 0) &&
129 (si->ifindex != ifp->ifindex))
130 {
131 si->ifindex = ifp->ifindex;
132 static_install_route (afi, safi, &rn->p, si);
133 }
134 }
135 }
136 }
137 }
138
139 }
140
141 /* Callback upon enabling a VRF. */
142 static int
143 zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
144 {
145 struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
146 struct route_table *stable = NULL;
147 struct route_node *rn = NULL;
148 struct static_route *si = NULL;
149 struct interface *ifp = NULL;
150 afi_t afi;
151 safi_t safi;
152
153 assert (zvrf);
154
155 zebra_vrf_add_update (zvrf);
156
157 for (afi = AFI_IP; afi < AFI_MAX; afi++)
158 {
159 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
160 {
161 stable = zvrf->stable[afi][safi];
162 if (stable)
163 {
164 for (rn = route_top (stable); rn; rn = route_next (rn))
165 {
166 if (rn->info)
167 {
168 si = rn->info;
169 si->vrf_id = vrf_id;
170 if (si->ifindex)
171 {
172 ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id);
173 if (ifp)
174 si->ifindex = ifp->ifindex;
175 else
176 continue;
177 }
178 static_install_route (afi, safi, &rn->p, si);
179 }
180 }
181 }
182 }
183 }
184 return 0;
185 }
186
187 /* Callback upon disabling a VRF. */
188 static int
189 zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
190 {
191 struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info);
192 struct route_table *stable = NULL;
193 struct route_node *rn = NULL;
194 afi_t afi;
195 safi_t safi;
196
197 if (IS_ZEBRA_DEBUG_KERNEL)
198 zlog_debug ("VRF %s id %u is now disabled.",
199 zvrf->name, zvrf->vrf_id);
200
201 for (afi = AFI_IP; afi < AFI_MAX; afi++)
202 {
203 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
204 {
205 stable = zvrf->stable[afi][safi];
206 if (stable)
207 {
208 for (rn = route_top (stable); rn; rn = route_next (rn))
209 {
210 if (rn->info)
211 static_uninstall_route(afi, safi, &rn->p, rn->info);
212 }
213 }
214 }
215 }
216 return 0;
217 }
218
219 static int
220 zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info)
221 {
222 struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
223
224 assert (zvrf);
225
226 zebra_vrf_delete_update (zvrf);
227
228 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
229 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
230
231 list_delete_all_node (zvrf->rid_all_sorted_list);
232 list_delete_all_node (zvrf->rid_lo_sorted_list);
233
234 XFREE (MTYPE_ZEBRA_VRF, zvrf);
235
236 return 0;
237 }
238
239 /* Lookup the routing table in a VRF based on both VRF-Id and table-id.
240 * NOTE: Table-id is relevant only in the Default VRF.
241 */
242 struct route_table *
243 zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
244 vrf_id_t vrf_id, u_int32_t table_id)
245 {
246 struct route_table *table = NULL;
247
248 if (afi >= AFI_MAX || safi >= SAFI_MAX)
249 return NULL;
250
251 if (vrf_id == VRF_DEFAULT)
252 {
253 if (table_id == RT_TABLE_MAIN ||
254 table_id == zebrad.rtm_table_default)
255 table = zebra_vrf_table (afi, safi, vrf_id);
256 else
257 table = zebra_vrf_other_route_table (afi, table_id, vrf_id);
258 }
259 else
260 table = zebra_vrf_table (afi, safi, vrf_id);
261
262 return table;
263 }
264
265 /*
266 * Create a routing table for the specific AFI/SAFI in the given VRF.
267 */
268 static void
269 zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
270 {
271 rib_table_info_t *info;
272 struct route_table *table;
273
274 assert (!zvrf->table[afi][safi]);
275
276 table = route_table_init ();
277 zvrf->table[afi][safi] = table;
278
279 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
280 info->zvrf = zvrf;
281 info->afi = afi;
282 info->safi = safi;
283 table->info = info;
284 }
285
286 /* Allocate new zebra VRF. */
287 struct zebra_vrf *
288 zebra_vrf_alloc (vrf_id_t vrf_id, const char *name)
289 {
290 struct zebra_vrf *zvrf;
291
292 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
293
294 /* Allocate routing table and static table. */
295 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
296 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
297 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
298 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
299 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
300 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
301 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
302 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
303
304 zvrf->rnh_table[AFI_IP] = route_table_init();
305 zvrf->rnh_table[AFI_IP6] = route_table_init();
306
307 zvrf->import_check_table[AFI_IP] = route_table_init();
308 zvrf->import_check_table[AFI_IP6] = route_table_init();
309
310 /* Set VRF ID */
311 zvrf->vrf_id = vrf_id;
312
313 if (name)
314 {
315 strncpy (zvrf->name, name, strlen(name));
316 zvrf->name[strlen(name)] = '\0';
317 }
318
319 return zvrf;
320 }
321
322 /* Lookup VRF by identifier. */
323 struct zebra_vrf *
324 zebra_vrf_lookup (vrf_id_t vrf_id)
325 {
326 return vrf_info_lookup (vrf_id);
327 }
328
329 /* Lookup the routing table in an enabled VRF. */
330 struct route_table *
331 zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
332 {
333 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
334
335 if (!zvrf)
336 return NULL;
337
338 if (afi >= AFI_MAX || safi >= SAFI_MAX)
339 return NULL;
340
341 return zvrf->table[afi][safi];
342 }
343
344 /* Lookup the static routing table in a VRF. */
345 struct route_table *
346 zebra_vrf_static_table (afi_t afi, safi_t safi, struct zebra_vrf *zvrf)
347 {
348 if (!zvrf)
349 return NULL;
350
351 if (afi >= AFI_MAX || safi >= SAFI_MAX)
352 return NULL;
353
354 return zvrf->stable[afi][safi];
355 }
356
357 struct route_table *
358 zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
359 {
360 struct zebra_vrf *zvrf;
361 rib_table_info_t *info;
362 struct route_table *table;
363
364 zvrf = vrf_info_lookup (vrf_id);
365 if (! zvrf)
366 return NULL;
367
368 if(afi >= AFI_MAX)
369 return NULL;
370
371 if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
372 return NULL;
373
374 if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) && (table_id != zebrad.rtm_table_default))
375 {
376 if (zvrf->other_table[afi][table_id] == NULL)
377 {
378 table = route_table_init();
379 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
380 info->zvrf = zvrf;
381 info->afi = afi;
382 info->safi = SAFI_UNICAST;
383 table->info = info;
384 zvrf->other_table[afi][table_id] = table;
385 }
386
387 return (zvrf->other_table[afi][table_id]);
388 }
389
390 return zvrf->table[afi][SAFI_UNICAST];
391 }
392
393 /* Zebra VRF initialization. */
394 void
395 zebra_vrf_init (void)
396 {
397 vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
398 vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
399 vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
400 vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
401
402 vrf_init ();
403 }