]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vrf.c
Merge pull request #7261 from Niral-Networks/niral_dev_vrf_ospf6
[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 180#if defined(HAVE_RTADV)
aab5893a 181 rtadv_vrf_terminate(zvrf);
df9c8c57
PG
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 317
cdc09a4b
MS
318 list_delete_all_node(zvrf->rid6_all_sorted_list);
319 list_delete_all_node(zvrf->rid6_lo_sorted_list);
320
d8612e65 321 otable_fini(&zvrf->other_tables);
d62a17ae 322 XFREE(MTYPE_ZEBRA_VRF, zvrf);
323 vrf->info = NULL;
5a8dfcd8 324
d62a17ae 325 return 0;
7c551956
DS
326}
327
ecbc5a37
PG
328static int zebra_vrf_update(struct vrf *vrf)
329{
330 struct zebra_vrf *zvrf = vrf->info;
331
332 assert(zvrf);
333 if (IS_ZEBRA_DEBUG_EVENT)
334 zlog_debug("VRF %s id %u, name updated", vrf->name,
335 zvrf_id(zvrf));
336 zebra_vrf_add_update(zvrf);
337 return 0;
338}
339
340
22bd3e94 341/* Return if this VRF has any FRR configuration or not.
342 * IMPORTANT: This function needs to be updated when additional configuration
343 * is added for a VRF.
344 */
345int zebra_vrf_has_config(struct zebra_vrf *zvrf)
346{
22bd3e94 347 /* EVPN L3-VNI? */
348 if (zvrf->l3vni)
349 return 1;
350
351 return 0;
352}
353
7c551956 354/* Lookup the routing table in a VRF based on both VRF-Id and table-id.
e9748a89
PG
355 * NOTE: Table-id is relevant on two modes:
356 * - case VRF backend is default : on default VRF only
357 * - case VRF backend is netns : on all VRFs
7c551956 358 */
c7c0b007
SW
359struct route_table *zebra_vrf_lookup_table_with_table_id(afi_t afi, safi_t safi,
360 vrf_id_t vrf_id,
361 uint32_t table_id)
7c551956 362{
8ab39b7f 363 struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
d8612e65 364 struct other_route_table ort, *otable;
8ab39b7f
DS
365
366 if (!zvrf)
367 return NULL;
d62a17ae 368
369 if (afi >= AFI_MAX || safi >= SAFI_MAX)
370 return NULL;
371
8ab39b7f
DS
372 if (table_id == zvrf->table_id)
373 return zebra_vrf_table(afi, safi, vrf_id);
d62a17ae 374
d8612e65
DS
375 ort.afi = afi;
376 ort.safi = safi;
377 ort.table_id = table_id;
378 otable = otable_find(&zvrf->other_tables, &ort);
c7c0b007 379
d8612e65
DS
380 if (otable)
381 return otable->table;
382
c7c0b007
SW
383 return NULL;
384}
385
386struct route_table *zebra_vrf_get_table_with_table_id(afi_t afi, safi_t safi,
387 vrf_id_t vrf_id,
388 uint32_t table_id)
389{
390 struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
391 struct other_route_table *otable;
392 struct route_table *table;
393
394 table = zebra_vrf_lookup_table_with_table_id(afi, safi, vrf_id,
395 table_id);
396
397 if (table)
398 goto done;
399
400 /* Create it as an `other` table */
d8612e65
DS
401 table = zebra_router_get_table(zvrf, table_id, afi, safi);
402
403 otable = XCALLOC(MTYPE_OTHER_TABLE, sizeof(*otable));
404 otable->afi = afi;
405 otable->safi = safi;
406 otable->table_id = table_id;
407 otable->table = table;
408 otable_add(&zvrf->other_tables, otable);
d62a17ae 409
c7c0b007 410done:
d62a17ae 411 return table;
7c551956
DS
412}
413
5335613b
DS
414void zebra_rtable_node_cleanup(struct route_table *table,
415 struct route_node *node)
5a8dfcd8 416{
d62a17ae 417 struct route_entry *re, *next;
5a8dfcd8 418
a2addae8 419 RNODE_FOREACH_RE_SAFE (node, re, next) {
407c87a6
DS
420 rib_unlink(node, re);
421 }
5a8dfcd8 422
699dae23
DS
423 if (node->info) {
424 rib_dest_t *dest = node->info;
425
aa57abfb 426 rnh_list_fini(&dest->nht);
699dae23
DS
427 XFREE(MTYPE_RIB_DEST, node->info);
428 }
5a8dfcd8
RW
429}
430
d62a17ae 431static void zebra_rnhtable_node_cleanup(struct route_table *table,
432 struct route_node *node)
5a8dfcd8 433{
d62a17ae 434 if (node->info)
435 zebra_free_rnh(node->info);
5a8dfcd8
RW
436}
437
7c551956
DS
438/*
439 * Create a routing table for the specific AFI/SAFI in the given VRF.
440 */
d62a17ae 441static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
442 safi_t safi)
7c551956 443{
c86ba6c2
DS
444 struct route_node *rn;
445 struct prefix p;
446
d62a17ae 447 assert(!zvrf->table[afi][safi]);
448
ea66cec4
DS
449 zvrf->table[afi][safi] =
450 zebra_router_get_table(zvrf, zvrf->table_id, afi, safi);
c86ba6c2
DS
451
452 memset(&p, 0, sizeof(p));
453 p.family = afi2family(afi);
454
455 rn = srcdest_rnode_get(zvrf->table[afi][safi], &p, NULL);
456 zebra_rib_create_dest(rn);
7c551956
DS
457}
458
459/* Allocate new zebra VRF. */
d62a17ae 460struct zebra_vrf *zebra_vrf_alloc(void)
7c551956 461{
d62a17ae 462 struct zebra_vrf *zvrf;
d62a17ae 463
464 zvrf = XCALLOC(MTYPE_ZEBRA_VRF, sizeof(struct zebra_vrf));
465
d62a17ae 466 zebra_vxlan_init_tables(zvrf);
467 zebra_mpls_init_tables(zvrf);
6833ae01 468 zebra_pw_init(zvrf);
e9748a89
PG
469 zvrf->table_id = RT_TABLE_MAIN;
470 /* by default table ID is default one */
d62a17ae 471 return zvrf;
7c551956
DS
472}
473
474/* Lookup VRF by identifier. */
d62a17ae 475struct zebra_vrf *zebra_vrf_lookup_by_id(vrf_id_t vrf_id)
7c551956 476{
d62a17ae 477 return vrf_info_lookup(vrf_id);
7c551956
DS
478}
479
51bdc5f8 480/* Lookup VRF by name. */
d62a17ae 481struct zebra_vrf *zebra_vrf_lookup_by_name(const char *name)
871d39b3 482{
d62a17ae 483 struct vrf *vrf;
871d39b3 484
d62a17ae 485 if (!name)
486 name = VRF_DEFAULT_NAME;
a3d21ef3 487
d62a17ae 488 vrf = vrf_lookup_by_name(name);
489 if (vrf)
490 return ((struct zebra_vrf *)vrf->info);
51bdc5f8 491
d62a17ae 492 return NULL;
871d39b3
DS
493}
494
7c551956 495/* Lookup the routing table in an enabled VRF. */
d62a17ae 496struct route_table *zebra_vrf_table(afi_t afi, safi_t safi, vrf_id_t vrf_id)
7c551956 497{
d62a17ae 498 struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
7c551956 499
d62a17ae 500 if (!zvrf)
501 return NULL;
7c551956 502
d62a17ae 503 if (afi >= AFI_MAX || safi >= SAFI_MAX)
504 return NULL;
7c551956 505
d62a17ae 506 return zvrf->table[afi][safi];
7c551956
DS
507}
508
d62a17ae 509static int vrf_config_write(struct vty *vty)
f30c50b9 510{
d62a17ae 511 struct vrf *vrf;
512 struct zebra_vrf *zvrf;
513
a2addae8 514 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 515 zvrf = vrf->info;
1e9f448f
DS
516
517 if (!zvrf)
518 continue;
519
a5654735
MK
520 if (zvrf_id(zvrf) == VRF_DEFAULT) {
521 if (zvrf->l3vni)
8d0f01f1
CS
522 vty_out(vty, "vni %u%s\n", zvrf->l3vni,
523 is_l3vni_for_prefix_routes_only(
524 zvrf->l3vni)
525 ? " prefix-routes-only"
526 : "");
5a0bdc78
PG
527 if (zvrf->zebra_rnh_ip_default_route)
528 vty_out(vty, "ip nht resolve-via-default\n");
529
530 if (zvrf->zebra_rnh_ipv6_default_route)
531 vty_out(vty, "ipv6 nht resolve-via-default\n");
c319e19d
QY
532 } else {
533 vty_frame(vty, "vrf %s\n", zvrf_name(zvrf));
22bd3e94 534 if (zvrf->l3vni)
996c9314
LB
535 vty_out(vty, " vni %u%s\n", zvrf->l3vni,
536 is_l3vni_for_prefix_routes_only(
537 zvrf->l3vni)
538 ? " prefix-routes-only"
539 : "");
b95c1883 540 zebra_ns_config_write(vty, (struct ns *)vrf->ns_ctxt);
5a0bdc78
PG
541 if (zvrf->zebra_rnh_ip_default_route)
542 vty_out(vty, " ip nht resolve-via-default\n");
543
544 if (zvrf->zebra_rnh_ipv6_default_route)
545 vty_out(vty, " ipv6 nht resolve-via-default\n");
22bd3e94 546 }
37728041 547
5a0bdc78 548
7cf16e19 549 zebra_routemap_config_write_protocol(vty, zvrf);
03fba42e 550 router_id_write(vty, zvrf);
7cf16e19 551
c319e19d
QY
552 if (zvrf_id(zvrf) != VRF_DEFAULT)
553 vty_endframe(vty, " exit-vrf\n!\n");
7cf16e19 554 else
555 vty_out(vty, "!\n");
d62a17ae 556 }
557 return 0;
f30c50b9
RW
558}
559
7c551956 560/* Zebra VRF initialization. */
d62a17ae 561void zebra_vrf_init(void)
7c551956 562{
996c9314 563 vrf_init(zebra_vrf_new, zebra_vrf_enable, zebra_vrf_disable,
ecbc5a37 564 zebra_vrf_delete, zebra_vrf_update);
7c551956 565
3bc34908 566 vrf_cmd_init(vrf_config_write, &zserv_privs);
7c551956 567}