]> git.proxmox.com Git - mirror_frr.git/blob - lib/vrf.c
zebra: Cleanup lines over 80 columns
[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
38 /* default VRF ID value used when VRF backend is not NETNS */
39 #define VRF_DEFAULT_INTERNAL 0
40
41 DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
42 DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
43
44 DEFINE_QOBJ_TYPE(vrf)
45
46 static __inline int vrf_id_compare(const struct vrf *, const struct vrf *);
47 static __inline int vrf_name_compare(const struct vrf *, const struct vrf *);
48
49 RB_GENERATE(vrf_id_head, vrf, id_entry, vrf_id_compare);
50 RB_GENERATE(vrf_name_head, vrf, name_entry, vrf_name_compare);
51
52 struct vrf_id_head vrfs_by_id = RB_INITIALIZER(&vrfs_by_id);
53 struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name);
54
55 static int vrf_backend;
56 static struct zebra_privs_t *vrf_daemon_privs;
57
58 /*
59 * Turn on/off debug code
60 * for vrf.
61 */
62 int debug_vrf = 0;
63
64 /* Holding VRF hooks */
65 struct 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
74 static int vrf_is_enabled(struct vrf *vrf);
75
76 /* VRF list existance check by name. */
77 struct 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
84 static __inline int vrf_id_compare(const struct vrf *a, const struct vrf *b)
85 {
86 return (a->vrf_id - b->vrf_id);
87 }
88
89 static 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 */
97 static 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
116 int 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
133 int 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 */
149 struct 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 */
203 void 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. */
243 struct 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 */
257 int 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 */
278 void 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
295 const 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
306 vrf_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. */
320 void *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. */
327 void *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
349 struct vrf_bitmap {
350 uint8_t *groups[VRF_BITMAP_NUM_OF_GROUPS];
351 };
352
353 vrf_bitmap_t vrf_bitmap_init(void)
354 {
355 return (vrf_bitmap_t)XCALLOC(MTYPE_VRF_BITMAP,
356 sizeof(struct vrf_bitmap));
357 }
358
359 void 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
374 void 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
391 void 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
405 int 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
421 static 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
431 static 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. */
440 void 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. */
473 void 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. */
499 int 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
525 int vrf_is_backend_netns(void)
526 {
527 return (vrf_backend == VRF_BACKEND_NETNS);
528 }
529
530 int vrf_get_backend(void)
531 {
532 return vrf_backend;
533 }
534
535 void vrf_configure_backend(int vrf_backend_netns)
536 {
537 vrf_backend = vrf_backend_netns;
538 }
539
540 int 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
566 int 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
633 int 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 */
645 DEFUN_NOSH(vrf_exit,
646 vrf_exit_cmd,
647 "exit-vrf",
648 "Exit current mode and down to previous mode\n")
649 {
650 /* We have to set vrf context to default vrf */
651 VTY_PUSH_CONTEXT(VRF_NODE, vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME));
652 vty->node = CONFIG_NODE;
653 return CMD_SUCCESS;
654 }
655
656 DEFUN_NOSH (vrf,
657 vrf_cmd,
658 "vrf NAME",
659 "Select a VRF to configure\n"
660 "VRF's name\n")
661 {
662 int idx_name = 1;
663 const char *vrfname = argv[idx_name]->arg;
664
665 return vrf_handler_create(vty, vrfname, NULL);
666 }
667
668 DEFUN_NOSH (no_vrf,
669 no_vrf_cmd,
670 "no vrf NAME",
671 NO_STR
672 "Delete a pseudo VRF's configuration\n"
673 "VRF's name\n")
674 {
675 const char *vrfname = argv[2]->arg;
676
677 struct vrf *vrfp;
678
679 vrfp = vrf_lookup_by_name(vrfname);
680
681 if (vrfp == NULL) {
682 vty_out(vty, "%% VRF %s does not exist\n", vrfname);
683 return CMD_WARNING_CONFIG_FAILED;
684 }
685
686 if (CHECK_FLAG(vrfp->status, VRF_ACTIVE)) {
687 vty_out(vty, "%% Only inactive VRFs can be deleted\n");
688 return CMD_WARNING_CONFIG_FAILED;
689 }
690
691 /* Clear configured flag and invoke delete. */
692 UNSET_FLAG(vrfp->status, VRF_CONFIGURED);
693 vrf_delete(vrfp);
694
695 return CMD_SUCCESS;
696 }
697
698
699 struct cmd_node vrf_node = {VRF_NODE, "%s(config-vrf)# ", 1};
700
701 DEFUN_NOSH (vrf_netns,
702 vrf_netns_cmd,
703 "netns NAME",
704 "Attach VRF to a Namespace\n"
705 "The file name in " NS_RUN_DIR ", or a full pathname\n")
706 {
707 int idx_name = 1, ret;
708 char *pathname = ns_netns_pathname(vty, argv[idx_name]->arg);
709
710 VTY_DECLVAR_CONTEXT(vrf, vrf);
711
712 if (!pathname)
713 return CMD_WARNING_CONFIG_FAILED;
714
715 if (vrf_daemon_privs &&
716 vrf_daemon_privs->change(ZPRIVS_RAISE))
717 zlog_err("%s: Can't raise privileges", __func__);
718
719 ret = vrf_netns_handler_create(vty, vrf, pathname, NS_UNKNOWN);
720
721 if (vrf_daemon_privs &&
722 vrf_daemon_privs->change(ZPRIVS_LOWER))
723 zlog_err("%s: Can't lower privileges", __func__);
724 return ret;
725 }
726
727 DEFUN (no_vrf_netns,
728 no_vrf_netns_cmd,
729 "no netns [NAME]",
730 NO_STR
731 "Detach VRF from a Namespace\n"
732 "The file name in " NS_RUN_DIR ", or a full pathname\n")
733 {
734 struct ns *ns = NULL;
735
736 VTY_DECLVAR_CONTEXT(vrf, vrf);
737
738 if (!vrf_is_backend_netns()) {
739 vty_out(vty, "VRF backend is not Netns. Aborting\n");
740 return CMD_WARNING_CONFIG_FAILED;
741 }
742 if (!vrf->ns_ctxt) {
743 vty_out(vty, "VRF %s(%u) is not configured with NetNS\n",
744 vrf->name, vrf->vrf_id);
745 return CMD_WARNING_CONFIG_FAILED;
746 }
747
748 ns = (struct ns *)vrf->ns_ctxt;
749
750 ns->vrf_ctxt = NULL;
751 vrf_disable(vrf);
752 /* vrf ID from VRF is necessary for Zebra
753 * so that propagate to other clients is done
754 */
755 ns_delete(ns);
756 vrf->ns_ctxt = NULL;
757 return CMD_SUCCESS;
758 }
759
760 /*
761 * Debug CLI for vrf's
762 */
763 DEFUN (vrf_debug,
764 vrf_debug_cmd,
765 "debug vrf",
766 DEBUG_STR
767 "VRF Debugging\n")
768 {
769 debug_vrf = 1;
770
771 return CMD_SUCCESS;
772 }
773
774 DEFUN (no_vrf_debug,
775 no_vrf_debug_cmd,
776 "no debug vrf",
777 NO_STR
778 DEBUG_STR
779 "VRF Debugging\n")
780 {
781 debug_vrf = 0;
782
783 return CMD_SUCCESS;
784 }
785
786 static int vrf_write_host(struct vty *vty)
787 {
788 if (debug_vrf)
789 vty_out(vty, "debug vrf\n");
790
791 return 1;
792 }
793
794 static struct cmd_node vrf_debug_node = {VRF_DEBUG_NODE, "", 1};
795
796 void vrf_install_commands(void)
797 {
798 install_node(&vrf_debug_node, vrf_write_host);
799
800 install_element(CONFIG_NODE, &vrf_debug_cmd);
801 install_element(ENABLE_NODE, &vrf_debug_cmd);
802 install_element(CONFIG_NODE, &no_vrf_debug_cmd);
803 install_element(ENABLE_NODE, &no_vrf_debug_cmd);
804 }
805
806 void vrf_cmd_init(int (*writefunc)(struct vty *vty),
807 struct zebra_privs_t *daemon_privs)
808 {
809 install_element(CONFIG_NODE, &vrf_cmd);
810 install_element(CONFIG_NODE, &no_vrf_cmd);
811 install_node(&vrf_node, writefunc);
812 install_default(VRF_NODE);
813 install_element(VRF_NODE, &vrf_exit_cmd);
814 if (vrf_is_backend_netns() && ns_have_netns()) {
815 /* Install NS commands. */
816 vrf_daemon_privs = daemon_privs;
817 install_element(VRF_NODE, &vrf_netns_cmd);
818 install_element(VRF_NODE, &no_vrf_netns_cmd);
819 }
820 }
821
822 vrf_id_t vrf_get_default_id(void)
823 {
824 struct vrf *vrf = vrf_lookup_by_name(VRF_DEFAULT_NAME);
825
826 if (vrf)
827 return vrf->vrf_id;
828 if (vrf_is_backend_netns())
829 return ns_get_default_id();
830 else
831 return VRF_DEFAULT_INTERNAL;
832 }
833
834 int vrf_bind(vrf_id_t vrf_id, int fd, char *name)
835 {
836 int ret = 0;
837
838 if (fd < 0 || name == NULL)
839 return fd;
840 if (vrf_is_mapped_on_netns(vrf_id))
841 return fd;
842 #ifdef SO_BINDTODEVICE
843 ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name));
844 if (ret < 0)
845 zlog_debug("bind to interface %s failed, errno=%d", name,
846 errno);
847 #endif /* SO_BINDTODEVICE */
848 return ret;
849 }
850 int vrf_getaddrinfo(const char *node, const char *service,
851 const struct addrinfo *hints, struct addrinfo **res,
852 vrf_id_t vrf_id)
853 {
854 int ret, ret2, save_errno;
855
856 ret = vrf_switch_to_netns(vrf_id);
857 if (ret < 0)
858 zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
859 safe_strerror(errno));
860 ret = getaddrinfo(node, service, hints, res);
861 save_errno = errno;
862 ret2 = vrf_switchback_to_initial();
863 if (ret2 < 0)
864 zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
865 vrf_id, safe_strerror(errno));
866 errno = save_errno;
867 return ret;
868 }
869
870 int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
871 {
872 int ret, saved_errno, rc;
873
874 ret = vrf_switch_to_netns(vrf_id);
875 if (ret < 0) {
876 zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
877 safe_strerror(errno));
878 return 0;
879 }
880 rc = ioctl(d, request, params);
881 saved_errno = errno;
882 ret = vrf_switchback_to_initial();
883 if (ret < 0)
884 zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
885 vrf_id, safe_strerror(errno));
886 errno = saved_errno;
887 return rc;
888 }
889
890 int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
891 char *interfacename)
892 {
893 int ret, save_errno, ret2;
894
895 ret = vrf_switch_to_netns(vrf_id);
896 if (ret < 0)
897 zlog_err("%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
898 safe_strerror(errno));
899 ret = sockunion_socket(su);
900 save_errno = errno;
901 ret2 = vrf_switchback_to_initial();
902 if (ret2 < 0)
903 zlog_err("%s: Can't switchback from VRF %u (%s)", __func__,
904 vrf_id, safe_strerror(errno));
905 errno = save_errno;
906
907 if (ret <= 0)
908 return ret;
909 ret2 = vrf_bind(vrf_id, ret, interfacename);
910 if (ret2 < 0) {
911 close(ret);
912 ret = ret2;
913 }
914 return ret;
915 }