]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vrf.c
Merge pull request #920 from opensourcerouting/static-routes-ifindex-update-3.0
[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 #include "command.h"
27 #include "memory.h"
28 #include "srcdest_table.h"
29
30 #include "vty.h"
31 #include "zebra/debug.h"
32 #include "zebra/zserv.h"
33 #include "zebra/rib.h"
34 #include "zebra/zebra_vrf.h"
35 #include "zebra/zebra_rnh.h"
36 #include "zebra/router-id.h"
37 #include "zebra/zebra_memory.h"
38 #include "zebra/zebra_static.h"
39 #include "zebra/interface.h"
40 #include "zebra/zebra_mpls.h"
41
42 extern struct zebra_t zebrad;
43
44 /* VRF information update. */
45 static void
46 zebra_vrf_add_update (struct zebra_vrf *zvrf)
47 {
48 struct listnode *node, *nnode;
49 struct zserv *client;
50
51 if (IS_ZEBRA_DEBUG_EVENT)
52 zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name (zvrf));
53
54 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
55 zsend_vrf_add (client, zvrf);
56 }
57
58 static void
59 zebra_vrf_delete_update (struct zebra_vrf *zvrf)
60 {
61 struct listnode *node, *nnode;
62 struct zserv *client;
63
64 if (IS_ZEBRA_DEBUG_EVENT)
65 zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name (zvrf));
66
67 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
68 zsend_vrf_delete (client, zvrf);
69 }
70
71 void
72 zebra_vrf_update_all (struct zserv *client)
73 {
74 struct vrf *vrf;
75
76 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
77 {
78 if (vrf->vrf_id)
79 zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id));
80 }
81 }
82
83 /* Callback upon creating a new VRF. */
84 static int
85 zebra_vrf_new (struct vrf *vrf)
86 {
87 struct zebra_vrf *zvrf;
88
89 if (IS_ZEBRA_DEBUG_EVENT)
90 zlog_info ("ZVRF %s with id %u", vrf->name, vrf->vrf_id);
91
92 zvrf = zebra_vrf_alloc ();
93 zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */
94 router_id_init (zvrf);
95 vrf->info = zvrf;
96 zvrf->vrf = vrf;
97
98 return 0;
99 }
100
101 /* Callback upon enabling a VRF. */
102 static int
103 zebra_vrf_enable (struct vrf *vrf)
104 {
105 struct zebra_vrf *zvrf = vrf->info;
106 struct route_table *stable;
107 struct route_node *rn;
108 struct static_route *si;
109 struct interface *ifp;
110 afi_t afi;
111 safi_t safi;
112
113 assert (zvrf);
114
115 zebra_vrf_add_update (zvrf);
116
117 for (afi = AFI_IP; afi < AFI_MAX; afi++)
118 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
119 {
120 stable = zvrf->stable[afi][safi];
121 if (! stable)
122 continue;
123
124 for (rn = route_top (stable); rn; rn = route_next (rn))
125 for (si = rn->info; si; si = si->next)
126 {
127 si->vrf_id = vrf->vrf_id;
128 if (si->ifindex)
129 {
130 ifp = if_lookup_by_name (si->ifname, si->vrf_id);
131 if (ifp)
132 si->ifindex = ifp->ifindex;
133 else
134 continue;
135 }
136 static_install_route (afi, safi, &rn->p, NULL, si);
137 }
138 }
139
140 return 0;
141 }
142
143 /* Callback upon disabling a VRF. */
144 static int
145 zebra_vrf_disable (struct vrf *vrf)
146 {
147 struct zebra_vrf *zvrf = vrf->info;
148 struct route_table *stable;
149 struct route_node *rn;
150 struct static_route *si;
151 afi_t afi;
152 safi_t safi;
153
154 if (IS_ZEBRA_DEBUG_KERNEL)
155 zlog_debug ("VRF %s id %u is now disabled.",
156 zvrf_name (zvrf), zvrf_id (zvrf));
157
158 for (afi = AFI_IP; afi < AFI_MAX; afi++)
159 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
160 {
161 stable = zvrf->stable[afi][safi];
162 if (! stable)
163 continue;
164
165 for (rn = route_top (stable); rn; rn = route_next (rn))
166 for (si = rn->info; si; si = si->next)
167 static_uninstall_route(afi, safi, &rn->p, NULL, si);
168 }
169
170 return 0;
171 }
172
173 static int
174 zebra_vrf_delete (struct vrf *vrf)
175 {
176 struct zebra_vrf *zvrf = vrf->info;
177 struct route_table *table;
178 u_int32_t table_id;
179 afi_t afi;
180 safi_t safi;
181 unsigned i;
182
183 assert (zvrf);
184
185 zebra_vrf_delete_update (zvrf);
186
187 /* uninstall everything */
188 if (! CHECK_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN))
189 {
190 struct listnode *node;
191 struct interface *ifp;
192
193 for (afi = AFI_IP; afi <= AFI_IP6; afi++)
194 {
195 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
196 rib_close_table (zvrf->table[afi][safi]);
197
198 if (vrf->vrf_id == VRF_DEFAULT)
199 for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
200 if (zvrf->other_table[afi][table_id])
201 rib_close_table (zvrf->other_table[afi][table_id]);
202 }
203
204 zebra_mpls_close_tables (zvrf);
205 zebra_pw_exit (zvrf);
206
207 for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
208 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
209 }
210
211 /* clean-up work queues */
212 for (i = 0; i < MQ_SIZE; i++)
213 {
214 struct listnode *lnode, *nnode;
215 struct route_node *rnode;
216 rib_dest_t *dest;
217
218 for (ALL_LIST_ELEMENTS (zebrad.mq->subq[i], lnode, nnode, rnode))
219 {
220 dest = rib_dest_from_rnode (rnode);
221 if (dest && rib_dest_vrf (dest) == zvrf)
222 {
223 route_unlock_node (rnode);
224 list_delete_node (zebrad.mq->subq[i], lnode);
225 zebrad.mq->size--;
226 }
227 }
228 }
229
230 /* release allocated memory */
231 for (afi = AFI_IP; afi <= AFI_IP6; afi++)
232 {
233 void *table_info;
234
235 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
236 {
237 table = zvrf->table[afi][safi];
238 table_info = table->info;
239 route_table_finish (table);
240 XFREE (MTYPE_RIB_TABLE_INFO, table_info);
241
242 table = zvrf->stable[afi][safi];
243 route_table_finish (table);
244 }
245
246 for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
247 if (zvrf->other_table[afi][table_id])
248 {
249 table = zvrf->other_table[afi][table_id];
250 table_info = table->info;
251 route_table_finish (table);
252 XFREE (MTYPE_RIB_TABLE_INFO, table_info);
253 }
254
255 route_table_finish (zvrf->rnh_table[afi]);
256 route_table_finish (zvrf->import_check_table[afi]);
257 }
258 list_delete_all_node (zvrf->rid_all_sorted_list);
259 list_delete_all_node (zvrf->rid_lo_sorted_list);
260 XFREE (MTYPE_ZEBRA_VRF, zvrf);
261 vrf->info = NULL;
262
263 return 0;
264 }
265
266 /* Lookup the routing table in a VRF based on both VRF-Id and table-id.
267 * NOTE: Table-id is relevant only in the Default VRF.
268 */
269 struct route_table *
270 zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
271 vrf_id_t vrf_id, u_int32_t table_id)
272 {
273 struct route_table *table = NULL;
274
275 if (afi >= AFI_MAX || safi >= SAFI_MAX)
276 return NULL;
277
278 if (vrf_id == VRF_DEFAULT)
279 {
280 if (table_id == RT_TABLE_MAIN ||
281 table_id == zebrad.rtm_table_default)
282 table = zebra_vrf_table (afi, safi, vrf_id);
283 else
284 table = zebra_vrf_other_route_table (afi, table_id, vrf_id);
285 }
286 else
287 table = zebra_vrf_table (afi, safi, vrf_id);
288
289 return table;
290 }
291
292 static void
293 zebra_rtable_node_cleanup (struct route_table *table, struct route_node *node)
294 {
295 struct rib *rib, *next;
296
297 RNODE_FOREACH_RIB_SAFE (node, rib, next)
298 rib_unlink (node, rib);
299
300 if (node->info)
301 XFREE (MTYPE_RIB_DEST, node->info);
302 }
303
304 static void
305 zebra_stable_node_cleanup (struct route_table *table, struct route_node *node)
306 {
307 struct static_route *si, *next;
308
309 if (node->info)
310 for (si = node->info; si; si = next)
311 {
312 next = si->next;
313 XFREE (MTYPE_STATIC_ROUTE, si);
314 }
315 }
316
317 static void
318 zebra_rnhtable_node_cleanup (struct route_table *table, struct route_node *node)
319 {
320 if (node->info)
321 zebra_free_rnh (node->info);
322 }
323
324 /*
325 * Create a routing table for the specific AFI/SAFI in the given VRF.
326 */
327 static void
328 zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
329 {
330 rib_table_info_t *info;
331 struct route_table *table;
332
333 assert (!zvrf->table[afi][safi]);
334
335 if (afi == AFI_IP6)
336 table = srcdest_table_init();
337 else
338 table = route_table_init();
339 table->cleanup = zebra_rtable_node_cleanup;
340 zvrf->table[afi][safi] = table;
341
342 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
343 info->zvrf = zvrf;
344 info->afi = afi;
345 info->safi = safi;
346 table->info = info;
347 }
348
349 /* Allocate new zebra VRF. */
350 struct zebra_vrf *
351 zebra_vrf_alloc (void)
352 {
353 struct zebra_vrf *zvrf;
354 afi_t afi;
355 safi_t safi;
356 struct route_table *table;
357
358 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
359
360 for (afi = AFI_IP; afi <= AFI_IP6; afi++)
361 {
362 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
363 {
364 zebra_vrf_table_create (zvrf, afi, safi);
365 if (afi == AFI_IP6)
366 table = srcdest_table_init();
367 else
368 table = route_table_init();
369 table->cleanup = zebra_stable_node_cleanup;
370 zvrf->stable[afi][safi] = table;
371 }
372
373 table = route_table_init();
374 table->cleanup = zebra_rnhtable_node_cleanup;
375 zvrf->rnh_table[afi] = table;
376
377 table = route_table_init();
378 table->cleanup = zebra_rnhtable_node_cleanup;
379 zvrf->import_check_table[afi] = table;
380 }
381
382 zebra_mpls_init_tables (zvrf);
383 zebra_pw_init (zvrf);
384
385 return zvrf;
386 }
387
388 /* Lookup VRF by identifier. */
389 struct zebra_vrf *
390 zebra_vrf_lookup_by_id (vrf_id_t vrf_id)
391 {
392 return vrf_info_lookup (vrf_id);
393 }
394
395 /* Lookup VRF by name. */
396 struct zebra_vrf *
397 zebra_vrf_lookup_by_name (const char *name)
398 {
399 struct vrf *vrf;
400
401 if (!name)
402 name = VRF_DEFAULT_NAME;
403
404 vrf = vrf_lookup_by_name (name);
405 if (vrf)
406 return ((struct zebra_vrf *) vrf->info);
407
408 return NULL;
409 }
410
411 /* Lookup the routing table in an enabled VRF. */
412 struct route_table *
413 zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
414 {
415 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
416
417 if (!zvrf)
418 return NULL;
419
420 if (afi >= AFI_MAX || safi >= SAFI_MAX)
421 return NULL;
422
423 return zvrf->table[afi][safi];
424 }
425
426 /* Lookup the static routing table in a VRF. */
427 struct route_table *
428 zebra_vrf_static_table (afi_t afi, safi_t safi, struct zebra_vrf *zvrf)
429 {
430 if (!zvrf)
431 return NULL;
432
433 if (afi >= AFI_MAX || safi >= SAFI_MAX)
434 return NULL;
435
436 return zvrf->stable[afi][safi];
437 }
438
439 struct route_table *
440 zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
441 {
442 struct zebra_vrf *zvrf;
443 rib_table_info_t *info;
444 struct route_table *table;
445
446 zvrf = vrf_info_lookup (vrf_id);
447 if (! zvrf)
448 return NULL;
449
450 if(afi >= AFI_MAX)
451 return NULL;
452
453 if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
454 return NULL;
455
456 if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) && (table_id != zebrad.rtm_table_default))
457 {
458 if (zvrf->other_table[afi][table_id] == NULL)
459 {
460 table = (afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
461 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
462 info->zvrf = zvrf;
463 info->afi = afi;
464 info->safi = SAFI_UNICAST;
465 table->info = info;
466 zvrf->other_table[afi][table_id] = table;
467 }
468
469 return (zvrf->other_table[afi][table_id]);
470 }
471
472 return zvrf->table[afi][SAFI_UNICAST];
473 }
474
475 static int
476 vrf_config_write (struct vty *vty)
477 {
478 struct vrf *vrf;
479 struct zebra_vrf *zvrf;
480
481 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
482 {
483 zvrf = vrf->info;
484 if (! zvrf || strcmp (zvrf_name (zvrf), VRF_DEFAULT_NAME))
485 {
486 vty_out (vty, "vrf %s%s", zvrf_name (zvrf), VTY_NEWLINE);
487 vty_out (vty, "!%s", VTY_NEWLINE);
488 }
489 }
490 return 0;
491 }
492
493 /* Zebra VRF initialization. */
494 void
495 zebra_vrf_init (void)
496 {
497 vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
498 vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
499 vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
500 vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
501
502 vrf_init ();
503 vrf_cmd_init (vrf_config_write);
504 }