]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vrf.c
Merge pull request #6122 from donaldsharp/more_cbit_fun
[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"
78dd30b2 28#include "vrf.h"
82f97584 29#include "vty.h"
78dd30b2 30
89272910 31#include "zebra/zebra_router.h"
df9c8c57 32#include "zebra/rtadv.h"
7c551956 33#include "zebra/debug.h"
bf094f69 34#include "zebra/zapi_msg.h"
7c551956
DS
35#include "zebra/rib.h"
36#include "zebra/zebra_vrf.h"
5a8dfcd8 37#include "zebra/zebra_rnh.h"
7c551956 38#include "zebra/router-id.h"
4a1ab8e4 39#include "zebra/zebra_memory.h"
5a8dfcd8 40#include "zebra/interface.h"
7758e3f3 41#include "zebra/zebra_mpls.h"
13d60d35 42#include "zebra/zebra_vxlan.h"
3bc34908 43#include "zebra/zebra_netns_notify.h"
7cf16e19 44#include "zebra/zebra_routemap.h"
7c551956 45
9d97533e 46static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
47 safi_t safi);
48static void zebra_rnhtable_node_cleanup(struct route_table *table,
49 struct route_node *node);
50
c1344b54
DL
51DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_VRF, "ZEBRA VRF")
52DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table")
d8612e65 53
7c551956 54/* VRF information update. */
d62a17ae 55static void zebra_vrf_add_update(struct zebra_vrf *zvrf)
7c551956 56{
d62a17ae 57 struct listnode *node, *nnode;
58 struct zserv *client;
7c551956 59
d62a17ae 60 if (IS_ZEBRA_DEBUG_EVENT)
61 zlog_debug("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name(zvrf));
7c551956 62
17da84a4
KS
63 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
64 /* Do not send unsolicited messages to synchronous clients. */
65 if (client->synchronous)
66 continue;
67
d62a17ae 68 zsend_vrf_add(client, zvrf);
17da84a4 69 }
7c551956
DS
70}
71
d62a17ae 72static void zebra_vrf_delete_update(struct zebra_vrf *zvrf)
7c551956 73{
d62a17ae 74 struct listnode *node, *nnode;
75 struct zserv *client;
7c551956 76
d62a17ae 77 if (IS_ZEBRA_DEBUG_EVENT)
78 zlog_debug("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name(zvrf));
7c551956 79
17da84a4
KS
80 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
81 /* Do not send unsolicited messages to synchronous clients. */
82 if (client->synchronous)
83 continue;
84
d62a17ae 85 zsend_vrf_delete(client, zvrf);
17da84a4 86 }
7c551956
DS
87}
88
d62a17ae 89void zebra_vrf_update_all(struct zserv *client)
7c551956 90{
d62a17ae 91 struct vrf *vrf;
7c551956 92
a2addae8 93 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
4691b65a 94 if (vrf->vrf_id != VRF_UNKNOWN)
d62a17ae 95 zsend_vrf_add(client, vrf_info_lookup(vrf->vrf_id));
96 }
7c551956
DS
97}
98
99/* Callback upon creating a new VRF. */
d62a17ae 100static int zebra_vrf_new(struct vrf *vrf)
7c551956 101{
d62a17ae 102 struct zebra_vrf *zvrf;
7c551956 103
d62a17ae 104 if (IS_ZEBRA_DEBUG_EVENT)
14a4d9d0 105 zlog_debug("VRF %s created, id %u", vrf->name, vrf->vrf_id);
7c551956 106
d62a17ae 107 zvrf = zebra_vrf_alloc();
d62a17ae 108 vrf->info = zvrf;
109 zvrf->vrf = vrf;
d8612e65
DS
110
111 otable_init(&zvrf->other_tables);
112
fbb65ff5 113 router_id_init(zvrf);
d62a17ae 114 return 0;
7c551956
DS
115}
116
117/* Callback upon enabling a VRF. */
d62a17ae 118static int zebra_vrf_enable(struct vrf *vrf)
7c551956 119{
d62a17ae 120 struct zebra_vrf *zvrf = vrf->info;
9d97533e 121 struct route_table *table;
d62a17ae 122 afi_t afi;
123 safi_t safi;
124
125 assert(zvrf);
84915b0a 126 if (IS_ZEBRA_DEBUG_EVENT)
996c9314
LB
127 zlog_debug("VRF %s id %u is now active", zvrf_name(zvrf),
128 zvrf_id(zvrf));
d62a17ae 129
fbb65ff5
PG
130 if (vrf_is_backend_netns())
131 zvrf->zns = zebra_ns_lookup((ns_id_t)vrf->vrf_id);
132 else
133 zvrf->zns = zebra_ns_lookup(NS_DEFAULT);
df9c8c57
PG
134#if defined(HAVE_RTADV)
135 rtadv_init(zvrf);
136#endif
137
84915b0a 138 /* Inform clients that the VRF is now active. This is an
139 * add for the clients.
140 */
d62a17ae 141
8288a24f 142 zebra_vrf_add_update(zvrf);
9d97533e 143 /* Allocate tables */
144 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
145 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
146 zebra_vrf_table_create(zvrf, afi, safi);
147
148 table = route_table_init();
149 table->cleanup = zebra_rnhtable_node_cleanup;
150 zvrf->rnh_table[afi] = table;
151
152 table = route_table_init();
153 table->cleanup = zebra_rnhtable_node_cleanup;
154 zvrf->import_check_table[afi] = table;
155 }
156
84915b0a 157 /* Kick off any VxLAN-EVPN processing. */
158 zebra_vxlan_vrf_enable(zvrf);
159
d62a17ae 160 return 0;
7c551956
DS
161}
162
163/* Callback upon disabling a VRF. */
d62a17ae 164static int zebra_vrf_disable(struct vrf *vrf)
7c551956 165{
d62a17ae 166 struct zebra_vrf *zvrf = vrf->info;
9d97533e 167 struct interface *ifp;
d62a17ae 168 afi_t afi;
169 safi_t safi;
9d97533e 170 unsigned i;
d62a17ae 171
84915b0a 172 assert(zvrf);
173 if (IS_ZEBRA_DEBUG_EVENT)
996c9314
LB
174 zlog_debug("VRF %s id %u is now inactive", zvrf_name(zvrf),
175 zvrf_id(zvrf));
d62a17ae 176
84915b0a 177 /* Stop any VxLAN-EVPN processing. */
178 zebra_vxlan_vrf_disable(zvrf);
d62a17ae 179
df9c8c57
PG
180#if defined(HAVE_RTADV)
181 rtadv_terminate(zvrf);
182#endif
183
84915b0a 184 /* Inform clients that the VRF is now inactive. This is a
185 * delete for the clients.
186 */
d62a17ae 187 zebra_vrf_delete_update(zvrf);
188
9d97533e 189 /* If asked to retain routes, there's nothing more to do. */
190 if (CHECK_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN))
191 return 0;
192
193 /* Remove all routes. */
194 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
41dc8c14
DS
195 route_table_finish(zvrf->rnh_table[afi]);
196 zvrf->rnh_table[afi] = NULL;
197 route_table_finish(zvrf->import_check_table[afi]);
198 zvrf->import_check_table[afi] = NULL;
199
9d97533e 200 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
201 rib_close_table(zvrf->table[afi][safi]);
9d97533e 202 }
203
204 /* Cleanup Vxlan, MPLS and PW tables. */
205 zebra_vxlan_cleanup_tables(zvrf);
206 zebra_mpls_cleanup_tables(zvrf);
207 zebra_pw_exit(zvrf);
208
996c9314
LB
209 /* Remove link-local IPv4 addresses created for BGP unnumbered peering.
210 */
9d97533e 211 FOR_ALL_INTERFACES (vrf, ifp)
212 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
213
214 /* clean-up work queues */
215 for (i = 0; i < MQ_SIZE; i++) {
216 struct listnode *lnode, *nnode;
217 struct route_node *rnode;
218 rib_dest_t *dest;
219
ea45a4e7 220 for (ALL_LIST_ELEMENTS(zrouter.mq->subq[i], lnode, nnode,
996c9314 221 rnode)) {
9d97533e 222 dest = rib_dest_from_rnode(rnode);
223 if (dest && rib_dest_vrf(dest) == zvrf) {
224 route_unlock_node(rnode);
ea45a4e7
DS
225 list_delete_node(zrouter.mq->subq[i], lnode);
226 zrouter.mq->size--;
9d97533e 227 }
d62a17ae 228 }
9d97533e 229 }
7c551956 230
9d97533e 231 /* Cleanup (free) routing tables and NHT tables. */
232 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
89272910
DS
233 /*
234 * Set the table pointer to NULL as that
235 * we no-longer need a copy of it, nor do we
236 * own this data, the zebra_router structure
237 * owns these tables. Once we've cleaned up the
238 * table, see rib_close_table above
239 * we no-longer need this pointer.
240 */
bd4fb615
DS
241 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
242 zebra_router_release_table(zvrf, zvrf->table_id, afi,
243 safi);
9d97533e 244 zvrf->table[afi][safi] = NULL;
bd4fb615 245 }
5a8dfcd8
RW
246 }
247
d62a17ae 248 return 0;
7c551956
DS
249}
250
d62a17ae 251static int zebra_vrf_delete(struct vrf *vrf)
7c551956 252{
d62a17ae 253 struct zebra_vrf *zvrf = vrf->info;
d8612e65 254 struct other_route_table *otable;
d62a17ae 255 struct route_table *table;
d62a17ae 256 afi_t afi;
257 safi_t safi;
258 unsigned i;
259
260 assert(zvrf);
84915b0a 261 if (IS_ZEBRA_DEBUG_EVENT)
996c9314
LB
262 zlog_debug("VRF %s id %u deleted", zvrf_name(zvrf),
263 zvrf_id(zvrf));
5a8dfcd8 264
d62a17ae 265 /* clean-up work queues */
266 for (i = 0; i < MQ_SIZE; i++) {
267 struct listnode *lnode, *nnode;
268 struct route_node *rnode;
269 rib_dest_t *dest;
270
ea45a4e7 271 for (ALL_LIST_ELEMENTS(zrouter.mq->subq[i], lnode, nnode,
996c9314 272 rnode)) {
d62a17ae 273 dest = rib_dest_from_rnode(rnode);
274 if (dest && rib_dest_vrf(dest) == zvrf) {
275 route_unlock_node(rnode);
ea45a4e7
DS
276 list_delete_node(zrouter.mq->subq[i], lnode);
277 zrouter.mq->size--;
d62a17ae 278 }
279 }
5a8dfcd8 280 }
5a8dfcd8 281
84915b0a 282 /* Free Vxlan and MPLS. */
283 zebra_vxlan_close_tables(zvrf);
284 zebra_mpls_close_tables(zvrf);
285
d62a17ae 286 /* release allocated memory */
287 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
d62a17ae 288 for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
289 table = zvrf->table[afi][safi];
9d97533e 290 if (table) {
bd4fb615
DS
291 zebra_router_release_table(zvrf, zvrf->table_id,
292 afi, safi);
293 zvrf->table[afi][safi] = NULL;
9d97533e 294 }
d62a17ae 295 }
5a8dfcd8 296
41dc8c14
DS
297 if (zvrf->rnh_table[afi])
298 route_table_finish(zvrf->rnh_table[afi]);
299 if (zvrf->import_check_table[afi])
300 route_table_finish(zvrf->import_check_table[afi]);
5a8dfcd8 301 }
b7cfce93 302
d8612e65
DS
303 otable = otable_pop(&zvrf->other_tables);
304 while (otable) {
305 zebra_router_release_table(zvrf, otable->table_id,
306 otable->afi, otable->safi);
307 XFREE(MTYPE_OTHER_TABLE, otable);
308
309 otable = otable_pop(&zvrf->other_tables);
310 }
311
84915b0a 312 /* Cleanup EVPN states for vrf */
b7cfce93
MK
313 zebra_vxlan_vrf_delete(zvrf);
314
d62a17ae 315 list_delete_all_node(zvrf->rid_all_sorted_list);
316 list_delete_all_node(zvrf->rid_lo_sorted_list);
d8612e65
DS
317
318 otable_fini(&zvrf->other_tables);
d62a17ae 319 XFREE(MTYPE_ZEBRA_VRF, zvrf);
320 vrf->info = NULL;
5a8dfcd8 321
d62a17ae 322 return 0;
7c551956
DS
323}
324
ecbc5a37
PG
325static int zebra_vrf_update(struct vrf *vrf)
326{
327 struct zebra_vrf *zvrf = vrf->info;
328
329 assert(zvrf);
330 if (IS_ZEBRA_DEBUG_EVENT)
331 zlog_debug("VRF %s id %u, name updated", vrf->name,
332 zvrf_id(zvrf));
333 zebra_vrf_add_update(zvrf);
334 return 0;
335}
336
337
22bd3e94 338/* Return if this VRF has any FRR configuration or not.
339 * IMPORTANT: This function needs to be updated when additional configuration
340 * is added for a VRF.
341 */
342int zebra_vrf_has_config(struct zebra_vrf *zvrf)
343{
22bd3e94 344 /* EVPN L3-VNI? */
345 if (zvrf->l3vni)
346 return 1;
347
348 return 0;
349}
350
7c551956 351/* Lookup the routing table in a VRF based on both VRF-Id and table-id.
e9748a89
PG
352 * NOTE: Table-id is relevant on two modes:
353 * - case VRF backend is default : on default VRF only
354 * - case VRF backend is netns : on all VRFs
7c551956 355 */
c7c0b007
SW
356struct route_table *zebra_vrf_lookup_table_with_table_id(afi_t afi, safi_t safi,
357 vrf_id_t vrf_id,
358 uint32_t table_id)
7c551956 359{
8ab39b7f 360 struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
d8612e65 361 struct other_route_table ort, *otable;
8ab39b7f
DS
362
363 if (!zvrf)
364 return NULL;
d62a17ae 365
366 if (afi >= AFI_MAX || safi >= SAFI_MAX)
367 return NULL;
368
8ab39b7f
DS
369 if (table_id == zvrf->table_id)
370 return zebra_vrf_table(afi, safi, vrf_id);
d62a17ae 371
d8612e65
DS
372 ort.afi = afi;
373 ort.safi = safi;
374 ort.table_id = table_id;
375 otable = otable_find(&zvrf->other_tables, &ort);
c7c0b007 376
d8612e65
DS
377 if (otable)
378 return otable->table;
379
c7c0b007
SW
380 return NULL;
381}
382
383struct route_table *zebra_vrf_get_table_with_table_id(afi_t afi, safi_t safi,
384 vrf_id_t vrf_id,
385 uint32_t table_id)
386{
387 struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
388 struct other_route_table *otable;
389 struct route_table *table;
390
391 table = zebra_vrf_lookup_table_with_table_id(afi, safi, vrf_id,
392 table_id);
393
394 if (table)
395 goto done;
396
397 /* Create it as an `other` table */
d8612e65
DS
398 table = zebra_router_get_table(zvrf, table_id, afi, safi);
399
400 otable = XCALLOC(MTYPE_OTHER_TABLE, sizeof(*otable));
401 otable->afi = afi;
402 otable->safi = safi;
403 otable->table_id = table_id;
404 otable->table = table;
405 otable_add(&zvrf->other_tables, otable);
d62a17ae 406
c7c0b007 407done:
d62a17ae 408 return table;
7c551956
DS
409}
410
5335613b
DS
411void zebra_rtable_node_cleanup(struct route_table *table,
412 struct route_node *node)
5a8dfcd8 413{
d62a17ae 414 struct route_entry *re, *next;
5a8dfcd8 415
a2addae8 416 RNODE_FOREACH_RE_SAFE (node, re, next) {
407c87a6
DS
417 rib_unlink(node, re);
418 }
5a8dfcd8 419
699dae23
DS
420 if (node->info) {
421 rib_dest_t *dest = node->info;
422
aa57abfb 423 rnh_list_fini(&dest->nht);
699dae23
DS
424 XFREE(MTYPE_RIB_DEST, node->info);
425 }
5a8dfcd8
RW
426}
427
d62a17ae 428static void zebra_rnhtable_node_cleanup(struct route_table *table,
429 struct route_node *node)
5a8dfcd8 430{
d62a17ae 431 if (node->info)
432 zebra_free_rnh(node->info);
5a8dfcd8
RW
433}
434
7c551956
DS
435/*
436 * Create a routing table for the specific AFI/SAFI in the given VRF.
437 */
d62a17ae 438static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
439 safi_t safi)
7c551956 440{
c86ba6c2
DS
441 struct route_node *rn;
442 struct prefix p;
443
d62a17ae 444 assert(!zvrf->table[afi][safi]);
445
ea66cec4
DS
446 zvrf->table[afi][safi] =
447 zebra_router_get_table(zvrf, zvrf->table_id, afi, safi);
c86ba6c2
DS
448
449 memset(&p, 0, sizeof(p));
450 p.family = afi2family(afi);
451
452 rn = srcdest_rnode_get(zvrf->table[afi][safi], &p, NULL);
453 zebra_rib_create_dest(rn);
7c551956
DS
454}
455
456/* Allocate new zebra VRF. */
d62a17ae 457struct zebra_vrf *zebra_vrf_alloc(void)
7c551956 458{
d62a17ae 459 struct zebra_vrf *zvrf;
d62a17ae 460
461 zvrf = XCALLOC(MTYPE_ZEBRA_VRF, sizeof(struct zebra_vrf));
462
d62a17ae 463 zebra_vxlan_init_tables(zvrf);
464 zebra_mpls_init_tables(zvrf);
6833ae01 465 zebra_pw_init(zvrf);
e9748a89
PG
466 zvrf->table_id = RT_TABLE_MAIN;
467 /* by default table ID is default one */
d62a17ae 468 return zvrf;
7c551956
DS
469}
470
471/* Lookup VRF by identifier. */
d62a17ae 472struct zebra_vrf *zebra_vrf_lookup_by_id(vrf_id_t vrf_id)
7c551956 473{
d62a17ae 474 return vrf_info_lookup(vrf_id);
7c551956
DS
475}
476
51bdc5f8 477/* Lookup VRF by name. */
d62a17ae 478struct zebra_vrf *zebra_vrf_lookup_by_name(const char *name)
871d39b3 479{
d62a17ae 480 struct vrf *vrf;
871d39b3 481
d62a17ae 482 if (!name)
483 name = VRF_DEFAULT_NAME;
a3d21ef3 484
d62a17ae 485 vrf = vrf_lookup_by_name(name);
486 if (vrf)
487 return ((struct zebra_vrf *)vrf->info);
51bdc5f8 488
d62a17ae 489 return NULL;
871d39b3
DS
490}
491
7c551956 492/* Lookup the routing table in an enabled VRF. */
d62a17ae 493struct route_table *zebra_vrf_table(afi_t afi, safi_t safi, vrf_id_t vrf_id)
7c551956 494{
d62a17ae 495 struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
7c551956 496
d62a17ae 497 if (!zvrf)
498 return NULL;
7c551956 499
d62a17ae 500 if (afi >= AFI_MAX || safi >= SAFI_MAX)
501 return NULL;
7c551956 502
d62a17ae 503 return zvrf->table[afi][safi];
7c551956
DS
504}
505
d62a17ae 506static int vrf_config_write(struct vty *vty)
f30c50b9 507{
d62a17ae 508 struct vrf *vrf;
509 struct zebra_vrf *zvrf;
510
a2addae8 511 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 512 zvrf = vrf->info;
1e9f448f
DS
513
514 if (!zvrf)
515 continue;
516
a5654735
MK
517 if (zvrf_id(zvrf) == VRF_DEFAULT) {
518 if (zvrf->l3vni)
8d0f01f1
CS
519 vty_out(vty, "vni %u%s\n", zvrf->l3vni,
520 is_l3vni_for_prefix_routes_only(
521 zvrf->l3vni)
522 ? " prefix-routes-only"
523 : "");
5a0bdc78
PG
524 if (zvrf->zebra_rnh_ip_default_route)
525 vty_out(vty, "ip nht resolve-via-default\n");
526
527 if (zvrf->zebra_rnh_ipv6_default_route)
528 vty_out(vty, "ipv6 nht resolve-via-default\n");
c319e19d
QY
529 } else {
530 vty_frame(vty, "vrf %s\n", zvrf_name(zvrf));
22bd3e94 531 if (zvrf->l3vni)
996c9314
LB
532 vty_out(vty, " vni %u%s\n", zvrf->l3vni,
533 is_l3vni_for_prefix_routes_only(
534 zvrf->l3vni)
535 ? " prefix-routes-only"
536 : "");
b95c1883 537 zebra_ns_config_write(vty, (struct ns *)vrf->ns_ctxt);
5a0bdc78
PG
538 if (zvrf->zebra_rnh_ip_default_route)
539 vty_out(vty, " ip nht resolve-via-default\n");
540
541 if (zvrf->zebra_rnh_ipv6_default_route)
542 vty_out(vty, " ipv6 nht resolve-via-default\n");
22bd3e94 543 }
37728041 544
5a0bdc78 545
7cf16e19 546 zebra_routemap_config_write_protocol(vty, zvrf);
547
c319e19d
QY
548 if (zvrf_id(zvrf) != VRF_DEFAULT)
549 vty_endframe(vty, " exit-vrf\n!\n");
7cf16e19 550 else
551 vty_out(vty, "!\n");
d62a17ae 552 }
553 return 0;
f30c50b9
RW
554}
555
7c551956 556/* Zebra VRF initialization. */
d62a17ae 557void zebra_vrf_init(void)
7c551956 558{
996c9314 559 vrf_init(zebra_vrf_new, zebra_vrf_enable, zebra_vrf_disable,
ecbc5a37 560 zebra_vrf_delete, zebra_vrf_update);
7c551956 561
3bc34908 562 vrf_cmd_init(vrf_config_write, &zserv_privs);
7c551956 563}