]> git.proxmox.com Git - mirror_frr.git/blame_incremental - lib/vrf.c
*: use C99 standard fixed-width integer types
[mirror_frr.git] / lib / vrf.c
... / ...
CommitLineData
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
38/* default VRF ID value used when VRF backend is not NETNS */
39#define VRF_DEFAULT_INTERNAL 0
40
41DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
42DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
43
44DEFINE_QOBJ_TYPE(vrf)
45
46static __inline int vrf_id_compare(const struct vrf *, const struct vrf *);
47static __inline int vrf_name_compare(const struct vrf *, const struct vrf *);
48
49RB_GENERATE(vrf_id_head, vrf, id_entry, vrf_id_compare);
50RB_GENERATE(vrf_name_head, vrf, name_entry, vrf_name_compare);
51
52struct vrf_id_head vrfs_by_id = RB_INITIALIZER(&vrfs_by_id);
53struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name);
54
55static int vrf_backend;
56static struct zebra_privs_t *vrf_daemon_privs;
57
58/*
59 * Turn on/off debug code
60 * for vrf.
61 */
62int debug_vrf = 0;
63
64/* Holding VRF hooks */
65struct vrf_master {
66 int (*vrf_new_hook)(struct vrf *);
67 int (*vrf_delete_hook)(struct vrf *);
68 int (*vrf_enable_hook)(struct vrf *);
69 int (*vrf_disable_hook)(struct vrf *);
70} vrf_master = {
71 0,
72};
73
74static int vrf_is_enabled(struct vrf *vrf);
75
76/* VRF list existance check by name. */
77struct vrf *vrf_lookup_by_name(const char *name)
78{
79 struct vrf vrf;
80 strlcpy(vrf.name, name, sizeof(vrf.name));
81 return (RB_FIND(vrf_name_head, &vrfs_by_name, &vrf));
82}
83
84static __inline int vrf_id_compare(const struct vrf *a, const struct vrf *b)
85{
86 return (a->vrf_id - b->vrf_id);
87}
88
89static int vrf_name_compare(const struct vrf *a, const struct vrf *b)
90{
91 return strcmp(a->name, b->name);
92}
93
94/* if ns_id is different and not VRF_UNKNOWN,
95 * then update vrf identifier, and enable VRF
96 */
97static void vrf_update_vrf_id(ns_id_t ns_id, void *opaqueptr)
98{
99 ns_id_t vrf_id = (vrf_id_t)ns_id;
100 vrf_id_t old_vrf_id;
101 struct vrf *vrf = (struct vrf *)opaqueptr;
102
103 if (!vrf)
104 return;
105 old_vrf_id = vrf->vrf_id;
106 if (vrf_id == vrf->vrf_id)
107 return;
108 if (vrf->vrf_id != VRF_UNKNOWN)
109 RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
110 vrf->vrf_id = vrf_id;
111 RB_INSERT(vrf_id_head, &vrfs_by_id, vrf);
112 if (old_vrf_id == VRF_UNKNOWN)
113 vrf_enable((struct vrf *)vrf);
114}
115
116int vrf_switch_to_netns(vrf_id_t vrf_id)
117{
118 char *name;
119 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
120
121 /* VRF is default VRF. silently ignore */
122 if (!vrf || vrf->vrf_id == VRF_DEFAULT)
123 return 0;
124 /* VRF has no NETNS backend. silently ignore */
125 if (vrf->data.l.netns_name[0] == '\0')
126 return 0;
127 name = ns_netns_pathname(NULL, vrf->data.l.netns_name);
128 if (debug_vrf)
129 zlog_debug("VRF_SWITCH: %s(%u)", name, vrf->vrf_id);
130 return ns_switch_to_netns(name);
131}
132
133int vrf_switchback_to_initial(void)
134{
135 int ret = ns_switchback_to_initial();
136
137 if (ret == 0 && debug_vrf)
138 zlog_debug("VRF_SWITCHBACK");
139 return ret;
140}
141
142/* Get a VRF. If not found, create one.
143 * Arg:
144 * name - The name of the vrf. May be NULL if unknown.
145 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
146 * Description: Please note that this routine can be called with just the name
147 * and 0 vrf-id
148 */
149struct vrf *vrf_get(vrf_id_t vrf_id, const char *name)
150{
151 struct vrf *vrf = NULL;
152 int new = 0;
153
154 if (debug_vrf)
155 zlog_debug("VRF_GET: %s(%u)", name == NULL ? "(NULL)" : name,
156 vrf_id);
157
158 /* Nothing to see, move along here */
159 if (!name && vrf_id == VRF_UNKNOWN)
160 return NULL;
161
162 /* Try to find VRF both by ID and name */
163 if (vrf_id != VRF_UNKNOWN)
164 vrf = vrf_lookup_by_id(vrf_id);
165 if (!vrf && name)
166 vrf = vrf_lookup_by_name(name);
167
168 if (vrf == NULL) {
169 vrf = XCALLOC(MTYPE_VRF, sizeof(struct vrf));
170 vrf->vrf_id = VRF_UNKNOWN;
171 QOBJ_REG(vrf, vrf);
172 new = 1;
173
174 if (debug_vrf)
175 zlog_debug("VRF(%u) %s is created.", vrf_id,
176 (name) ? name : "(NULL)");
177 }
178
179 /* Set identifier */
180 if (vrf_id != VRF_UNKNOWN && vrf->vrf_id == VRF_UNKNOWN) {
181 vrf->vrf_id = vrf_id;
182 RB_INSERT(vrf_id_head, &vrfs_by_id, vrf);
183 }
184
185 /* Set name */
186 if (name && vrf->name[0] != '\0' && strcmp(name, vrf->name)) {
187 RB_REMOVE(vrf_name_head, &vrfs_by_name, vrf);
188 strlcpy(vrf->name, name, sizeof(vrf->name));
189 RB_INSERT(vrf_name_head, &vrfs_by_name, vrf);
190 } else if (name && vrf->name[0] == '\0') {
191 strlcpy(vrf->name, name, sizeof(vrf->name));
192 RB_INSERT(vrf_name_head, &vrfs_by_name, vrf);
193 }
194 if (new &&vrf_master.vrf_new_hook)
195 (*vrf_master.vrf_new_hook)(vrf);
196
197 return vrf;
198}
199
200/* Delete a VRF. This is called when the underlying VRF goes away, a
201 * pre-configured VRF is deleted or when shutting down (vrf_terminate()).
202 */
203void vrf_delete(struct vrf *vrf)
204{
205 if (debug_vrf)
206 zlog_debug("VRF %u is to be deleted.", vrf->vrf_id);
207
208 if (vrf_is_enabled(vrf))
209 vrf_disable(vrf);
210
211 /* If the VRF is user configured, it'll stick around, just remove
212 * the ID mapping. Interfaces assigned to this VRF should've been
213 * removed already as part of the VRF going down.
214 */
215 if (vrf_is_user_cfged(vrf)) {
216 if (vrf->vrf_id != VRF_UNKNOWN) {
217 /* Delete any VRF interfaces - should be only
218 * the VRF itself, other interfaces should've
219 * been moved out of the VRF.
220 */
221 if_terminate(vrf);
222 RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
223 vrf->vrf_id = VRF_UNKNOWN;
224 }
225 return;
226 }
227
228 if (vrf_master.vrf_delete_hook)
229 (*vrf_master.vrf_delete_hook)(vrf);
230
231 QOBJ_UNREG(vrf);
232 if_terminate(vrf);
233
234 if (vrf->vrf_id != VRF_UNKNOWN)
235 RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
236 if (vrf->name[0] != '\0')
237 RB_REMOVE(vrf_name_head, &vrfs_by_name, vrf);
238
239 XFREE(MTYPE_VRF, vrf);
240}
241
242/* Look up a VRF by identifier. */
243struct vrf *vrf_lookup_by_id(vrf_id_t vrf_id)
244{
245 struct vrf vrf;
246 vrf.vrf_id = vrf_id;
247 return (RB_FIND(vrf_id_head, &vrfs_by_id, &vrf));
248}
249
250/*
251 * Enable a VRF - that is, let the VRF be ready to use.
252 * The VRF_ENABLE_HOOK callback will be called to inform
253 * that they can allocate resources in this VRF.
254 *
255 * RETURN: 1 - enabled successfully; otherwise, 0.
256 */
257int vrf_enable(struct vrf *vrf)
258{
259 if (vrf_is_enabled(vrf))
260 return 1;
261
262 if (debug_vrf)
263 zlog_debug("VRF %u is enabled.", vrf->vrf_id);
264
265 SET_FLAG(vrf->status, VRF_ACTIVE);
266
267 if (vrf_master.vrf_enable_hook)
268 (*vrf_master.vrf_enable_hook)(vrf);
269
270 return 1;
271}
272
273/*
274 * Disable a VRF - that is, let the VRF be unusable.
275 * The VRF_DELETE_HOOK callback will be called to inform
276 * that they must release the resources in the VRF.
277 */
278void vrf_disable(struct vrf *vrf)
279{
280 if (!vrf_is_enabled(vrf))
281 return;
282
283 UNSET_FLAG(vrf->status, VRF_ACTIVE);
284
285 if (debug_vrf)
286 zlog_debug("VRF %u is to be disabled.", vrf->vrf_id);
287
288 /* Till now, nothing to be done for the default VRF. */
289 // Pending: see why this statement.
290
291 if (vrf_master.vrf_disable_hook)
292 (*vrf_master.vrf_disable_hook)(vrf);
293}
294
295const char *vrf_id_to_name(vrf_id_t vrf_id)
296{
297 struct vrf *vrf;
298
299 vrf = vrf_lookup_by_id(vrf_id);
300 if (vrf)
301 return vrf->name;
302
303 return "n/a";
304}
305
306vrf_id_t vrf_name_to_id(const char *name)
307{
308 struct vrf *vrf;
309 vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid
310 // id/ routine not used.
311
312 vrf = vrf_lookup_by_name(name);
313 if (vrf)
314 vrf_id = vrf->vrf_id;
315
316 return vrf_id;
317}
318
319/* Get the data pointer of the specified VRF. If not found, create one. */
320void *vrf_info_get(vrf_id_t vrf_id)
321{
322 struct vrf *vrf = vrf_get(vrf_id, NULL);
323 return vrf->info;
324}
325
326/* Look up the data pointer of the specified VRF. */
327void *vrf_info_lookup(vrf_id_t vrf_id)
328{
329 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
330 return vrf ? vrf->info : NULL;
331}
332
333/*
334 * VRF bit-map
335 */
336
337#define VRF_BITMAP_NUM_OF_GROUPS 1024
338#define VRF_BITMAP_NUM_OF_BITS_IN_GROUP (UINT32_MAX / VRF_BITMAP_NUM_OF_GROUPS)
339#define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
340 (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
341
342#define VRF_BITMAP_GROUP(_id) ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
343#define VRF_BITMAP_BIT_OFFSET(_id) ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
344
345#define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) ((_bit_offset) / CHAR_BIT)
346#define VRF_BITMAP_FLAG(_bit_offset) \
347 (((uint8_t)1) << ((_bit_offset) % CHAR_BIT))
348
349struct vrf_bitmap {
350 uint8_t *groups[VRF_BITMAP_NUM_OF_GROUPS];
351};
352
353vrf_bitmap_t vrf_bitmap_init(void)
354{
355 return (vrf_bitmap_t)XCALLOC(MTYPE_VRF_BITMAP,
356 sizeof(struct vrf_bitmap));
357}
358
359void vrf_bitmap_free(vrf_bitmap_t bmap)
360{
361 struct vrf_bitmap *bm = (struct vrf_bitmap *)bmap;
362 int i;
363
364 if (bmap == VRF_BITMAP_NULL)
365 return;
366
367 for (i = 0; i < VRF_BITMAP_NUM_OF_GROUPS; i++)
368 if (bm->groups[i])
369 XFREE(MTYPE_VRF_BITMAP, bm->groups[i]);
370
371 XFREE(MTYPE_VRF_BITMAP, bm);
372}
373
374void vrf_bitmap_set(vrf_bitmap_t bmap, vrf_id_t vrf_id)
375{
376 struct vrf_bitmap *bm = (struct vrf_bitmap *)bmap;
377 uint8_t group = VRF_BITMAP_GROUP(vrf_id);
378 uint8_t offset = VRF_BITMAP_BIT_OFFSET(vrf_id);
379
380 if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN)
381 return;
382
383 if (bm->groups[group] == NULL)
384 bm->groups[group] = XCALLOC(MTYPE_VRF_BITMAP,
385 VRF_BITMAP_NUM_OF_BYTES_IN_GROUP);
386
387 SET_FLAG(bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP(offset)],
388 VRF_BITMAP_FLAG(offset));
389}
390
391void vrf_bitmap_unset(vrf_bitmap_t bmap, vrf_id_t vrf_id)
392{
393 struct vrf_bitmap *bm = (struct vrf_bitmap *)bmap;
394 uint8_t group = VRF_BITMAP_GROUP(vrf_id);
395 uint8_t offset = VRF_BITMAP_BIT_OFFSET(vrf_id);
396
397 if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN
398 || bm->groups[group] == NULL)
399 return;
400
401 UNSET_FLAG(bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP(offset)],
402 VRF_BITMAP_FLAG(offset));
403}
404
405int vrf_bitmap_check(vrf_bitmap_t bmap, vrf_id_t vrf_id)
406{
407 struct vrf_bitmap *bm = (struct vrf_bitmap *)bmap;
408 uint8_t group = VRF_BITMAP_GROUP(vrf_id);
409 uint8_t offset = VRF_BITMAP_BIT_OFFSET(vrf_id);
410
411 if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN
412 || bm->groups[group] == NULL)
413 return 0;
414
415 return CHECK_FLAG(bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP(offset)],
416 VRF_BITMAP_FLAG(offset))
417 ? 1
418 : 0;
419}
420
421static void vrf_autocomplete(vector comps, struct cmd_token *token)
422{
423 struct vrf *vrf = NULL;
424
425 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
426 if (vrf->vrf_id != VRF_DEFAULT)
427 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
428 }
429}
430
431static const struct cmd_variable_handler vrf_var_handlers[] = {
432 {
433 .varname = "vrf",
434 .completions = vrf_autocomplete,
435 },
436 {.completions = NULL},
437};
438
439/* Initialize VRF module. */
440void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
441 int (*disable)(struct vrf *), int (*delete)(struct vrf *))
442{
443 struct vrf *default_vrf;
444
445 /* initialise NS, in case VRF backend if NETNS */
446 ns_init();
447 if (debug_vrf)
448 zlog_debug("%s: Initializing VRF subsystem",
449 __PRETTY_FUNCTION__);
450
451 vrf_master.vrf_new_hook = create;
452 vrf_master.vrf_enable_hook = enable;
453 vrf_master.vrf_disable_hook = disable;
454 vrf_master.vrf_delete_hook = delete;
455
456 /* The default VRF always exists. */
457 default_vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
458 if (!default_vrf) {
459 zlog_err("vrf_init: failed to create the default VRF!");
460 exit(1);
461 }
462
463 /* Enable the default VRF. */
464 if (!vrf_enable(default_vrf)) {
465 zlog_err("vrf_init: failed to enable the default VRF!");
466 exit(1);
467 }
468
469 cmd_variable_handler_register(vrf_var_handlers);
470}
471
472/* Terminate VRF module. */
473void vrf_terminate(void)
474{
475 struct vrf *vrf;
476
477 if (debug_vrf)
478 zlog_debug("%s: Shutting down vrf subsystem",
479 __PRETTY_FUNCTION__);
480
481 while (!RB_EMPTY(vrf_id_head, &vrfs_by_id)) {
482 vrf = RB_ROOT(vrf_id_head, &vrfs_by_id);
483
484 /* Clear configured flag and invoke delete. */
485 UNSET_FLAG(vrf->status, VRF_CONFIGURED);
486 vrf_delete(vrf);
487 }
488
489 while (!RB_EMPTY(vrf_name_head, &vrfs_by_name)) {
490 vrf = RB_ROOT(vrf_name_head, &vrfs_by_name);
491
492 /* Clear configured flag and invoke delete. */
493 UNSET_FLAG(vrf->status, VRF_CONFIGURED);
494 vrf_delete(vrf);
495 }
496}
497
498/* Create a socket for the VRF. */
499int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
500 char *interfacename)
501{
502 int ret, save_errno, ret2;
503
504 ret = vrf_switch_to_netns(vrf_id);
505 if (ret < 0)
506 zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
507 safe_strerror(errno));
508 ret = socket(domain, type, protocol);
509 save_errno = errno;
510 ret2 = vrf_switchback_to_initial();
511 if (ret2 < 0)
512 zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
513 vrf_id, safe_strerror(errno));
514 errno = save_errno;
515 if (ret <= 0)
516 return ret;
517 ret2 = vrf_bind(vrf_id, ret, interfacename);
518 if (ret2 < 0) {
519 close(ret);
520 ret = ret2;
521 }
522 return ret;
523}
524
525int vrf_is_backend_netns(void)
526{
527 return (vrf_backend == VRF_BACKEND_NETNS);
528}
529
530int vrf_get_backend(void)
531{
532 return vrf_backend;
533}
534
535void vrf_configure_backend(int vrf_backend_netns)
536{
537 vrf_backend = vrf_backend_netns;
538}
539
540int vrf_handler_create(struct vty *vty, const char *vrfname, struct vrf **vrf)
541{
542 struct vrf *vrfp;
543
544 if (strlen(vrfname) > VRF_NAMSIZ) {
545 if (vty)
546 vty_out(vty,
547 "%% VRF name %s invalid: length exceeds %d bytes\n",
548 vrfname, VRF_NAMSIZ);
549 else
550 zlog_warn(
551 "%% VRF name %s invalid: length exceeds %d bytes\n",
552 vrfname, VRF_NAMSIZ);
553 return CMD_WARNING_CONFIG_FAILED;
554 }
555
556 vrfp = vrf_get(VRF_UNKNOWN, vrfname);
557
558 if (vty)
559 VTY_PUSH_CONTEXT(VRF_NODE, vrfp);
560
561 if (vrf)
562 *vrf = vrfp;
563 return CMD_SUCCESS;
564}
565
566int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
567 ns_id_t ns_id)
568{
569 struct ns *ns = NULL;
570
571 if (!vrf)
572 return CMD_WARNING_CONFIG_FAILED;
573 if (vrf->vrf_id != VRF_UNKNOWN && vrf->ns_ctxt == NULL) {
574 if (vty)
575 vty_out(vty,
576 "VRF %u is already configured with VRF %s\n",
577 vrf->vrf_id, vrf->name);
578 else
579 zlog_warn("VRF %u is already configured with VRF %s\n",
580 vrf->vrf_id, vrf->name);
581 return CMD_WARNING_CONFIG_FAILED;
582 }
583 if (vrf->ns_ctxt != NULL) {
584 ns = (struct ns *)vrf->ns_ctxt;
585 if (ns && 0 != strcmp(ns->name, pathname)) {
586 if (vty)
587 vty_out(vty,
588 "VRF %u already configured with NETNS %s\n",
589 vrf->vrf_id, ns->name);
590 else
591 zlog_warn(
592 "VRF %u already configured with NETNS %s",
593 vrf->vrf_id, ns->name);
594 return CMD_WARNING_CONFIG_FAILED;
595 }
596 }
597 ns = ns_lookup_name(pathname);
598 if (ns && ns->vrf_ctxt) {
599 struct vrf *vrf2 = (struct vrf *)ns->vrf_ctxt;
600
601 if (vrf2 == vrf)
602 return CMD_SUCCESS;
603 if (vty)
604 vty_out(vty,
605 "NS %s is already configured"
606 " with VRF %u(%s)\n",
607 ns->name, vrf2->vrf_id, vrf2->name);
608 else
609 zlog_warn("NS %s is already configured with VRF %u(%s)",
610 ns->name, vrf2->vrf_id, vrf2->name);
611 return CMD_WARNING_CONFIG_FAILED;
612 }
613 ns = ns_get_created(ns, pathname, ns_id);
614 ns->vrf_ctxt = (void *)vrf;
615 vrf->ns_ctxt = (void *)ns;
616 /* update VRF netns NAME */
617 if (vrf)
618 strlcpy(vrf->data.l.netns_name, basename(pathname), NS_NAMSIZ);
619
620 if (!ns_enable(ns, vrf_update_vrf_id)) {
621 if (vty)
622 vty_out(vty, "Can not associate NS %u with NETNS %s\n",
623 ns->ns_id, ns->name);
624 else
625 zlog_warn("Can not associate NS %u with NETNS %s",
626 ns->ns_id, ns->name);
627 return CMD_WARNING_CONFIG_FAILED;
628 }
629
630 return CMD_SUCCESS;
631}
632
633int vrf_is_mapped_on_netns(vrf_id_t vrf_id)
634{
635 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
636
637 if (!vrf || vrf->data.l.netns_name[0] == '\0')
638 return 0;
639 if (vrf->vrf_id == VRF_DEFAULT)
640 return 0;
641 return 1;
642}
643
644/* vrf CLI commands */
645DEFUN_NOSH (vrf,
646 vrf_cmd,
647 "vrf NAME",
648 "Select a VRF to configure\n"
649 "VRF's name\n")
650{
651 int idx_name = 1;
652 const char *vrfname = argv[idx_name]->arg;
653
654 return vrf_handler_create(vty, vrfname, NULL);
655}
656
657DEFUN_NOSH (no_vrf,
658 no_vrf_cmd,
659 "no vrf NAME",
660 NO_STR
661 "Delete a pseudo VRF's configuration\n"
662 "VRF's name\n")
663{
664 const char *vrfname = argv[2]->arg;
665
666 struct vrf *vrfp;
667
668 vrfp = vrf_lookup_by_name(vrfname);
669
670 if (vrfp == NULL) {
671 vty_out(vty, "%% VRF %s does not exist\n", vrfname);
672 return CMD_WARNING_CONFIG_FAILED;
673 }
674
675 if (CHECK_FLAG(vrfp->status, VRF_ACTIVE)) {
676 vty_out(vty, "%% Only inactive VRFs can be deleted\n");
677 return CMD_WARNING_CONFIG_FAILED;
678 }
679
680 /* Clear configured flag and invoke delete. */
681 UNSET_FLAG(vrfp->status, VRF_CONFIGURED);
682 vrf_delete(vrfp);
683
684 return CMD_SUCCESS;
685}
686
687
688struct cmd_node vrf_node = {VRF_NODE, "%s(config-vrf)# ", 1};
689
690DEFUN_NOSH (vrf_netns,
691 vrf_netns_cmd,
692 "netns NAME",
693 "Attach VRF to a Namespace\n"
694 "The file name in " NS_RUN_DIR ", or a full pathname\n")
695{
696 int idx_name = 1, ret;
697 char *pathname = ns_netns_pathname(vty, argv[idx_name]->arg);
698
699 VTY_DECLVAR_CONTEXT(vrf, vrf);
700
701 if (!pathname)
702 return CMD_WARNING_CONFIG_FAILED;
703
704 if (vrf_daemon_privs &&
705 vrf_daemon_privs->change(ZPRIVS_RAISE))
706 zlog_err("%s: Can't raise privileges", __func__);
707
708 ret = vrf_netns_handler_create(vty, vrf, pathname, NS_UNKNOWN);
709
710 if (vrf_daemon_privs &&
711 vrf_daemon_privs->change(ZPRIVS_LOWER))
712 zlog_err("%s: Can't lower privileges", __func__);
713 return ret;
714}
715
716DEFUN (no_vrf_netns,
717 no_vrf_netns_cmd,
718 "no netns [NAME]",
719 NO_STR
720 "Detach VRF from a Namespace\n"
721 "The file name in " NS_RUN_DIR ", or a full pathname\n")
722{
723 struct ns *ns = NULL;
724
725 VTY_DECLVAR_CONTEXT(vrf, vrf);
726
727 if (!vrf_is_backend_netns()) {
728 vty_out(vty, "VRF backend is not Netns. Aborting\n");
729 return CMD_WARNING_CONFIG_FAILED;
730 }
731 if (!vrf->ns_ctxt) {
732 vty_out(vty, "VRF %s(%u) is not configured with NetNS\n",
733 vrf->name, vrf->vrf_id);
734 return CMD_WARNING_CONFIG_FAILED;
735 }
736
737 ns = (struct ns *)vrf->ns_ctxt;
738
739 ns->vrf_ctxt = NULL;
740 vrf_disable(vrf);
741 /* vrf ID from VRF is necessary for Zebra
742 * so that propagate to other clients is done
743 */
744 ns_delete(ns);
745 vrf->ns_ctxt = NULL;
746 return CMD_SUCCESS;
747}
748
749/*
750 * Debug CLI for vrf's
751 */
752DEFUN (vrf_debug,
753 vrf_debug_cmd,
754 "debug vrf",
755 DEBUG_STR
756 "VRF Debugging\n")
757{
758 debug_vrf = 1;
759
760 return CMD_SUCCESS;
761}
762
763DEFUN (no_vrf_debug,
764 no_vrf_debug_cmd,
765 "no debug vrf",
766 NO_STR
767 DEBUG_STR
768 "VRF Debugging\n")
769{
770 debug_vrf = 0;
771
772 return CMD_SUCCESS;
773}
774
775static int vrf_write_host(struct vty *vty)
776{
777 if (debug_vrf)
778 vty_out(vty, "debug vrf\n");
779
780 return 1;
781}
782
783static struct cmd_node vrf_debug_node = {VRF_DEBUG_NODE, "", 1};
784
785void vrf_install_commands(void)
786{
787 install_node(&vrf_debug_node, vrf_write_host);
788
789 install_element(CONFIG_NODE, &vrf_debug_cmd);
790 install_element(ENABLE_NODE, &vrf_debug_cmd);
791 install_element(CONFIG_NODE, &no_vrf_debug_cmd);
792 install_element(ENABLE_NODE, &no_vrf_debug_cmd);
793}
794
795void vrf_cmd_init(int (*writefunc)(struct vty *vty),
796 struct zebra_privs_t *daemon_privs)
797{
798 install_element(CONFIG_NODE, &vrf_cmd);
799 install_element(CONFIG_NODE, &no_vrf_cmd);
800 install_node(&vrf_node, writefunc);
801 install_default(VRF_NODE);
802 if (vrf_is_backend_netns() && ns_have_netns()) {
803 /* Install NS commands. */
804 vrf_daemon_privs = daemon_privs;
805 install_element(VRF_NODE, &vrf_netns_cmd);
806 install_element(VRF_NODE, &no_vrf_netns_cmd);
807 }
808}
809
810vrf_id_t vrf_get_default_id(void)
811{
812 struct vrf *vrf = vrf_lookup_by_name(VRF_DEFAULT_NAME);
813
814 if (vrf)
815 return vrf->vrf_id;
816 if (vrf_is_backend_netns())
817 return ns_get_default_id();
818 else
819 return VRF_DEFAULT_INTERNAL;
820}
821
822int vrf_bind(vrf_id_t vrf_id, int fd, char *name)
823{
824 int ret = 0;
825
826 if (fd < 0 || name == NULL)
827 return fd;
828 if (vrf_is_mapped_on_netns(vrf_id))
829 return fd;
830#ifdef SO_BINDTODEVICE
831 ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name));
832 if (ret < 0)
833 zlog_debug("bind to interface %s failed, errno=%d", name,
834 errno);
835#endif /* SO_BINDTODEVICE */
836 return ret;
837}
838int vrf_getaddrinfo(const char *node, const char *service,
839 const struct addrinfo *hints, struct addrinfo **res,
840 vrf_id_t vrf_id)
841{
842 int ret, ret2, save_errno;
843
844 ret = vrf_switch_to_netns(vrf_id);
845 if (ret < 0)
846 zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
847 safe_strerror(errno));
848 ret = getaddrinfo(node, service, hints, res);
849 save_errno = errno;
850 ret2 = vrf_switchback_to_initial();
851 if (ret2 < 0)
852 zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
853 vrf_id, safe_strerror(errno));
854 errno = save_errno;
855 return ret;
856}
857
858int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
859{
860 int ret, saved_errno, rc;
861
862 ret = vrf_switch_to_netns(vrf_id);
863 if (ret < 0) {
864 zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
865 safe_strerror(errno));
866 return 0;
867 }
868 rc = ioctl(d, request, params);
869 saved_errno = errno;
870 ret = vrf_switchback_to_initial();
871 if (ret < 0)
872 zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
873 vrf_id, safe_strerror(errno));
874 errno = saved_errno;
875 return rc;
876}
877
878int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
879 char *interfacename)
880{
881 int ret, save_errno, ret2;
882
883 ret = vrf_switch_to_netns(vrf_id);
884 if (ret < 0)
885 zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
886 safe_strerror(errno));
887 ret = sockunion_socket(su);
888 save_errno = errno;
889 ret2 = vrf_switchback_to_initial();
890 if (ret2 < 0)
891 zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
892 vrf_id, safe_strerror(errno));
893 errno = save_errno;
894
895 if (ret <= 0)
896 return ret;
897 ret2 = vrf_bind(vrf_id, ret, interfacename);
898 if (ret2 < 0) {
899 close(ret);
900 ret = ret2;
901 }
902 return ret;
903}