3 * Copyright (C) 2014 6WIND S.A.
5 * This file is part of GNU Zebra.
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.
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.
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
37 #include "nexthop_group.h"
38 #include "lib_errors.h"
39 #include "northbound.h"
40 #include "northbound_cli.h"
42 /* default VRF ID value used when VRF backend is not NETNS */
43 #define VRF_DEFAULT_INTERNAL 0
44 #define VRF_DEFAULT_NAME_INTERNAL "default"
46 DEFINE_MTYPE_STATIC(LIB
, VRF
, "VRF")
47 DEFINE_MTYPE_STATIC(LIB
, VRF_BITMAP
, "VRF bit-map")
51 static __inline
int vrf_id_compare(const struct vrf
*, const struct vrf
*);
52 static __inline
int vrf_name_compare(const struct vrf
*, const struct vrf
*);
54 RB_GENERATE(vrf_id_head
, vrf
, id_entry
, vrf_id_compare
);
55 RB_GENERATE(vrf_name_head
, vrf
, name_entry
, vrf_name_compare
);
57 struct vrf_id_head vrfs_by_id
= RB_INITIALIZER(&vrfs_by_id
);
58 struct vrf_name_head vrfs_by_name
= RB_INITIALIZER(&vrfs_by_name
);
60 static int vrf_backend
;
61 static int vrf_backend_configured
;
62 static struct zebra_privs_t
*vrf_daemon_privs
;
63 static char vrf_default_name
[VRF_NAMSIZ
] = VRF_DEFAULT_NAME_INTERNAL
;
66 * Turn on/off debug code
69 static int debug_vrf
= 0;
71 /* Holding VRF hooks */
72 static struct vrf_master
{
73 int (*vrf_new_hook
)(struct vrf
*);
74 int (*vrf_delete_hook
)(struct vrf
*);
75 int (*vrf_enable_hook
)(struct vrf
*);
76 int (*vrf_disable_hook
)(struct vrf
*);
77 int (*vrf_update_name_hook
)(struct vrf
*vrf
);
82 static int vrf_is_enabled(struct vrf
*vrf
);
84 /* VRF list existance check by name. */
85 struct vrf
*vrf_lookup_by_name(const char *name
)
88 strlcpy(vrf
.name
, name
, sizeof(vrf
.name
));
89 return (RB_FIND(vrf_name_head
, &vrfs_by_name
, &vrf
));
92 static __inline
int vrf_id_compare(const struct vrf
*a
, const struct vrf
*b
)
94 return (a
->vrf_id
- b
->vrf_id
);
97 static int vrf_name_compare(const struct vrf
*a
, const struct vrf
*b
)
99 return strcmp(a
->name
, b
->name
);
102 /* if ns_id is different and not VRF_UNKNOWN,
103 * then update vrf identifier, and enable VRF
105 static void vrf_update_vrf_id(ns_id_t ns_id
, void *opaqueptr
)
107 ns_id_t vrf_id
= (vrf_id_t
)ns_id
;
109 struct vrf
*vrf
= (struct vrf
*)opaqueptr
;
113 old_vrf_id
= vrf
->vrf_id
;
114 if (vrf_id
== vrf
->vrf_id
)
116 if (vrf
->vrf_id
!= VRF_UNKNOWN
)
117 RB_REMOVE(vrf_id_head
, &vrfs_by_id
, vrf
);
118 vrf
->vrf_id
= vrf_id
;
119 RB_INSERT(vrf_id_head
, &vrfs_by_id
, vrf
);
120 if (old_vrf_id
== VRF_UNKNOWN
)
124 int vrf_switch_to_netns(vrf_id_t vrf_id
)
127 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
129 /* VRF is default VRF. silently ignore */
130 if (!vrf
|| vrf
->vrf_id
== VRF_DEFAULT
)
131 return 1; /* 1 = default */
132 /* VRF has no NETNS backend. silently ignore */
133 if (vrf
->data
.l
.netns_name
[0] == '\0')
134 return 2; /* 2 = no netns */
135 name
= ns_netns_pathname(NULL
, vrf
->data
.l
.netns_name
);
137 zlog_debug("VRF_SWITCH: %s(%u)", name
, vrf
->vrf_id
);
138 return ns_switch_to_netns(name
);
141 int vrf_switchback_to_initial(void)
143 int ret
= ns_switchback_to_initial();
145 if (ret
== 0 && debug_vrf
)
146 zlog_debug("VRF_SWITCHBACK");
150 /* Get a VRF. If not found, create one.
152 * name - The name of the vrf. May be NULL if unknown.
153 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
154 * Description: Please note that this routine can be called with just the name
157 struct vrf
*vrf_get(vrf_id_t vrf_id
, const char *name
)
159 struct vrf
*vrf
= NULL
;
163 zlog_debug("VRF_GET: %s(%u)", name
== NULL
? "(NULL)" : name
,
166 /* Nothing to see, move along here */
167 if (!name
&& vrf_id
== VRF_UNKNOWN
)
170 /* attempt to find already available VRF
173 vrf
= vrf_lookup_by_name(name
);
174 if (vrf
&& vrf_id
!= VRF_UNKNOWN
175 && vrf
->vrf_id
!= VRF_UNKNOWN
176 && vrf
->vrf_id
!= vrf_id
) {
177 zlog_debug("VRF_GET: avoid %s creation(%u), same name exists (%u)",
178 name
, vrf_id
, vrf
->vrf_id
);
181 /* Try to find VRF both by ID and name */
182 if (!vrf
&& vrf_id
!= VRF_UNKNOWN
)
183 vrf
= vrf_lookup_by_id(vrf_id
);
186 vrf
= XCALLOC(MTYPE_VRF
, sizeof(struct vrf
));
187 vrf
->vrf_id
= VRF_UNKNOWN
;
192 zlog_debug("VRF(%u) %s is created.", vrf_id
,
193 (name
) ? name
: "(NULL)");
197 if (vrf_id
!= VRF_UNKNOWN
&& vrf
->vrf_id
== VRF_UNKNOWN
) {
198 vrf
->vrf_id
= vrf_id
;
199 RB_INSERT(vrf_id_head
, &vrfs_by_id
, vrf
);
203 if (name
&& vrf
->name
[0] != '\0' && strcmp(name
, vrf
->name
)) {
204 /* update the vrf name */
205 RB_REMOVE(vrf_name_head
, &vrfs_by_name
, vrf
);
206 strlcpy(vrf
->data
.l
.netns_name
,
208 strlcpy(vrf
->name
, name
, sizeof(vrf
->name
));
209 RB_INSERT(vrf_name_head
, &vrfs_by_name
, vrf
);
210 if (vrf
->vrf_id
== VRF_DEFAULT
)
211 vrf_set_default_name(vrf
->name
, false);
212 } else if (name
&& vrf
->name
[0] == '\0') {
213 strlcpy(vrf
->name
, name
, sizeof(vrf
->name
));
214 RB_INSERT(vrf_name_head
, &vrfs_by_name
, vrf
);
216 if (new &&vrf_master
.vrf_new_hook
)
217 (*vrf_master
.vrf_new_hook
)(vrf
);
222 /* Delete a VRF. This is called when the underlying VRF goes away, a
223 * pre-configured VRF is deleted or when shutting down (vrf_terminate()).
225 void vrf_delete(struct vrf
*vrf
)
228 zlog_debug("VRF %u is to be deleted.", vrf
->vrf_id
);
230 if (vrf_is_enabled(vrf
))
233 /* If the VRF is user configured, it'll stick around, just remove
234 * the ID mapping. Interfaces assigned to this VRF should've been
235 * removed already as part of the VRF going down.
237 if (vrf_is_user_cfged(vrf
)) {
238 if (vrf
->vrf_id
!= VRF_UNKNOWN
) {
239 /* Delete any VRF interfaces - should be only
240 * the VRF itself, other interfaces should've
241 * been moved out of the VRF.
244 RB_REMOVE(vrf_id_head
, &vrfs_by_id
, vrf
);
245 vrf
->vrf_id
= VRF_UNKNOWN
;
250 if (vrf_master
.vrf_delete_hook
)
251 (*vrf_master
.vrf_delete_hook
)(vrf
);
256 if (vrf
->vrf_id
!= VRF_UNKNOWN
)
257 RB_REMOVE(vrf_id_head
, &vrfs_by_id
, vrf
);
258 if (vrf
->name
[0] != '\0')
259 RB_REMOVE(vrf_name_head
, &vrfs_by_name
, vrf
);
261 XFREE(MTYPE_VRF
, vrf
);
264 /* Look up a VRF by identifier. */
265 struct vrf
*vrf_lookup_by_id(vrf_id_t vrf_id
)
269 return (RB_FIND(vrf_id_head
, &vrfs_by_id
, &vrf
));
273 * Enable a VRF - that is, let the VRF be ready to use.
274 * The VRF_ENABLE_HOOK callback will be called to inform
275 * that they can allocate resources in this VRF.
277 * RETURN: 1 - enabled successfully; otherwise, 0.
279 int vrf_enable(struct vrf
*vrf
)
281 if (vrf_is_enabled(vrf
))
285 zlog_debug("VRF %u is enabled.", vrf
->vrf_id
);
287 SET_FLAG(vrf
->status
, VRF_ACTIVE
);
289 if (vrf_master
.vrf_enable_hook
)
290 (*vrf_master
.vrf_enable_hook
)(vrf
);
293 * If we have any nexthop group entries that
294 * are awaiting vrf initialization then
295 * let's let people know about it
297 nexthop_group_enable_vrf(vrf
);
303 * Disable a VRF - that is, let the VRF be unusable.
304 * The VRF_DELETE_HOOK callback will be called to inform
305 * that they must release the resources in the VRF.
307 void vrf_disable(struct vrf
*vrf
)
309 if (!vrf_is_enabled(vrf
))
312 UNSET_FLAG(vrf
->status
, VRF_ACTIVE
);
315 zlog_debug("VRF %u is to be disabled.", vrf
->vrf_id
);
317 /* Till now, nothing to be done for the default VRF. */
318 // Pending: see why this statement.
320 if (vrf_master
.vrf_disable_hook
)
321 (*vrf_master
.vrf_disable_hook
)(vrf
);
324 const char *vrf_id_to_name(vrf_id_t vrf_id
)
328 vrf
= vrf_lookup_by_id(vrf_id
);
329 return VRF_LOGNAME(vrf
);
332 vrf_id_t
vrf_name_to_id(const char *name
)
335 vrf_id_t vrf_id
= VRF_DEFAULT
; // Pending: need a way to return invalid
336 // id/ routine not used.
340 vrf
= vrf_lookup_by_name(name
);
342 vrf_id
= vrf
->vrf_id
;
347 /* Get the data pointer of the specified VRF. If not found, create one. */
348 void *vrf_info_get(vrf_id_t vrf_id
)
350 struct vrf
*vrf
= vrf_get(vrf_id
, NULL
);
354 /* Look up the data pointer of the specified VRF. */
355 void *vrf_info_lookup(vrf_id_t vrf_id
)
357 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
358 return vrf
? vrf
->info
: NULL
;
362 * VRF hash for storing set or not.
369 static unsigned int vrf_hash_bitmap_key(const void *data
)
371 const struct vrf_bit_set
*bit
= data
;
376 static bool vrf_hash_bitmap_cmp(const void *a
, const void *b
)
378 const struct vrf_bit_set
*bit1
= a
;
379 const struct vrf_bit_set
*bit2
= b
;
381 return bit1
->vrf_id
== bit2
->vrf_id
;
384 static void *vrf_hash_bitmap_alloc(void *data
)
386 struct vrf_bit_set
*copy
= data
;
387 struct vrf_bit_set
*bit
;
389 bit
= XMALLOC(MTYPE_VRF_BITMAP
, sizeof(*bit
));
390 bit
->vrf_id
= copy
->vrf_id
;
395 static void vrf_hash_bitmap_free(void *data
)
397 struct vrf_bit_set
*bit
= data
;
399 XFREE(MTYPE_VRF_BITMAP
, bit
);
402 vrf_bitmap_t
vrf_bitmap_init(void)
404 return hash_create_size(32, vrf_hash_bitmap_key
, vrf_hash_bitmap_cmp
,
408 void vrf_bitmap_free(vrf_bitmap_t bmap
)
410 struct hash
*vrf_hash
= bmap
;
412 if (vrf_hash
== NULL
)
415 hash_clean(vrf_hash
, vrf_hash_bitmap_free
);
419 void vrf_bitmap_set(vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
421 struct vrf_bit_set lookup
= { .vrf_id
= vrf_id
};
422 struct hash
*vrf_hash
= bmap
;
423 struct vrf_bit_set
*bit
;
425 if (vrf_hash
== NULL
|| vrf_id
== VRF_UNKNOWN
)
428 bit
= hash_get(vrf_hash
, &lookup
, vrf_hash_bitmap_alloc
);
432 void vrf_bitmap_unset(vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
434 struct vrf_bit_set lookup
= { .vrf_id
= vrf_id
};
435 struct hash
*vrf_hash
= bmap
;
436 struct vrf_bit_set
*bit
;
438 if (vrf_hash
== NULL
|| vrf_id
== VRF_UNKNOWN
)
441 bit
= hash_get(vrf_hash
, &lookup
, vrf_hash_bitmap_alloc
);
445 int vrf_bitmap_check(vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
447 struct vrf_bit_set lookup
= { .vrf_id
= vrf_id
};
448 struct hash
*vrf_hash
= bmap
;
449 struct vrf_bit_set
*bit
;
451 if (vrf_hash
== NULL
|| vrf_id
== VRF_UNKNOWN
)
454 bit
= hash_lookup(vrf_hash
, &lookup
);
461 static void vrf_autocomplete(vector comps
, struct cmd_token
*token
)
463 struct vrf
*vrf
= NULL
;
465 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
466 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
469 static const struct cmd_variable_handler vrf_var_handlers
[] = {
472 .completions
= vrf_autocomplete
,
475 .varname
= "vrf_name",
476 .completions
= vrf_autocomplete
,
479 .varname
= "nexthop_vrf",
480 .completions
= vrf_autocomplete
,
482 {.completions
= NULL
},
485 /* Initialize VRF module. */
486 void vrf_init(int (*create
)(struct vrf
*), int (*enable
)(struct vrf
*),
487 int (*disable
)(struct vrf
*), int (*destroy
)(struct vrf
*),
488 int ((*update
)(struct vrf
*)))
490 struct vrf
*default_vrf
;
492 /* initialise NS, in case VRF backend if NETNS */
495 zlog_debug("%s: Initializing VRF subsystem", __func__
);
497 vrf_master
.vrf_new_hook
= create
;
498 vrf_master
.vrf_enable_hook
= enable
;
499 vrf_master
.vrf_disable_hook
= disable
;
500 vrf_master
.vrf_delete_hook
= destroy
;
501 vrf_master
.vrf_update_name_hook
= update
;
503 /* The default VRF always exists. */
504 default_vrf
= vrf_get(VRF_DEFAULT
, VRF_DEFAULT_NAME
);
506 flog_err(EC_LIB_VRF_START
,
507 "vrf_init: failed to create the default VRF!");
510 if (vrf_is_backend_netns()) {
513 strlcpy(default_vrf
->data
.l
.netns_name
,
514 VRF_DEFAULT_NAME
, NS_NAMSIZ
);
515 ns
= ns_lookup(ns_get_default_id());
516 ns
->vrf_ctxt
= default_vrf
;
517 default_vrf
->ns_ctxt
= ns
;
520 /* Enable the default VRF. */
521 if (!vrf_enable(default_vrf
)) {
522 flog_err(EC_LIB_VRF_START
,
523 "vrf_init: failed to enable the default VRF!");
527 cmd_variable_handler_register(vrf_var_handlers
);
530 /* Terminate VRF module. */
531 void vrf_terminate(void)
536 zlog_debug("%s: Shutting down vrf subsystem", __func__
);
538 while (!RB_EMPTY(vrf_id_head
, &vrfs_by_id
)) {
539 vrf
= RB_ROOT(vrf_id_head
, &vrfs_by_id
);
541 /* Clear configured flag and invoke delete. */
542 UNSET_FLAG(vrf
->status
, VRF_CONFIGURED
);
546 while (!RB_EMPTY(vrf_name_head
, &vrfs_by_name
)) {
547 vrf
= RB_ROOT(vrf_name_head
, &vrfs_by_name
);
549 /* Clear configured flag and invoke delete. */
550 UNSET_FLAG(vrf
->status
, VRF_CONFIGURED
);
555 int vrf_socket(int domain
, int type
, int protocol
, vrf_id_t vrf_id
,
556 const char *interfacename
)
558 int ret
, save_errno
, ret2
;
560 ret
= vrf_switch_to_netns(vrf_id
);
562 flog_err_sys(EC_LIB_SOCKET
, "%s: Can't switch to VRF %u (%s)",
563 __func__
, vrf_id
, safe_strerror(errno
));
565 ret
= socket(domain
, type
, protocol
);
567 ret2
= vrf_switchback_to_initial();
569 flog_err_sys(EC_LIB_SOCKET
,
570 "%s: Can't switchback from VRF %u (%s)", __func__
,
571 vrf_id
, safe_strerror(errno
));
575 ret2
= vrf_bind(vrf_id
, ret
, interfacename
);
583 int vrf_is_backend_netns(void)
585 return (vrf_backend
== VRF_BACKEND_NETNS
);
588 int vrf_get_backend(void)
590 if (!vrf_backend_configured
)
591 return VRF_BACKEND_UNKNOWN
;
595 int vrf_configure_backend(enum vrf_backend_type backend
)
597 /* Work around issue in old gcc */
599 case VRF_BACKEND_UNKNOWN
:
600 case VRF_BACKEND_NETNS
:
601 case VRF_BACKEND_VRF_LITE
:
607 vrf_backend
= backend
;
608 vrf_backend_configured
= 1;
613 int vrf_handler_create(struct vty
*vty
, const char *vrfname
,
617 char xpath_list
[XPATH_MAXLEN
];
620 if (strlen(vrfname
) > VRF_NAMSIZ
) {
623 "%% VRF name %s invalid: length exceeds %d bytes\n",
624 vrfname
, VRF_NAMSIZ
);
628 "%% VRF name %s invalid: length exceeds %d bytes\n",
629 vrfname
, VRF_NAMSIZ
);
630 return CMD_WARNING_CONFIG_FAILED
;
634 snprintf(xpath_list
, sizeof(xpath_list
),
635 "/frr-vrf:lib/vrf[name='%s']", vrfname
);
637 nb_cli_enqueue_change(vty
, xpath_list
, NB_OP_CREATE
, NULL
);
638 ret
= nb_cli_apply_changes(vty
, xpath_list
);
639 if (ret
== CMD_SUCCESS
) {
640 VTY_PUSH_XPATH(VRF_NODE
, xpath_list
);
641 vrfp
= vrf_lookup_by_name(vrfname
);
643 VTY_PUSH_CONTEXT(VRF_NODE
, vrfp
);
646 vrfp
= vrf_get(VRF_UNKNOWN
, vrfname
);
654 int vrf_netns_handler_create(struct vty
*vty
, struct vrf
*vrf
, char *pathname
,
655 ns_id_t ns_id
, ns_id_t internal_ns_id
)
657 struct ns
*ns
= NULL
;
660 return CMD_WARNING_CONFIG_FAILED
;
661 if (vrf
->vrf_id
!= VRF_UNKNOWN
&& vrf
->ns_ctxt
== NULL
) {
664 "VRF %u is already configured with VRF %s\n",
665 vrf
->vrf_id
, vrf
->name
);
667 zlog_info("VRF %u is already configured with VRF %s",
668 vrf
->vrf_id
, vrf
->name
);
669 return CMD_WARNING_CONFIG_FAILED
;
671 if (vrf
->ns_ctxt
!= NULL
) {
672 ns
= (struct ns
*)vrf
->ns_ctxt
;
673 if (!strcmp(ns
->name
, pathname
)) {
676 "VRF %u already configured with NETNS %s\n",
677 vrf
->vrf_id
, ns
->name
);
680 "VRF %u already configured with NETNS %s",
681 vrf
->vrf_id
, ns
->name
);
682 return CMD_WARNING_CONFIG_FAILED
;
685 ns
= ns_lookup_name(pathname
);
686 if (ns
&& ns
->vrf_ctxt
) {
687 struct vrf
*vrf2
= (struct vrf
*)ns
->vrf_ctxt
;
693 "NS %s is already configured"
694 " with VRF %u(%s)\n",
695 ns
->name
, vrf2
->vrf_id
, vrf2
->name
);
697 zlog_info("NS %s is already configured with VRF %u(%s)",
698 ns
->name
, vrf2
->vrf_id
, vrf2
->name
);
699 return CMD_WARNING_CONFIG_FAILED
;
701 ns
= ns_get_created(ns
, pathname
, ns_id
);
702 ns
->internal_ns_id
= internal_ns_id
;
703 ns
->vrf_ctxt
= (void *)vrf
;
704 vrf
->ns_ctxt
= (void *)ns
;
705 /* update VRF netns NAME */
706 strlcpy(vrf
->data
.l
.netns_name
, basename(pathname
), NS_NAMSIZ
);
708 if (!ns_enable(ns
, vrf_update_vrf_id
)) {
710 vty_out(vty
, "Can not associate NS %u with NETNS %s\n",
711 ns
->ns_id
, ns
->name
);
713 zlog_info("Can not associate NS %u with NETNS %s",
714 ns
->ns_id
, ns
->name
);
715 return CMD_WARNING_CONFIG_FAILED
;
721 /* vrf CLI commands */
725 "Exit current mode and down to previous mode\n")
727 /* We have to set vrf context to default vrf */
728 VTY_PUSH_CONTEXT(VRF_NODE
, vrf_get(VRF_DEFAULT
, VRF_DEFAULT_NAME
));
729 vty
->node
= CONFIG_NODE
;
736 "Select a VRF to configure\n"
740 const char *vrfname
= argv
[idx_name
]->arg
;
742 return vrf_handler_create(vty
, vrfname
, NULL
);
749 "Delete a pseudo VRF's configuration\n"
752 const char *vrfname
= argv
[2]->arg
;
753 char xpath_list
[XPATH_MAXLEN
];
757 vrfp
= vrf_lookup_by_name(vrfname
);
760 vty_out(vty
, "%% VRF %s does not exist\n", vrfname
);
761 return CMD_WARNING_CONFIG_FAILED
;
764 if (CHECK_FLAG(vrfp
->status
, VRF_ACTIVE
)) {
765 vty_out(vty
, "%% Only inactive VRFs can be deleted\n");
766 return CMD_WARNING_CONFIG_FAILED
;
769 snprintf(xpath_list
, sizeof(xpath_list
), "/frr-vrf:lib/vrf[name='%s']",
772 nb_cli_enqueue_change(vty
, xpath_list
, NB_OP_DESTROY
, NULL
);
773 return nb_cli_apply_changes(vty
, xpath_list
);
777 static struct cmd_node vrf_node
= {
780 .parent_node
= CONFIG_NODE
,
781 .prompt
= "%s(config-vrf)# ",
784 DEFUN_NOSH (vrf_netns
,
787 "Attach VRF to a Namespace\n"
788 "The file name in " NS_RUN_DIR
", or a full pathname\n")
790 int idx_name
= 1, ret
;
791 char *pathname
= ns_netns_pathname(vty
, argv
[idx_name
]->arg
);
793 VTY_DECLVAR_CONTEXT(vrf
, vrf
);
796 return CMD_WARNING_CONFIG_FAILED
;
798 frr_with_privs(vrf_daemon_privs
) {
799 ret
= vrf_netns_handler_create(vty
, vrf
, pathname
,
800 NS_UNKNOWN
, NS_UNKNOWN
);
805 DEFUN_NOSH (no_vrf_netns
,
809 "Detach VRF from a Namespace\n"
810 "The file name in " NS_RUN_DIR
", or a full pathname\n")
812 struct ns
*ns
= NULL
;
814 VTY_DECLVAR_CONTEXT(vrf
, vrf
);
816 if (!vrf_is_backend_netns()) {
817 vty_out(vty
, "VRF backend is not Netns. Aborting\n");
818 return CMD_WARNING_CONFIG_FAILED
;
821 vty_out(vty
, "VRF %s(%u) is not configured with NetNS\n",
822 vrf
->name
, vrf
->vrf_id
);
823 return CMD_WARNING_CONFIG_FAILED
;
826 ns
= (struct ns
*)vrf
->ns_ctxt
;
830 /* vrf ID from VRF is necessary for Zebra
831 * so that propagate to other clients is done
839 * Debug CLI for vrf's
864 static int vrf_write_host(struct vty
*vty
)
867 vty_out(vty
, "debug vrf\n");
872 static int vrf_write_host(struct vty
*vty
);
873 static struct cmd_node vrf_debug_node
= {
875 .node
= VRF_DEBUG_NODE
,
877 .config_write
= vrf_write_host
,
880 void vrf_install_commands(void)
882 install_node(&vrf_debug_node
);
884 install_element(CONFIG_NODE
, &vrf_debug_cmd
);
885 install_element(ENABLE_NODE
, &vrf_debug_cmd
);
886 install_element(CONFIG_NODE
, &no_vrf_debug_cmd
);
887 install_element(ENABLE_NODE
, &no_vrf_debug_cmd
);
890 void vrf_cmd_init(int (*writefunc
)(struct vty
*vty
),
891 struct zebra_privs_t
*daemon_privs
)
893 install_element(CONFIG_NODE
, &vrf_cmd
);
894 install_element(CONFIG_NODE
, &no_vrf_cmd
);
895 vrf_node
.config_write
= writefunc
;
896 install_node(&vrf_node
);
897 install_default(VRF_NODE
);
898 install_element(VRF_NODE
, &vrf_exit_cmd
);
899 if (vrf_is_backend_netns() && ns_have_netns()) {
900 /* Install NS commands. */
901 vrf_daemon_privs
= daemon_privs
;
902 install_element(VRF_NODE
, &vrf_netns_cmd
);
903 install_element(VRF_NODE
, &no_vrf_netns_cmd
);
907 void vrf_set_default_name(const char *default_name
, bool force
)
910 static bool def_vrf_forced
;
912 def_vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
913 assert(default_name
);
914 if (def_vrf
&& !force
&& def_vrf_forced
) {
915 zlog_debug("VRF: %s, avoid changing name to %s, previously forced (%u)",
916 def_vrf
->name
, default_name
,
920 if (strmatch(vrf_default_name
, default_name
))
922 snprintf(vrf_default_name
, VRF_NAMSIZ
, "%s", default_name
);
925 def_vrf_forced
= true;
926 RB_REMOVE(vrf_name_head
, &vrfs_by_name
, def_vrf
);
927 strlcpy(def_vrf
->data
.l
.netns_name
,
928 vrf_default_name
, NS_NAMSIZ
);
929 strlcpy(def_vrf
->name
, vrf_default_name
, sizeof(def_vrf
->name
));
930 RB_INSERT(vrf_name_head
, &vrfs_by_name
, def_vrf
);
931 if (vrf_master
.vrf_update_name_hook
)
932 (*vrf_master
.vrf_update_name_hook
)(def_vrf
);
936 const char *vrf_get_default_name(void)
938 return vrf_default_name
;
941 vrf_id_t
vrf_get_default_id(void)
943 /* backend netns is only known by zebra
944 * for other daemons, we return VRF_DEFAULT_INTERNAL
946 if (vrf_is_backend_netns())
947 return ns_get_default_id();
949 return VRF_DEFAULT_INTERNAL
;
952 int vrf_bind(vrf_id_t vrf_id
, int fd
, const char *name
)
955 struct interface
*ifp
;
957 if (fd
< 0 || name
== NULL
)
959 /* the device should exist
960 * otherwise we should return
961 * case ifname = vrf in netns mode => return
963 ifp
= if_lookup_by_name(name
, vrf_id
);
966 #ifdef SO_BINDTODEVICE
967 ret
= setsockopt(fd
, SOL_SOCKET
, SO_BINDTODEVICE
, name
, strlen(name
)+1);
969 zlog_debug("bind to interface %s failed, errno=%d", name
,
971 #endif /* SO_BINDTODEVICE */
974 int vrf_getaddrinfo(const char *node
, const char *service
,
975 const struct addrinfo
*hints
, struct addrinfo
**res
,
978 int ret
, ret2
, save_errno
;
980 ret
= vrf_switch_to_netns(vrf_id
);
982 flog_err_sys(EC_LIB_SOCKET
, "%s: Can't switch to VRF %u (%s)",
983 __func__
, vrf_id
, safe_strerror(errno
));
984 ret
= getaddrinfo(node
, service
, hints
, res
);
986 ret2
= vrf_switchback_to_initial();
988 flog_err_sys(EC_LIB_SOCKET
,
989 "%s: Can't switchback from VRF %u (%s)", __func__
,
990 vrf_id
, safe_strerror(errno
));
995 int vrf_ioctl(vrf_id_t vrf_id
, int d
, unsigned long request
, char *params
)
997 int ret
, saved_errno
, rc
;
999 ret
= vrf_switch_to_netns(vrf_id
);
1001 flog_err_sys(EC_LIB_SOCKET
, "%s: Can't switch to VRF %u (%s)",
1002 __func__
, vrf_id
, safe_strerror(errno
));
1005 rc
= ioctl(d
, request
, params
);
1006 saved_errno
= errno
;
1007 ret
= vrf_switchback_to_initial();
1009 flog_err_sys(EC_LIB_SOCKET
,
1010 "%s: Can't switchback from VRF %u (%s)", __func__
,
1011 vrf_id
, safe_strerror(errno
));
1012 errno
= saved_errno
;
1016 int vrf_sockunion_socket(const union sockunion
*su
, vrf_id_t vrf_id
,
1017 const char *interfacename
)
1019 int ret
, save_errno
, ret2
;
1021 ret
= vrf_switch_to_netns(vrf_id
);
1023 flog_err_sys(EC_LIB_SOCKET
, "%s: Can't switch to VRF %u (%s)",
1024 __func__
, vrf_id
, safe_strerror(errno
));
1025 ret
= sockunion_socket(su
);
1027 ret2
= vrf_switchback_to_initial();
1029 flog_err_sys(EC_LIB_SOCKET
,
1030 "%s: Can't switchback from VRF %u (%s)", __func__
,
1031 vrf_id
, safe_strerror(errno
));
1036 ret2
= vrf_bind(vrf_id
, ret
, interfacename
);
1044 vrf_id_t
vrf_generate_id(void)
1046 static int vrf_id_local
;
1048 return ++vrf_id_local
;
1051 /* ------- Northbound callbacks ------- */
1054 * XPath: /frr-vrf:lib/vrf
1056 static int lib_vrf_create(struct nb_cb_create_args
*args
)
1058 const char *vrfname
;
1061 vrfname
= yang_dnode_get_string(args
->dnode
, "./name");
1063 if (args
->event
!= NB_EV_APPLY
)
1066 vrfp
= vrf_get(VRF_UNKNOWN
, vrfname
);
1068 nb_running_set_entry(args
->dnode
, vrfp
);
1073 static int lib_vrf_destroy(struct nb_cb_destroy_args
*args
)
1077 switch (args
->event
) {
1078 case NB_EV_VALIDATE
:
1079 vrfp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1080 if (CHECK_FLAG(vrfp
->status
, VRF_ACTIVE
)) {
1081 zlog_debug("%s Only inactive VRFs can be deleted",
1083 return NB_ERR_VALIDATION
;
1090 vrfp
= nb_running_unset_entry(args
->dnode
);
1092 /* Clear configured flag and invoke delete. */
1093 UNSET_FLAG(vrfp
->status
, VRF_CONFIGURED
);
1101 static const void *lib_vrf_get_next(struct nb_cb_get_next_args
*args
)
1103 struct vrf
*vrfp
= (struct vrf
*)args
->list_entry
;
1105 if (args
->list_entry
== NULL
) {
1106 vrfp
= RB_MIN(vrf_name_head
, &vrfs_by_name
);
1108 vrfp
= RB_NEXT(vrf_name_head
, vrfp
);
1114 static int lib_vrf_get_keys(struct nb_cb_get_keys_args
*args
)
1116 struct vrf
*vrfp
= (struct vrf
*)args
->list_entry
;
1118 args
->keys
->num
= 1;
1119 strlcpy(args
->keys
->key
[0], vrfp
->name
, sizeof(args
->keys
->key
[0]));
1124 static const void *lib_vrf_lookup_entry(struct nb_cb_lookup_entry_args
*args
)
1126 const char *vrfname
= args
->keys
->key
[0];
1128 struct vrf
*vrf
= vrf_lookup_by_name(vrfname
);
1134 * XPath: /frr-vrf:lib/vrf/id
1136 static struct yang_data
*
1137 lib_vrf_state_id_get_elem(struct nb_cb_get_elem_args
*args
)
1139 struct vrf
*vrfp
= (struct vrf
*)args
->list_entry
;
1141 return yang_data_new_uint32(args
->xpath
, vrfp
->vrf_id
);
1145 * XPath: /frr-vrf:lib/vrf/active
1147 static struct yang_data
*
1148 lib_vrf_state_active_get_elem(struct nb_cb_get_elem_args
*args
)
1150 struct vrf
*vrfp
= (struct vrf
*)args
->list_entry
;
1152 if (vrfp
->status
== VRF_ACTIVE
)
1153 return yang_data_new_bool(
1154 args
->xpath
, vrfp
->status
== VRF_ACTIVE
? true : false);
1159 /* clang-format off */
1160 const struct frr_yang_module_info frr_vrf_info
= {
1164 .xpath
= "/frr-vrf:lib/vrf",
1166 .create
= lib_vrf_create
,
1167 .destroy
= lib_vrf_destroy
,
1168 .get_next
= lib_vrf_get_next
,
1169 .get_keys
= lib_vrf_get_keys
,
1170 .lookup_entry
= lib_vrf_lookup_entry
,
1174 .xpath
= "/frr-vrf:lib/vrf/state/id",
1176 .get_elem
= lib_vrf_state_id_get_elem
,
1180 .xpath
= "/frr-vrf:lib/vrf/state/active",
1182 .get_elem
= lib_vrf_state_active_get_elem
,