]> git.proxmox.com Git - mirror_frr.git/blob - lib/vrf.c
Merge pull request #5895 from patrasar/2404618
[mirror_frr.git] / lib / vrf.c
1 /*
2 * VRF functions.
3 * Copyright (C) 2014 6WIND S.A.
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
11 *
12 * GNU Zebra 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 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
20 */
21
22 #include <zebra.h>
23
24 /* for basename */
25 #include <libgen.h>
26
27 #include "if.h"
28 #include "vrf.h"
29 #include "vrf_int.h"
30 #include "prefix.h"
31 #include "table.h"
32 #include "log.h"
33 #include "memory.h"
34 #include "command.h"
35 #include "ns.h"
36 #include "privs.h"
37 #include "nexthop_group.h"
38 #include "lib_errors.h"
39 #include "northbound.h"
40 #include "northbound_cli.h"
41
42 /* default VRF name value used when VRF backend is not NETNS */
43 #define VRF_DEFAULT_NAME_INTERNAL "default"
44
45 DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
46 DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
47
48 DEFINE_QOBJ_TYPE(vrf)
49
50 static __inline int vrf_id_compare(const struct vrf *, const struct vrf *);
51 static __inline int vrf_name_compare(const struct vrf *, const struct vrf *);
52
53 RB_GENERATE(vrf_id_head, vrf, id_entry, vrf_id_compare);
54 RB_GENERATE(vrf_name_head, vrf, name_entry, vrf_name_compare);
55
56 struct vrf_id_head vrfs_by_id = RB_INITIALIZER(&vrfs_by_id);
57 struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name);
58
59 static int vrf_backend;
60 static int vrf_backend_configured;
61 static struct zebra_privs_t *vrf_daemon_privs;
62 static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL;
63
64 /*
65 * Turn on/off debug code
66 * for vrf.
67 */
68 static int debug_vrf = 0;
69
70 /* Holding VRF hooks */
71 static struct vrf_master {
72 int (*vrf_new_hook)(struct vrf *);
73 int (*vrf_delete_hook)(struct vrf *);
74 int (*vrf_enable_hook)(struct vrf *);
75 int (*vrf_disable_hook)(struct vrf *);
76 int (*vrf_update_name_hook)(struct vrf *vrf);
77 } vrf_master = {
78 0,
79 };
80
81 static int vrf_is_enabled(struct vrf *vrf);
82
83 /* VRF list existance check by name. */
84 struct vrf *vrf_lookup_by_name(const char *name)
85 {
86 struct vrf vrf;
87 strlcpy(vrf.name, name, sizeof(vrf.name));
88 return (RB_FIND(vrf_name_head, &vrfs_by_name, &vrf));
89 }
90
91 static __inline int vrf_id_compare(const struct vrf *a, const struct vrf *b)
92 {
93 return (a->vrf_id - b->vrf_id);
94 }
95
96 static int vrf_name_compare(const struct vrf *a, const struct vrf *b)
97 {
98 return strcmp(a->name, b->name);
99 }
100
101 /* if ns_id is different and not VRF_UNKNOWN,
102 * then update vrf identifier, and enable VRF
103 */
104 static void vrf_update_vrf_id(ns_id_t ns_id, void *opaqueptr)
105 {
106 ns_id_t vrf_id = (vrf_id_t)ns_id;
107 vrf_id_t old_vrf_id;
108 struct vrf *vrf = (struct vrf *)opaqueptr;
109
110 if (!vrf)
111 return;
112 old_vrf_id = vrf->vrf_id;
113 if (vrf_id == vrf->vrf_id)
114 return;
115 if (vrf->vrf_id != VRF_UNKNOWN)
116 RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
117 vrf->vrf_id = vrf_id;
118 RB_INSERT(vrf_id_head, &vrfs_by_id, vrf);
119 if (old_vrf_id == VRF_UNKNOWN)
120 vrf_enable(vrf);
121 }
122
123 int vrf_switch_to_netns(vrf_id_t vrf_id)
124 {
125 char *name;
126 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
127
128 /* VRF is default VRF. silently ignore */
129 if (!vrf || vrf->vrf_id == VRF_DEFAULT)
130 return 1; /* 1 = default */
131 /* VRF has no NETNS backend. silently ignore */
132 if (vrf->data.l.netns_name[0] == '\0')
133 return 2; /* 2 = no netns */
134 name = ns_netns_pathname(NULL, vrf->data.l.netns_name);
135 if (debug_vrf)
136 zlog_debug("VRF_SWITCH: %s(%u)", name, vrf->vrf_id);
137 return ns_switch_to_netns(name);
138 }
139
140 int vrf_switchback_to_initial(void)
141 {
142 int ret = ns_switchback_to_initial();
143
144 if (ret == 0 && debug_vrf)
145 zlog_debug("VRF_SWITCHBACK");
146 return ret;
147 }
148
149 /* Get a VRF. If not found, create one.
150 * Arg:
151 * name - The name of the vrf. May be NULL if unknown.
152 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
153 * Description: Please note that this routine can be called with just the name
154 * and 0 vrf-id
155 */
156 struct vrf *vrf_get(vrf_id_t vrf_id, const char *name)
157 {
158 struct vrf *vrf = NULL;
159 int new = 0;
160
161 /* Nothing to see, move along here */
162 if (!name && vrf_id == VRF_UNKNOWN)
163 return NULL;
164
165 /* attempt to find already available VRF
166 */
167 if (name)
168 vrf = vrf_lookup_by_name(name);
169 if (vrf && vrf_id != VRF_UNKNOWN
170 && vrf->vrf_id != VRF_UNKNOWN
171 && vrf->vrf_id != vrf_id) {
172 zlog_debug("VRF_GET: avoid %s creation(%u), same name exists (%u)",
173 name, vrf_id, vrf->vrf_id);
174 return NULL;
175 }
176 /* Try to find VRF both by ID and name */
177 if (!vrf && vrf_id != VRF_UNKNOWN)
178 vrf = vrf_lookup_by_id(vrf_id);
179
180 if (vrf == NULL) {
181 vrf = XCALLOC(MTYPE_VRF, sizeof(struct vrf));
182 vrf->vrf_id = VRF_UNKNOWN;
183 QOBJ_REG(vrf, vrf);
184 new = 1;
185
186 if (debug_vrf)
187 zlog_debug("VRF(%u) %s is created.", vrf_id,
188 (name) ? name : "(NULL)");
189 }
190
191 /* Set identifier */
192 if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN) {
193 vrf->vrf_id = vrf_id;
194 RB_INSERT(vrf_id_head, &vrfs_by_id, vrf);
195 }
196
197 /* Set name */
198 if (name && vrf->name[0] != '\0' && strcmp(name, vrf->name)) {
199 /* update the vrf name */
200 RB_REMOVE(vrf_name_head, &vrfs_by_name, vrf);
201 strlcpy(vrf->data.l.netns_name,
202 name, NS_NAMSIZ);
203 strlcpy(vrf->name, name, sizeof(vrf->name));
204 RB_INSERT(vrf_name_head, &vrfs_by_name, vrf);
205 if (vrf->vrf_id == VRF_DEFAULT)
206 vrf_set_default_name(vrf->name, false);
207 } else if (name && vrf->name[0] == '\0') {
208 strlcpy(vrf->name, name, sizeof(vrf->name));
209 RB_INSERT(vrf_name_head, &vrfs_by_name, vrf);
210 }
211 if (new &&vrf_master.vrf_new_hook)
212 (*vrf_master.vrf_new_hook)(vrf);
213
214 return vrf;
215 }
216
217 /* Delete a VRF. This is called when the underlying VRF goes away, a
218 * pre-configured VRF is deleted or when shutting down (vrf_terminate()).
219 */
220 void vrf_delete(struct vrf *vrf)
221 {
222 if (debug_vrf)
223 zlog_debug("VRF %s(%u) is to be deleted.", vrf->name,
224 vrf->vrf_id);
225
226 if (vrf_is_enabled(vrf))
227 vrf_disable(vrf);
228
229 /* If the VRF is user configured, it'll stick around, just remove
230 * the ID mapping. Interfaces assigned to this VRF should've been
231 * removed already as part of the VRF going down.
232 */
233 if (vrf_is_user_cfged(vrf)) {
234 if (vrf->vrf_id != VRF_UNKNOWN) {
235 /* Delete any VRF interfaces - should be only
236 * the VRF itself, other interfaces should've
237 * been moved out of the VRF.
238 */
239 if_terminate(vrf);
240 RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
241 vrf->vrf_id = VRF_UNKNOWN;
242 }
243 return;
244 }
245
246 if (vrf_master.vrf_delete_hook)
247 (*vrf_master.vrf_delete_hook)(vrf);
248
249 QOBJ_UNREG(vrf);
250 if_terminate(vrf);
251
252 if (vrf->vrf_id != VRF_UNKNOWN)
253 RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
254 if (vrf->name[0] != '\0')
255 RB_REMOVE(vrf_name_head, &vrfs_by_name, vrf);
256
257 XFREE(MTYPE_VRF, vrf);
258 }
259
260 /* Look up a VRF by identifier. */
261 struct vrf *vrf_lookup_by_id(vrf_id_t vrf_id)
262 {
263 struct vrf vrf;
264 vrf.vrf_id = vrf_id;
265 return (RB_FIND(vrf_id_head, &vrfs_by_id, &vrf));
266 }
267
268 /*
269 * Enable a VRF - that is, let the VRF be ready to use.
270 * The VRF_ENABLE_HOOK callback will be called to inform
271 * that they can allocate resources in this VRF.
272 *
273 * RETURN: 1 - enabled successfully; otherwise, 0.
274 */
275 int vrf_enable(struct vrf *vrf)
276 {
277 if (vrf_is_enabled(vrf))
278 return 1;
279
280 if (debug_vrf)
281 zlog_debug("VRF %s(%u) is enabled.", vrf->name, vrf->vrf_id);
282
283 SET_FLAG(vrf->status, VRF_ACTIVE);
284
285 if (vrf_master.vrf_enable_hook)
286 (*vrf_master.vrf_enable_hook)(vrf);
287
288 /*
289 * If we have any nexthop group entries that
290 * are awaiting vrf initialization then
291 * let's let people know about it
292 */
293 nexthop_group_enable_vrf(vrf);
294
295 return 1;
296 }
297
298 /*
299 * Disable a VRF - that is, let the VRF be unusable.
300 * The VRF_DELETE_HOOK callback will be called to inform
301 * that they must release the resources in the VRF.
302 */
303 void vrf_disable(struct vrf *vrf)
304 {
305 if (!vrf_is_enabled(vrf))
306 return;
307
308 UNSET_FLAG(vrf->status, VRF_ACTIVE);
309
310 if (debug_vrf)
311 zlog_debug("VRF %s(%u) is to be disabled.", vrf->name,
312 vrf->vrf_id);
313
314 /* Till now, nothing to be done for the default VRF. */
315 // Pending: see why this statement.
316
317
318 /*
319 * When the vrf is disabled let's
320 * handle all nexthop-groups associated
321 * with this vrf
322 */
323 nexthop_group_disable_vrf(vrf);
324
325 if (vrf_master.vrf_disable_hook)
326 (*vrf_master.vrf_disable_hook)(vrf);
327 }
328
329 const char *vrf_id_to_name(vrf_id_t vrf_id)
330 {
331 struct vrf *vrf;
332
333 if (vrf_id == VRF_DEFAULT)
334 return VRF_DEFAULT_NAME;
335
336 vrf = vrf_lookup_by_id(vrf_id);
337 return VRF_LOGNAME(vrf);
338 }
339
340 vrf_id_t vrf_name_to_id(const char *name)
341 {
342 struct vrf *vrf;
343 vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid
344 // id/ routine not used.
345
346 if (!name)
347 return vrf_id;
348 vrf = vrf_lookup_by_name(name);
349 if (vrf)
350 vrf_id = vrf->vrf_id;
351
352 return vrf_id;
353 }
354
355 /* Get the data pointer of the specified VRF. If not found, create one. */
356 void *vrf_info_get(vrf_id_t vrf_id)
357 {
358 struct vrf *vrf = vrf_get(vrf_id, NULL);
359 return vrf->info;
360 }
361
362 /* Look up the data pointer of the specified VRF. */
363 void *vrf_info_lookup(vrf_id_t vrf_id)
364 {
365 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
366 return vrf ? vrf->info : NULL;
367 }
368
369 /*
370 * VRF hash for storing set or not.
371 */
372 struct vrf_bit_set {
373 vrf_id_t vrf_id;
374 bool set;
375 };
376
377 static unsigned int vrf_hash_bitmap_key(const void *data)
378 {
379 const struct vrf_bit_set *bit = data;
380
381 return bit->vrf_id;
382 }
383
384 static bool vrf_hash_bitmap_cmp(const void *a, const void *b)
385 {
386 const struct vrf_bit_set *bit1 = a;
387 const struct vrf_bit_set *bit2 = b;
388
389 return bit1->vrf_id == bit2->vrf_id;
390 }
391
392 static void *vrf_hash_bitmap_alloc(void *data)
393 {
394 struct vrf_bit_set *copy = data;
395 struct vrf_bit_set *bit;
396
397 bit = XMALLOC(MTYPE_VRF_BITMAP, sizeof(*bit));
398 bit->vrf_id = copy->vrf_id;
399
400 return bit;
401 }
402
403 static void vrf_hash_bitmap_free(void *data)
404 {
405 struct vrf_bit_set *bit = data;
406
407 XFREE(MTYPE_VRF_BITMAP, bit);
408 }
409
410 vrf_bitmap_t vrf_bitmap_init(void)
411 {
412 return hash_create_size(32, vrf_hash_bitmap_key, vrf_hash_bitmap_cmp,
413 "VRF BIT HASH");
414 }
415
416 void vrf_bitmap_free(vrf_bitmap_t bmap)
417 {
418 struct hash *vrf_hash = bmap;
419
420 if (vrf_hash == NULL)
421 return;
422
423 hash_clean(vrf_hash, vrf_hash_bitmap_free);
424 hash_free(vrf_hash);
425 }
426
427 void vrf_bitmap_set(vrf_bitmap_t bmap, vrf_id_t vrf_id)
428 {
429 struct vrf_bit_set lookup = { .vrf_id = vrf_id };
430 struct hash *vrf_hash = bmap;
431 struct vrf_bit_set *bit;
432
433 if (vrf_hash == NULL || vrf_id == VRF_UNKNOWN)
434 return;
435
436 bit = hash_get(vrf_hash, &lookup, vrf_hash_bitmap_alloc);
437 bit->set = true;
438 }
439
440 void vrf_bitmap_unset(vrf_bitmap_t bmap, vrf_id_t vrf_id)
441 {
442 struct vrf_bit_set lookup = { .vrf_id = vrf_id };
443 struct hash *vrf_hash = bmap;
444 struct vrf_bit_set *bit;
445
446 if (vrf_hash == NULL || vrf_id == VRF_UNKNOWN)
447 return;
448
449 bit = hash_get(vrf_hash, &lookup, vrf_hash_bitmap_alloc);
450 bit->set = false;
451 }
452
453 int vrf_bitmap_check(vrf_bitmap_t bmap, vrf_id_t vrf_id)
454 {
455 struct vrf_bit_set lookup = { .vrf_id = vrf_id };
456 struct hash *vrf_hash = bmap;
457 struct vrf_bit_set *bit;
458
459 if (vrf_hash == NULL || vrf_id == VRF_UNKNOWN)
460 return 0;
461
462 bit = hash_lookup(vrf_hash, &lookup);
463 if (bit)
464 return bit->set;
465
466 return 0;
467 }
468
469 static void vrf_autocomplete(vector comps, struct cmd_token *token)
470 {
471 struct vrf *vrf = NULL;
472
473 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
474 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
475 }
476
477 static const struct cmd_variable_handler vrf_var_handlers[] = {
478 {
479 .varname = "vrf",
480 .completions = vrf_autocomplete,
481 },
482 {
483 .varname = "vrf_name",
484 .completions = vrf_autocomplete,
485 },
486 {
487 .varname = "nexthop_vrf",
488 .completions = vrf_autocomplete,
489 },
490 {.completions = NULL},
491 };
492
493 /* Initialize VRF module. */
494 void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
495 int (*disable)(struct vrf *), int (*destroy)(struct vrf *),
496 int ((*update)(struct vrf *)))
497 {
498 struct vrf *default_vrf;
499
500 /* initialise NS, in case VRF backend if NETNS */
501 ns_init();
502 if (debug_vrf)
503 zlog_debug("%s: Initializing VRF subsystem", __func__);
504
505 vrf_master.vrf_new_hook = create;
506 vrf_master.vrf_enable_hook = enable;
507 vrf_master.vrf_disable_hook = disable;
508 vrf_master.vrf_delete_hook = destroy;
509 vrf_master.vrf_update_name_hook = update;
510
511 /* The default VRF always exists. */
512 default_vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
513 if (!default_vrf) {
514 flog_err(EC_LIB_VRF_START,
515 "vrf_init: failed to create the default VRF!");
516 exit(1);
517 }
518 if (vrf_is_backend_netns()) {
519 struct ns *ns;
520
521 strlcpy(default_vrf->data.l.netns_name,
522 VRF_DEFAULT_NAME, NS_NAMSIZ);
523 ns = ns_lookup(NS_DEFAULT);
524 ns->vrf_ctxt = default_vrf;
525 default_vrf->ns_ctxt = ns;
526 }
527
528 /* Enable the default VRF. */
529 if (!vrf_enable(default_vrf)) {
530 flog_err(EC_LIB_VRF_START,
531 "vrf_init: failed to enable the default VRF!");
532 exit(1);
533 }
534
535 cmd_variable_handler_register(vrf_var_handlers);
536 }
537
538 /* Terminate VRF module. */
539 void vrf_terminate(void)
540 {
541 struct vrf *vrf;
542
543 if (debug_vrf)
544 zlog_debug("%s: Shutting down vrf subsystem", __func__);
545
546 while (!RB_EMPTY(vrf_id_head, &vrfs_by_id)) {
547 vrf = RB_ROOT(vrf_id_head, &vrfs_by_id);
548
549 /* Clear configured flag and invoke delete. */
550 UNSET_FLAG(vrf->status, VRF_CONFIGURED);
551 vrf_delete(vrf);
552 }
553
554 while (!RB_EMPTY(vrf_name_head, &vrfs_by_name)) {
555 vrf = RB_ROOT(vrf_name_head, &vrfs_by_name);
556
557 /* Clear configured flag and invoke delete. */
558 UNSET_FLAG(vrf->status, VRF_CONFIGURED);
559 vrf_delete(vrf);
560 }
561 }
562
563 int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
564 const char *interfacename)
565 {
566 int ret, save_errno, ret2;
567
568 ret = vrf_switch_to_netns(vrf_id);
569 if (ret < 0)
570 flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
571 __func__, vrf_id, safe_strerror(errno));
572
573 ret = socket(domain, type, protocol);
574 save_errno = errno;
575 ret2 = vrf_switchback_to_initial();
576 if (ret2 < 0)
577 flog_err_sys(EC_LIB_SOCKET,
578 "%s: Can't switchback from VRF %u (%s)", __func__,
579 vrf_id, safe_strerror(errno));
580 errno = save_errno;
581 if (ret <= 0)
582 return ret;
583 ret2 = vrf_bind(vrf_id, ret, interfacename);
584 if (ret2 < 0) {
585 close(ret);
586 ret = ret2;
587 }
588 return ret;
589 }
590
591 int vrf_is_backend_netns(void)
592 {
593 return (vrf_backend == VRF_BACKEND_NETNS);
594 }
595
596 int vrf_get_backend(void)
597 {
598 if (!vrf_backend_configured)
599 return VRF_BACKEND_UNKNOWN;
600 return vrf_backend;
601 }
602
603 int vrf_configure_backend(enum vrf_backend_type backend)
604 {
605 /* Work around issue in old gcc */
606 switch (backend) {
607 case VRF_BACKEND_UNKNOWN:
608 case VRF_BACKEND_NETNS:
609 case VRF_BACKEND_VRF_LITE:
610 break;
611 default:
612 return -1;
613 }
614
615 vrf_backend = backend;
616 vrf_backend_configured = 1;
617
618 return 0;
619 }
620
621 int vrf_handler_create(struct vty *vty, const char *vrfname,
622 struct vrf **vrf)
623 {
624 struct vrf *vrfp;
625 char xpath_list[XPATH_MAXLEN];
626 int ret;
627
628 if (strlen(vrfname) > VRF_NAMSIZ) {
629 if (vty)
630 vty_out(vty,
631 "%% VRF name %s invalid: length exceeds %d bytes\n",
632 vrfname, VRF_NAMSIZ);
633 else
634 flog_warn(
635 EC_LIB_VRF_LENGTH,
636 "%% VRF name %s invalid: length exceeds %d bytes\n",
637 vrfname, VRF_NAMSIZ);
638 return CMD_WARNING_CONFIG_FAILED;
639 }
640
641 if (vty) {
642 snprintf(xpath_list, sizeof(xpath_list),
643 "/frr-vrf:lib/vrf[name='%s']", vrfname);
644
645 nb_cli_enqueue_change(vty, xpath_list, NB_OP_CREATE, NULL);
646 ret = nb_cli_apply_changes(vty, xpath_list);
647 if (ret == CMD_SUCCESS) {
648 VTY_PUSH_XPATH(VRF_NODE, xpath_list);
649 nb_cli_pending_commit_check(vty);
650 vrfp = vrf_lookup_by_name(vrfname);
651 if (vrfp)
652 VTY_PUSH_CONTEXT(VRF_NODE, vrfp);
653 }
654 } else {
655 vrfp = vrf_get(VRF_UNKNOWN, vrfname);
656
657 if (vrf)
658 *vrf = vrfp;
659 }
660 return CMD_SUCCESS;
661 }
662
663 int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
664 ns_id_t ns_id, ns_id_t internal_ns_id,
665 ns_id_t rel_def_ns_id)
666 {
667 struct ns *ns = NULL;
668
669 if (!vrf)
670 return CMD_WARNING_CONFIG_FAILED;
671 if (vrf->vrf_id != VRF_UNKNOWN && vrf->ns_ctxt == NULL) {
672 if (vty)
673 vty_out(vty,
674 "VRF %u is already configured with VRF %s\n",
675 vrf->vrf_id, vrf->name);
676 else
677 zlog_info("VRF %u is already configured with VRF %s",
678 vrf->vrf_id, vrf->name);
679 return CMD_WARNING_CONFIG_FAILED;
680 }
681 if (vrf->ns_ctxt != NULL) {
682 ns = (struct ns *)vrf->ns_ctxt;
683 if (!strcmp(ns->name, pathname)) {
684 if (vty)
685 vty_out(vty,
686 "VRF %u already configured with NETNS %s\n",
687 vrf->vrf_id, ns->name);
688 else
689 zlog_info(
690 "VRF %u already configured with NETNS %s",
691 vrf->vrf_id, ns->name);
692 return CMD_WARNING_CONFIG_FAILED;
693 }
694 }
695 ns = ns_lookup_name(pathname);
696 if (ns && ns->vrf_ctxt) {
697 struct vrf *vrf2 = (struct vrf *)ns->vrf_ctxt;
698
699 if (vrf2 == vrf)
700 return CMD_SUCCESS;
701 if (vty)
702 vty_out(vty,
703 "NS %s is already configured with VRF %u(%s)\n",
704 ns->name, vrf2->vrf_id, vrf2->name);
705 else
706 zlog_info("NS %s is already configured with VRF %u(%s)",
707 ns->name, vrf2->vrf_id, vrf2->name);
708 return CMD_WARNING_CONFIG_FAILED;
709 }
710 ns = ns_get_created(ns, pathname, ns_id);
711 ns->internal_ns_id = internal_ns_id;
712 ns->relative_default_ns = rel_def_ns_id;
713 ns->vrf_ctxt = (void *)vrf;
714 vrf->ns_ctxt = (void *)ns;
715 /* update VRF netns NAME */
716 strlcpy(vrf->data.l.netns_name, basename(pathname), NS_NAMSIZ);
717
718 if (!ns_enable(ns, vrf_update_vrf_id)) {
719 if (vty)
720 vty_out(vty, "Can not associate NS %u with NETNS %s\n",
721 ns->ns_id, ns->name);
722 else
723 zlog_info("Can not associate NS %u with NETNS %s",
724 ns->ns_id, ns->name);
725 return CMD_WARNING_CONFIG_FAILED;
726 }
727
728 return CMD_SUCCESS;
729 }
730
731 /* vrf CLI commands */
732 DEFUN_NOSH(vrf_exit,
733 vrf_exit_cmd,
734 "exit-vrf",
735 "Exit current mode and down to previous mode\n")
736 {
737 /* We have to set vrf context to default vrf */
738 VTY_PUSH_CONTEXT(VRF_NODE, vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME));
739 cmd_exit(vty);
740 return CMD_SUCCESS;
741 }
742
743 DEFUN_YANG_NOSH (vrf,
744 vrf_cmd,
745 "vrf NAME",
746 "Select a VRF to configure\n"
747 "VRF's name\n")
748 {
749 int idx_name = 1;
750 const char *vrfname = argv[idx_name]->arg;
751
752 return vrf_handler_create(vty, vrfname, NULL);
753 }
754
755 DEFUN_YANG (no_vrf,
756 no_vrf_cmd,
757 "no vrf NAME",
758 NO_STR
759 "Delete a pseudo VRF's configuration\n"
760 "VRF's name\n")
761 {
762 const char *vrfname = argv[2]->arg;
763 char xpath_list[XPATH_MAXLEN];
764
765 struct vrf *vrfp;
766
767 vrfp = vrf_lookup_by_name(vrfname);
768
769 if (vrfp == NULL)
770 return CMD_SUCCESS;
771
772 if (CHECK_FLAG(vrfp->status, VRF_ACTIVE)) {
773 vty_out(vty, "%% Only inactive VRFs can be deleted\n");
774 return CMD_WARNING_CONFIG_FAILED;
775 }
776
777 snprintf(xpath_list, sizeof(xpath_list), "/frr-vrf:lib/vrf[name='%s']",
778 vrfname);
779
780 nb_cli_enqueue_change(vty, xpath_list, NB_OP_DESTROY, NULL);
781 return nb_cli_apply_changes(vty, xpath_list);
782 }
783
784
785 static struct cmd_node vrf_node = {
786 .name = "vrf",
787 .node = VRF_NODE,
788 .parent_node = CONFIG_NODE,
789 .prompt = "%s(config-vrf)# ",
790 };
791
792 DEFUN_NOSH (vrf_netns,
793 vrf_netns_cmd,
794 "netns NAME",
795 "Attach VRF to a Namespace\n"
796 "The file name in " NS_RUN_DIR ", or a full pathname\n")
797 {
798 int idx_name = 1, ret;
799 char *pathname = ns_netns_pathname(vty, argv[idx_name]->arg);
800
801 VTY_DECLVAR_CONTEXT(vrf, vrf);
802
803 if (!pathname)
804 return CMD_WARNING_CONFIG_FAILED;
805
806 frr_with_privs(vrf_daemon_privs) {
807 ret = vrf_netns_handler_create(vty, vrf, pathname,
808 NS_UNKNOWN,
809 NS_UNKNOWN,
810 NS_UNKNOWN);
811 }
812 return ret;
813 }
814
815 DEFUN_NOSH (no_vrf_netns,
816 no_vrf_netns_cmd,
817 "no netns [NAME]",
818 NO_STR
819 "Detach VRF from a Namespace\n"
820 "The file name in " NS_RUN_DIR ", or a full pathname\n")
821 {
822 struct ns *ns = NULL;
823
824 VTY_DECLVAR_CONTEXT(vrf, vrf);
825
826 if (!vrf_is_backend_netns()) {
827 vty_out(vty, "VRF backend is not Netns. Aborting\n");
828 return CMD_WARNING_CONFIG_FAILED;
829 }
830 if (!vrf->ns_ctxt) {
831 vty_out(vty, "VRF %s(%u) is not configured with NetNS\n",
832 vrf->name, vrf->vrf_id);
833 return CMD_WARNING_CONFIG_FAILED;
834 }
835
836 ns = (struct ns *)vrf->ns_ctxt;
837
838 ns->vrf_ctxt = NULL;
839 vrf_disable(vrf);
840 /* vrf ID from VRF is necessary for Zebra
841 * so that propagate to other clients is done
842 */
843 ns_delete(ns);
844 vrf->ns_ctxt = NULL;
845 return CMD_SUCCESS;
846 }
847
848 /*
849 * Debug CLI for vrf's
850 */
851 DEFUN (vrf_debug,
852 vrf_debug_cmd,
853 "debug vrf",
854 DEBUG_STR
855 "VRF Debugging\n")
856 {
857 debug_vrf = 1;
858
859 return CMD_SUCCESS;
860 }
861
862 DEFUN (no_vrf_debug,
863 no_vrf_debug_cmd,
864 "no debug vrf",
865 NO_STR
866 DEBUG_STR
867 "VRF Debugging\n")
868 {
869 debug_vrf = 0;
870
871 return CMD_SUCCESS;
872 }
873
874 static int vrf_write_host(struct vty *vty)
875 {
876 if (debug_vrf)
877 vty_out(vty, "debug vrf\n");
878
879 return 1;
880 }
881
882 static int vrf_write_host(struct vty *vty);
883 static struct cmd_node vrf_debug_node = {
884 .name = "vrf debug",
885 .node = VRF_DEBUG_NODE,
886 .prompt = "",
887 .config_write = vrf_write_host,
888 };
889
890 void vrf_install_commands(void)
891 {
892 install_node(&vrf_debug_node);
893
894 install_element(CONFIG_NODE, &vrf_debug_cmd);
895 install_element(ENABLE_NODE, &vrf_debug_cmd);
896 install_element(CONFIG_NODE, &no_vrf_debug_cmd);
897 install_element(ENABLE_NODE, &no_vrf_debug_cmd);
898 }
899
900 void vrf_cmd_init(int (*writefunc)(struct vty *vty),
901 struct zebra_privs_t *daemon_privs)
902 {
903 install_element(CONFIG_NODE, &vrf_cmd);
904 install_element(CONFIG_NODE, &no_vrf_cmd);
905 vrf_node.config_write = writefunc;
906 install_node(&vrf_node);
907 install_default(VRF_NODE);
908 install_element(VRF_NODE, &vrf_exit_cmd);
909 if (vrf_is_backend_netns() && ns_have_netns()) {
910 /* Install NS commands. */
911 vrf_daemon_privs = daemon_privs;
912 install_element(VRF_NODE, &vrf_netns_cmd);
913 install_element(VRF_NODE, &no_vrf_netns_cmd);
914 }
915 }
916
917 void vrf_set_default_name(const char *default_name, bool force)
918 {
919 struct vrf *def_vrf;
920 static bool def_vrf_forced;
921
922 def_vrf = vrf_lookup_by_id(VRF_DEFAULT);
923 assert(default_name);
924 if (def_vrf && !force && def_vrf_forced) {
925 zlog_debug("VRF: %s, avoid changing name to %s, previously forced (%u)",
926 def_vrf->name, default_name,
927 def_vrf->vrf_id);
928 return;
929 }
930 if (strmatch(vrf_default_name, default_name))
931 return;
932 snprintf(vrf_default_name, VRF_NAMSIZ, "%s", default_name);
933 if (def_vrf) {
934 if (force)
935 def_vrf_forced = true;
936 RB_REMOVE(vrf_name_head, &vrfs_by_name, def_vrf);
937 strlcpy(def_vrf->data.l.netns_name,
938 vrf_default_name, NS_NAMSIZ);
939 strlcpy(def_vrf->name, vrf_default_name, sizeof(def_vrf->name));
940 RB_INSERT(vrf_name_head, &vrfs_by_name, def_vrf);
941 if (vrf_master.vrf_update_name_hook)
942 (*vrf_master.vrf_update_name_hook)(def_vrf);
943 }
944 }
945
946 const char *vrf_get_default_name(void)
947 {
948 return vrf_default_name;
949 }
950
951 int vrf_bind(vrf_id_t vrf_id, int fd, const char *name)
952 {
953 int ret = 0;
954 struct interface *ifp;
955
956 if (fd < 0 || name == NULL)
957 return fd;
958 /* the device should exist
959 * otherwise we should return
960 * case ifname = vrf in netns mode => return
961 */
962 ifp = if_lookup_by_name(name, vrf_id);
963 if (!ifp)
964 return fd;
965 #ifdef SO_BINDTODEVICE
966 ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1);
967 if (ret < 0)
968 zlog_debug("bind to interface %s failed, errno=%d", name,
969 errno);
970 #endif /* SO_BINDTODEVICE */
971 return ret;
972 }
973 int vrf_getaddrinfo(const char *node, const char *service,
974 const struct addrinfo *hints, struct addrinfo **res,
975 vrf_id_t vrf_id)
976 {
977 int ret, ret2, save_errno;
978
979 ret = vrf_switch_to_netns(vrf_id);
980 if (ret < 0)
981 flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
982 __func__, vrf_id, safe_strerror(errno));
983 ret = getaddrinfo(node, service, hints, res);
984 save_errno = errno;
985 ret2 = vrf_switchback_to_initial();
986 if (ret2 < 0)
987 flog_err_sys(EC_LIB_SOCKET,
988 "%s: Can't switchback from VRF %u (%s)", __func__,
989 vrf_id, safe_strerror(errno));
990 errno = save_errno;
991 return ret;
992 }
993
994 int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
995 {
996 int ret, saved_errno, rc;
997
998 ret = vrf_switch_to_netns(vrf_id);
999 if (ret < 0) {
1000 flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
1001 __func__, vrf_id, safe_strerror(errno));
1002 return 0;
1003 }
1004 rc = ioctl(d, request, params);
1005 saved_errno = errno;
1006 ret = vrf_switchback_to_initial();
1007 if (ret < 0)
1008 flog_err_sys(EC_LIB_SOCKET,
1009 "%s: Can't switchback from VRF %u (%s)", __func__,
1010 vrf_id, safe_strerror(errno));
1011 errno = saved_errno;
1012 return rc;
1013 }
1014
1015 int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
1016 const char *interfacename)
1017 {
1018 int ret, save_errno, ret2;
1019
1020 ret = vrf_switch_to_netns(vrf_id);
1021 if (ret < 0)
1022 flog_err_sys(EC_LIB_SOCKET, "%s: Can't switch to VRF %u (%s)",
1023 __func__, vrf_id, safe_strerror(errno));
1024 ret = sockunion_socket(su);
1025 save_errno = errno;
1026 ret2 = vrf_switchback_to_initial();
1027 if (ret2 < 0)
1028 flog_err_sys(EC_LIB_SOCKET,
1029 "%s: Can't switchback from VRF %u (%s)", __func__,
1030 vrf_id, safe_strerror(errno));
1031 errno = save_errno;
1032
1033 if (ret <= 0)
1034 return ret;
1035 ret2 = vrf_bind(vrf_id, ret, interfacename);
1036 if (ret2 < 0) {
1037 close(ret);
1038 ret = ret2;
1039 }
1040 return ret;
1041 }
1042
1043 vrf_id_t vrf_generate_id(void)
1044 {
1045 static int vrf_id_local;
1046
1047 return ++vrf_id_local;
1048 }
1049
1050 /* ------- Northbound callbacks ------- */
1051
1052 /*
1053 * XPath: /frr-vrf:lib/vrf
1054 */
1055 static int lib_vrf_create(struct nb_cb_create_args *args)
1056 {
1057 const char *vrfname;
1058 struct vrf *vrfp;
1059
1060 vrfname = yang_dnode_get_string(args->dnode, "./name");
1061
1062 if (args->event != NB_EV_APPLY)
1063 return NB_OK;
1064
1065 vrfp = vrf_get(VRF_UNKNOWN, vrfname);
1066
1067 nb_running_set_entry(args->dnode, vrfp);
1068
1069 return NB_OK;
1070 }
1071
1072 static int lib_vrf_destroy(struct nb_cb_destroy_args *args)
1073 {
1074 struct vrf *vrfp;
1075
1076 switch (args->event) {
1077 case NB_EV_VALIDATE:
1078 vrfp = nb_running_get_entry(args->dnode, NULL, true);
1079 if (CHECK_FLAG(vrfp->status, VRF_ACTIVE)) {
1080 snprintf(args->errmsg, args->errmsg_len,
1081 "Only inactive VRFs can be deleted");
1082 return NB_ERR_VALIDATION;
1083 }
1084 break;
1085 case NB_EV_PREPARE:
1086 case NB_EV_ABORT:
1087 break;
1088 case NB_EV_APPLY:
1089 vrfp = nb_running_unset_entry(args->dnode);
1090
1091 /* Clear configured flag and invoke delete. */
1092 UNSET_FLAG(vrfp->status, VRF_CONFIGURED);
1093 vrf_delete(vrfp);
1094 break;
1095 }
1096
1097 return NB_OK;
1098 }
1099
1100 static const void *lib_vrf_get_next(struct nb_cb_get_next_args *args)
1101 {
1102 struct vrf *vrfp = (struct vrf *)args->list_entry;
1103
1104 if (args->list_entry == NULL) {
1105 vrfp = RB_MIN(vrf_name_head, &vrfs_by_name);
1106 } else {
1107 vrfp = RB_NEXT(vrf_name_head, vrfp);
1108 }
1109
1110 return vrfp;
1111 }
1112
1113 static int lib_vrf_get_keys(struct nb_cb_get_keys_args *args)
1114 {
1115 struct vrf *vrfp = (struct vrf *)args->list_entry;
1116
1117 args->keys->num = 1;
1118 strlcpy(args->keys->key[0], vrfp->name, sizeof(args->keys->key[0]));
1119
1120 return NB_OK;
1121 }
1122
1123 static const void *lib_vrf_lookup_entry(struct nb_cb_lookup_entry_args *args)
1124 {
1125 const char *vrfname = args->keys->key[0];
1126
1127 struct vrf *vrf = vrf_lookup_by_name(vrfname);
1128
1129 return vrf;
1130 }
1131
1132 /*
1133 * XPath: /frr-vrf:lib/vrf/id
1134 */
1135 static struct yang_data *
1136 lib_vrf_state_id_get_elem(struct nb_cb_get_elem_args *args)
1137 {
1138 struct vrf *vrfp = (struct vrf *)args->list_entry;
1139
1140 return yang_data_new_uint32(args->xpath, vrfp->vrf_id);
1141 }
1142
1143 /*
1144 * XPath: /frr-vrf:lib/vrf/active
1145 */
1146 static struct yang_data *
1147 lib_vrf_state_active_get_elem(struct nb_cb_get_elem_args *args)
1148 {
1149 struct vrf *vrfp = (struct vrf *)args->list_entry;
1150
1151 if (vrfp->status == VRF_ACTIVE)
1152 return yang_data_new_bool(
1153 args->xpath, vrfp->status == VRF_ACTIVE ? true : false);
1154
1155 return NULL;
1156 }
1157
1158 /* clang-format off */
1159 const struct frr_yang_module_info frr_vrf_info = {
1160 .name = "frr-vrf",
1161 .nodes = {
1162 {
1163 .xpath = "/frr-vrf:lib/vrf",
1164 .cbs = {
1165 .create = lib_vrf_create,
1166 .destroy = lib_vrf_destroy,
1167 .get_next = lib_vrf_get_next,
1168 .get_keys = lib_vrf_get_keys,
1169 .lookup_entry = lib_vrf_lookup_entry,
1170 }
1171 },
1172 {
1173 .xpath = "/frr-vrf:lib/vrf/state/id",
1174 .cbs = {
1175 .get_elem = lib_vrf_state_id_get_elem,
1176 }
1177 },
1178 {
1179 .xpath = "/frr-vrf:lib/vrf/state/active",
1180 .cbs = {
1181 .get_elem = lib_vrf_state_active_get_elem,
1182 }
1183 },
1184 {
1185 .xpath = NULL,
1186 },
1187 }
1188 };
1189