]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vrf.c
*: add indent control files
[mirror_frr.git] / zebra / zebra_vrf.c
CommitLineData
7c551956
DS
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 *
896014f4
DL
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7c551956
DS
20 */
21#include <zebra.h>
22
23#include "log.h"
24#include "linklist.h"
f30c50b9 25#include "command.h"
4a1ab8e4 26#include "memory.h"
05737783 27#include "srcdest_table.h"
7c551956 28
82f97584 29#include "vty.h"
7c551956
DS
30#include "zebra/debug.h"
31#include "zebra/zserv.h"
32#include "zebra/rib.h"
33#include "zebra/zebra_vrf.h"
5a8dfcd8 34#include "zebra/zebra_rnh.h"
7c551956 35#include "zebra/router-id.h"
4a1ab8e4 36#include "zebra/zebra_memory.h"
28f6dde8 37#include "zebra/zebra_static.h"
5a8dfcd8 38#include "zebra/interface.h"
7758e3f3 39#include "zebra/zebra_mpls.h"
13d60d35 40#include "zebra/zebra_vxlan.h"
7c551956
DS
41
42extern struct zebra_t zebrad;
43
44/* VRF information update. */
45static void
46zebra_vrf_add_update (struct zebra_vrf *zvrf)
47{
48 struct listnode *node, *nnode;
49 struct zserv *client;
50
51 if (IS_ZEBRA_DEBUG_EVENT)
661512bf 52 zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name (zvrf));
7c551956
DS
53
54 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
55 zsend_vrf_add (client, zvrf);
56}
57
58static void
59zebra_vrf_delete_update (struct zebra_vrf *zvrf)
60{
61 struct listnode *node, *nnode;
62 struct zserv *client;
63
64 if (IS_ZEBRA_DEBUG_EVENT)
661512bf 65 zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name (zvrf));
7c551956
DS
66
67 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
68 zsend_vrf_delete (client, zvrf);
69}
70
71void
72zebra_vrf_update_all (struct zserv *client)
73{
74 struct vrf *vrf;
7c551956 75
1a1a7065 76 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
7c551956 77 {
1a1a7065 78 if (vrf->vrf_id)
7c551956
DS
79 zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id));
80 }
81}
82
83/* Callback upon creating a new VRF. */
84static int
661512bf 85zebra_vrf_new (struct vrf *vrf)
7c551956 86{
661512bf 87 struct zebra_vrf *zvrf;
7c551956 88
3f6d6a5d 89 if (IS_ZEBRA_DEBUG_EVENT)
661512bf 90 zlog_info ("ZVRF %s with id %u", vrf->name, vrf->vrf_id);
7c551956 91
661512bf
RW
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;
34f8e6af 97
7c551956
DS
98 return 0;
99}
100
fb148af4
DS
101/*
102 * Moving an interface amongst different vrf's
103 * causes the interface to get a new ifindex
104 * so we need to find static routes with
105 * the old ifindex and replace with new
106 * ifindex to insert back into the table
107 */
108void
109zebra_vrf_static_route_interface_fixup (struct interface *ifp)
110{
111 afi_t afi;
112 safi_t safi;
5f3d1bdf 113 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id (ifp->vrf_id);
fb148af4
DS
114 struct route_table *stable = NULL;
115 struct route_node *rn = NULL;
116 struct static_route *si = NULL;
117
118 if (!zvrf)
119 return;
120
121 for (afi = AFI_IP; afi < AFI_MAX; afi++)
122 {
123 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
124 {
125 stable = zvrf->stable[afi][safi];
126 if (stable)
127 for (rn = route_top (stable); rn; rn = route_next (rn))
128 {
129 if (rn->info)
130 {
131 si = rn->info;
132 if ((strcmp (si->ifname, ifp->name) == 0) &&
133 (si->ifindex != ifp->ifindex))
134 {
135 si->ifindex = ifp->ifindex;
c423229b 136 static_install_route (afi, safi, &rn->p, NULL, si);
fb148af4
DS
137 }
138 }
139 }
140 }
141 }
142
143}
144
7c551956
DS
145/* Callback upon enabling a VRF. */
146static int
661512bf 147zebra_vrf_enable (struct vrf *vrf)
7c551956 148{
661512bf 149 struct zebra_vrf *zvrf = vrf->info;
2414ffe5
RW
150 struct route_table *stable;
151 struct route_node *rn;
152 struct static_route *si;
153 struct interface *ifp;
fb148af4
DS
154 afi_t afi;
155 safi_t safi;
7c551956
DS
156
157 assert (zvrf);
158
159 zebra_vrf_add_update (zvrf);
160
fb148af4 161 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2414ffe5
RW
162 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
163 {
164 stable = zvrf->stable[afi][safi];
165 if (! stable)
166 continue;
167
168 for (rn = route_top (stable); rn; rn = route_next (rn))
169 for (si = rn->info; si; si = si->next)
fb148af4 170 {
2414ffe5
RW
171 si->vrf_id = vrf->vrf_id;
172 if (si->ifindex)
fb148af4 173 {
1306c09a 174 ifp = if_lookup_by_name (si->ifname, si->vrf_id);
2414ffe5
RW
175 if (ifp)
176 si->ifindex = ifp->ifindex;
177 else
178 continue;
fb148af4 179 }
c423229b 180 static_install_route (afi, safi, &rn->p, NULL, si);
fb148af4 181 }
2414ffe5
RW
182 }
183
7c551956
DS
184 return 0;
185}
186
187/* Callback upon disabling a VRF. */
188static int
661512bf 189zebra_vrf_disable (struct vrf *vrf)
7c551956 190{
661512bf 191 struct zebra_vrf *zvrf = vrf->info;
2414ffe5
RW
192 struct route_table *stable;
193 struct route_node *rn;
194 struct static_route *si;
fb148af4
DS
195 afi_t afi;
196 safi_t safi;
7c551956
DS
197
198 if (IS_ZEBRA_DEBUG_KERNEL)
199 zlog_debug ("VRF %s id %u is now disabled.",
661512bf 200 zvrf_name (zvrf), zvrf_id (zvrf));
7c551956 201
fb148af4 202 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2414ffe5
RW
203 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
204 {
205 stable = zvrf->stable[afi][safi];
206 if (! stable)
207 continue;
208
209 for (rn = route_top (stable); rn; rn = route_next (rn))
210 for (si = rn->info; si; si = si->next)
c423229b 211 static_uninstall_route(afi, safi, &rn->p, NULL, si);
2414ffe5
RW
212 }
213
7c551956
DS
214 return 0;
215}
216
217static int
661512bf 218zebra_vrf_delete (struct vrf *vrf)
7c551956 219{
661512bf 220 struct zebra_vrf *zvrf = vrf->info;
5a8dfcd8
RW
221 struct route_table *table;
222 u_int32_t table_id;
223 afi_t afi;
224 safi_t safi;
225 unsigned i;
7c551956
DS
226
227 assert (zvrf);
228
229 zebra_vrf_delete_update (zvrf);
230
5a8dfcd8
RW
231 /* uninstall everything */
232 if (! CHECK_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN))
233 {
234 struct listnode *node;
235 struct interface *ifp;
7c551956 236
5a8dfcd8
RW
237 for (afi = AFI_IP; afi <= AFI_IP6; afi++)
238 {
239 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
240 rib_close_table (zvrf->table[afi][safi]);
241
242 if (vrf->vrf_id == VRF_DEFAULT)
243 for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
244 if (zvrf->other_table[afi][table_id])
245 rib_close_table (zvrf->other_table[afi][table_id]);
246 }
247
13d60d35 248 /* Cleanup Vxlan table and update kernel */
249 zebra_vxlan_close_tables (zvrf);
250
5a8dfcd8 251 zebra_mpls_close_tables (zvrf);
7c551956 252
5a8dfcd8
RW
253 for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
254 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
255 }
256
257 /* clean-up work queues */
258 for (i = 0; i < MQ_SIZE; i++)
259 {
260 struct listnode *lnode, *nnode;
261 struct route_node *rnode;
262 rib_dest_t *dest;
263
264 for (ALL_LIST_ELEMENTS (zebrad.mq->subq[i], lnode, nnode, rnode))
265 {
266 dest = rib_dest_from_rnode (rnode);
267 if (dest && rib_dest_vrf (dest) == zvrf)
268 {
269 route_unlock_node (rnode);
270 list_delete_node (zebrad.mq->subq[i], lnode);
06b57ec2 271 zebrad.mq->size--;
5a8dfcd8
RW
272 }
273 }
274 }
275
276 /* release allocated memory */
277 for (afi = AFI_IP; afi <= AFI_IP6; afi++)
278 {
0f124559
RW
279 void *table_info;
280
5a8dfcd8
RW
281 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
282 {
283 table = zvrf->table[afi][safi];
0f124559 284 table_info = table->info;
5a8dfcd8 285 route_table_finish (table);
0f124559 286 XFREE (MTYPE_RIB_TABLE_INFO, table_info);
5a8dfcd8
RW
287
288 table = zvrf->stable[afi][safi];
289 route_table_finish (table);
290 }
291
292 for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++)
293 if (zvrf->other_table[afi][table_id])
294 {
295 table = zvrf->other_table[afi][table_id];
0f124559 296 table_info = table->info;
5a8dfcd8 297 route_table_finish (table);
0f124559 298 XFREE (MTYPE_RIB_TABLE_INFO, table_info);
5a8dfcd8
RW
299 }
300
301 route_table_finish (zvrf->rnh_table[afi]);
302 route_table_finish (zvrf->import_check_table[afi]);
303 }
7c551956
DS
304 list_delete_all_node (zvrf->rid_all_sorted_list);
305 list_delete_all_node (zvrf->rid_lo_sorted_list);
5a8dfcd8 306 XFREE (MTYPE_ZEBRA_VRF, zvrf);
661512bf 307 vrf->info = NULL;
7c551956 308
7c551956
DS
309 return 0;
310}
311
312/* Lookup the routing table in a VRF based on both VRF-Id and table-id.
313 * NOTE: Table-id is relevant only in the Default VRF.
314 */
315struct route_table *
316zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
317 vrf_id_t vrf_id, u_int32_t table_id)
318{
319 struct route_table *table = NULL;
320
321 if (afi >= AFI_MAX || safi >= SAFI_MAX)
322 return NULL;
323
324 if (vrf_id == VRF_DEFAULT)
325 {
326 if (table_id == RT_TABLE_MAIN ||
327 table_id == zebrad.rtm_table_default)
328 table = zebra_vrf_table (afi, safi, vrf_id);
329 else
330 table = zebra_vrf_other_route_table (afi, table_id, vrf_id);
331 }
332 else
333 table = zebra_vrf_table (afi, safi, vrf_id);
334
335 return table;
336}
337
5a8dfcd8 338static void
05737783 339zebra_rtable_node_cleanup (struct route_table *table, struct route_node *node)
5a8dfcd8 340{
f0f77c9a 341 struct route_entry *re, *next;
5a8dfcd8 342
f0f77c9a
DS
343 RNODE_FOREACH_RE_SAFE (node, re, next)
344 rib_unlink (node, re);
5a8dfcd8
RW
345
346 if (node->info)
347 XFREE (MTYPE_RIB_DEST, node->info);
5a8dfcd8
RW
348}
349
350static void
c423229b 351zebra_stable_node_cleanup (struct route_table *table, struct route_node *node)
5a8dfcd8
RW
352{
353 struct static_route *si, *next;
354
355 if (node->info)
356 for (si = node->info; si; si = next)
357 {
358 next = si->next;
359 XFREE (MTYPE_STATIC_ROUTE, si);
360 }
5a8dfcd8
RW
361}
362
363static void
05737783 364zebra_rnhtable_node_cleanup (struct route_table *table, struct route_node *node)
5a8dfcd8
RW
365{
366 if (node->info)
367 zebra_free_rnh (node->info);
5a8dfcd8
RW
368}
369
7c551956
DS
370/*
371 * Create a routing table for the specific AFI/SAFI in the given VRF.
372 */
373static void
374zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
375{
376 rib_table_info_t *info;
377 struct route_table *table;
378
379 assert (!zvrf->table[afi][safi]);
380
05737783
CF
381 if (afi == AFI_IP6)
382 table = srcdest_table_init();
383 else
384 table = route_table_init();
385 table->cleanup = zebra_rtable_node_cleanup;
7c551956
DS
386 zvrf->table[afi][safi] = table;
387
388 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
389 info->zvrf = zvrf;
390 info->afi = afi;
391 info->safi = safi;
392 table->info = info;
393}
394
395/* Allocate new zebra VRF. */
396struct zebra_vrf *
661512bf 397zebra_vrf_alloc (void)
7c551956
DS
398{
399 struct zebra_vrf *zvrf;
5a8dfcd8
RW
400 afi_t afi;
401 safi_t safi;
05737783 402 struct route_table *table;
7c551956
DS
403
404 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
405
5a8dfcd8 406 for (afi = AFI_IP; afi <= AFI_IP6; afi++)
7c551956 407 {
5a8dfcd8 408 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
c423229b
CF
409 {
410 zebra_vrf_table_create (zvrf, afi, safi);
411 if (afi == AFI_IP6)
412 table = srcdest_table_init();
413 else
414 table = route_table_init();
415 table->cleanup = zebra_stable_node_cleanup;
416 zvrf->stable[afi][safi] = table;
417 }
5a8dfcd8 418
05737783
CF
419 table = route_table_init();
420 table->cleanup = zebra_rnhtable_node_cleanup;
421 zvrf->rnh_table[afi] = table;
422
423 table = route_table_init();
424 table->cleanup = zebra_rnhtable_node_cleanup;
425 zvrf->import_check_table[afi] = table;
7c551956
DS
426 }
427
13d60d35 428 zebra_vxlan_init_tables (zvrf);
7758e3f3 429 zebra_mpls_init_tables (zvrf);
430
7c551956
DS
431 return zvrf;
432}
433
434/* Lookup VRF by identifier. */
435struct zebra_vrf *
5f3d1bdf 436zebra_vrf_lookup_by_id (vrf_id_t vrf_id)
7c551956
DS
437{
438 return vrf_info_lookup (vrf_id);
439}
440
51bdc5f8 441/* Lookup VRF by name. */
871d39b3 442struct zebra_vrf *
05e8e11e 443zebra_vrf_lookup_by_name (const char *name)
871d39b3 444{
51bdc5f8 445 struct vrf *vrf;
871d39b3 446
a3d21ef3
DS
447 if (!name)
448 name = VRF_DEFAULT_NAME;
449
05e8e11e 450 vrf = vrf_lookup_by_name (name);
51bdc5f8
RW
451 if (vrf)
452 return ((struct zebra_vrf *) vrf->info);
453
871d39b3
DS
454 return NULL;
455}
456
7c551956
DS
457/* Lookup the routing table in an enabled VRF. */
458struct route_table *
459zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
460{
461 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
462
463 if (!zvrf)
464 return NULL;
465
466 if (afi >= AFI_MAX || safi >= SAFI_MAX)
467 return NULL;
468
469 return zvrf->table[afi][safi];
470}
471
472/* Lookup the static routing table in a VRF. */
473struct route_table *
01bb6d57 474zebra_vrf_static_table (afi_t afi, safi_t safi, struct zebra_vrf *zvrf)
7c551956 475{
7c551956
DS
476 if (!zvrf)
477 return NULL;
478
479 if (afi >= AFI_MAX || safi >= SAFI_MAX)
480 return NULL;
481
482 return zvrf->stable[afi][safi];
483}
484
485struct route_table *
486zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
487{
488 struct zebra_vrf *zvrf;
489 rib_table_info_t *info;
490 struct route_table *table;
491
492 zvrf = vrf_info_lookup (vrf_id);
493 if (! zvrf)
494 return NULL;
495
496 if(afi >= AFI_MAX)
497 return NULL;
498
499 if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
500 return NULL;
501
502 if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) && (table_id != zebrad.rtm_table_default))
503 {
504 if (zvrf->other_table[afi][table_id] == NULL)
505 {
05737783 506 table = (afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
7c551956
DS
507 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
508 info->zvrf = zvrf;
509 info->afi = afi;
510 info->safi = SAFI_UNICAST;
511 table->info = info;
512 zvrf->other_table[afi][table_id] = table;
513 }
514
515 return (zvrf->other_table[afi][table_id]);
516 }
517
518 return zvrf->table[afi][SAFI_UNICAST];
519}
520
f30c50b9
RW
521static int
522vrf_config_write (struct vty *vty)
523{
51bdc5f8 524 struct vrf *vrf;
f30c50b9
RW
525 struct zebra_vrf *zvrf;
526
806f8760 527 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
f30c50b9 528 {
51bdc5f8 529 zvrf = vrf->info;
661512bf 530 if (! zvrf || strcmp (zvrf_name (zvrf), VRF_DEFAULT_NAME))
f30c50b9 531 {
5c7571d4
DL
532 vty_out (vty, "vrf %s\n", zvrf_name(zvrf));
533 vty_out (vty, "!\n");
f30c50b9
RW
534 }
535 }
536 return 0;
537}
538
7c551956
DS
539/* Zebra VRF initialization. */
540void
541zebra_vrf_init (void)
542{
6df85364
DS
543 vrf_init (zebra_vrf_new,
544 zebra_vrf_enable,
545 zebra_vrf_disable,
546 zebra_vrf_delete);
7c551956 547
7ddcfca4 548 vrf_cmd_init (vrf_config_write);
7c551956 549}