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
34 #include "nexthop_group.h"
35 #include "lib_errors.h"
36 #include "northbound.h"
37 #include "northbound_cli.h"
39 /* default VRF name value used when VRF backend is not NETNS */
40 #define VRF_DEFAULT_NAME_INTERNAL "default"
42 DEFINE_MTYPE_STATIC(LIB
, VRF
, "VRF");
43 DEFINE_MTYPE_STATIC(LIB
, VRF_BITMAP
, "VRF bit-map");
45 DEFINE_QOBJ_TYPE(vrf
);
47 static __inline
int vrf_id_compare(const struct vrf
*, const struct vrf
*);
48 static __inline
int vrf_name_compare(const struct vrf
*, const struct vrf
*);
50 RB_GENERATE(vrf_id_head
, vrf
, id_entry
, vrf_id_compare
);
51 RB_GENERATE(vrf_name_head
, vrf
, name_entry
, vrf_name_compare
);
53 struct vrf_id_head vrfs_by_id
= RB_INITIALIZER(&vrfs_by_id
);
54 struct vrf_name_head vrfs_by_name
= RB_INITIALIZER(&vrfs_by_name
);
56 static int vrf_backend
;
57 static int vrf_backend_configured
;
58 static char vrf_default_name
[VRF_NAMSIZ
] = VRF_DEFAULT_NAME_INTERNAL
;
61 * Turn on/off debug code
64 static int debug_vrf
= 0;
66 /* Holding VRF hooks */
67 static struct vrf_master
{
68 int (*vrf_new_hook
)(struct vrf
*);
69 int (*vrf_delete_hook
)(struct vrf
*);
70 int (*vrf_enable_hook
)(struct vrf
*);
71 int (*vrf_disable_hook
)(struct vrf
*);
76 static int vrf_is_enabled(struct vrf
*vrf
);
78 /* VRF list existance check by name. */
79 struct vrf
*vrf_lookup_by_name(const char *name
)
82 strlcpy(vrf
.name
, name
, sizeof(vrf
.name
));
83 return (RB_FIND(vrf_name_head
, &vrfs_by_name
, &vrf
));
86 static __inline
int vrf_id_compare(const struct vrf
*a
, const struct vrf
*b
)
88 return (a
->vrf_id
- b
->vrf_id
);
91 static int vrf_name_compare(const struct vrf
*a
, const struct vrf
*b
)
93 return strcmp(a
->name
, b
->name
);
96 int vrf_switch_to_netns(vrf_id_t vrf_id
)
99 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
101 /* VRF is default VRF. silently ignore */
102 if (!vrf
|| vrf
->vrf_id
== VRF_DEFAULT
)
103 return 1; /* 1 = default */
104 /* VRF has no NETNS backend. silently ignore */
105 if (vrf
->data
.l
.netns_name
[0] == '\0')
106 return 2; /* 2 = no netns */
107 name
= ns_netns_pathname(NULL
, vrf
->data
.l
.netns_name
);
109 zlog_debug("VRF_SWITCH: %s(%u)", name
, vrf
->vrf_id
);
110 return ns_switch_to_netns(name
);
113 int vrf_switchback_to_initial(void)
115 int ret
= ns_switchback_to_initial();
117 if (ret
== 0 && debug_vrf
)
118 zlog_debug("VRF_SWITCHBACK");
122 /* Get a VRF. If not found, create one.
124 * name - The name of the vrf. May be NULL if unknown.
125 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
126 * Description: Please note that this routine can be called with just the name
129 struct vrf
*vrf_get(vrf_id_t vrf_id
, const char *name
)
131 struct vrf
*vrf
= NULL
;
134 /* Nothing to see, move along here */
135 if (!name
&& vrf_id
== VRF_UNKNOWN
)
138 /* attempt to find already available VRF
141 vrf
= vrf_lookup_by_name(name
);
142 if (vrf
&& vrf_id
!= VRF_UNKNOWN
143 && vrf
->vrf_id
!= VRF_UNKNOWN
144 && vrf
->vrf_id
!= vrf_id
) {
145 zlog_debug("VRF_GET: avoid %s creation(%u), same name exists (%u)",
146 name
, vrf_id
, vrf
->vrf_id
);
149 /* Try to find VRF both by ID and name */
150 if (!vrf
&& vrf_id
!= VRF_UNKNOWN
)
151 vrf
= vrf_lookup_by_id(vrf_id
);
154 vrf
= XCALLOC(MTYPE_VRF
, sizeof(struct vrf
));
155 vrf
->vrf_id
= VRF_UNKNOWN
;
160 zlog_debug("VRF(%u) %s is created.", vrf_id
,
161 (name
) ? name
: "(NULL)");
165 if (vrf_id
!= VRF_UNKNOWN
&& vrf
->vrf_id
== VRF_UNKNOWN
) {
166 vrf
->vrf_id
= vrf_id
;
167 RB_INSERT(vrf_id_head
, &vrfs_by_id
, vrf
);
171 if (name
&& vrf
->name
[0] != '\0' && strcmp(name
, vrf
->name
)) {
172 /* update the vrf name */
173 RB_REMOVE(vrf_name_head
, &vrfs_by_name
, vrf
);
174 strlcpy(vrf
->data
.l
.netns_name
,
176 strlcpy(vrf
->name
, name
, sizeof(vrf
->name
));
177 RB_INSERT(vrf_name_head
, &vrfs_by_name
, vrf
);
178 } else if (name
&& vrf
->name
[0] == '\0') {
179 strlcpy(vrf
->name
, name
, sizeof(vrf
->name
));
180 RB_INSERT(vrf_name_head
, &vrfs_by_name
, vrf
);
182 if (new &&vrf_master
.vrf_new_hook
)
183 (*vrf_master
.vrf_new_hook
)(vrf
);
188 /* Update a VRF. If not found, create one.
190 * name - The name of the vrf.
191 * vrf_id - The vrf_id of the vrf.
192 * Description: This function first finds the vrf using its name. If the vrf is
193 * found and the vrf-id of the existing vrf does not match the new vrf id, it
194 * will disable the existing vrf and update it with new vrf-id. If the vrf is
195 * not found, it will create the vrf with given name and the new vrf id.
197 struct vrf
*vrf_update(vrf_id_t new_vrf_id
, const char *name
)
199 struct vrf
*vrf
= NULL
;
201 /*Treat VRF add for existing vrf as update
202 * Update VRF ID and also update in VRF ID table
205 vrf
= vrf_lookup_by_name(name
);
206 if (vrf
&& new_vrf_id
!= VRF_UNKNOWN
&& vrf
->vrf_id
!= VRF_UNKNOWN
207 && vrf
->vrf_id
!= new_vrf_id
) {
210 "Vrf Update event: %s old id: %u, new id: %u",
211 name
, vrf
->vrf_id
, new_vrf_id
);
214 /*Disable the vrf to simulate implicit delete
215 * so that all stale routes are deleted
216 * This vrf will be enabled down the line
221 RB_REMOVE(vrf_id_head
, &vrfs_by_id
, vrf
);
222 vrf
->vrf_id
= new_vrf_id
;
223 RB_INSERT(vrf_id_head
, &vrfs_by_id
, vrf
);
228 * vrf_get is implied creation if it does not exist
230 vrf
= vrf_get(new_vrf_id
, name
);
235 /* Delete a VRF. This is called when the underlying VRF goes away, a
236 * pre-configured VRF is deleted or when shutting down (vrf_terminate()).
238 void vrf_delete(struct vrf
*vrf
)
241 zlog_debug("VRF %s(%u) is to be deleted.", vrf
->name
,
244 if (vrf_is_enabled(vrf
))
247 if (vrf
->vrf_id
!= VRF_UNKNOWN
) {
248 RB_REMOVE(vrf_id_head
, &vrfs_by_id
, vrf
);
249 vrf
->vrf_id
= VRF_UNKNOWN
;
252 /* If the VRF is user configured, it'll stick around, just remove
253 * the ID mapping. Interfaces assigned to this VRF should've been
254 * removed already as part of the VRF going down.
256 if (vrf_is_user_cfged(vrf
))
259 /* Do not delete the VRF if it has interfaces configured in it. */
260 if (!RB_EMPTY(if_name_head
, &vrf
->ifaces_by_name
))
263 if (vrf_master
.vrf_delete_hook
)
264 (*vrf_master
.vrf_delete_hook
)(vrf
);
268 if (vrf
->name
[0] != '\0')
269 RB_REMOVE(vrf_name_head
, &vrfs_by_name
, vrf
);
271 XFREE(MTYPE_VRF
, vrf
);
274 /* Look up a VRF by identifier. */
275 struct vrf
*vrf_lookup_by_id(vrf_id_t vrf_id
)
279 return (RB_FIND(vrf_id_head
, &vrfs_by_id
, &vrf
));
283 * Enable a VRF - that is, let the VRF be ready to use.
284 * The VRF_ENABLE_HOOK callback will be called to inform
285 * that they can allocate resources in this VRF.
287 * RETURN: 1 - enabled successfully; otherwise, 0.
289 int vrf_enable(struct vrf
*vrf
)
291 if (vrf_is_enabled(vrf
))
295 zlog_debug("VRF %s(%u) is enabled.", vrf
->name
, vrf
->vrf_id
);
297 SET_FLAG(vrf
->status
, VRF_ACTIVE
);
299 if (vrf_master
.vrf_enable_hook
)
300 (*vrf_master
.vrf_enable_hook
)(vrf
);
303 * If we have any nexthop group entries that
304 * are awaiting vrf initialization then
305 * let's let people know about it
307 nexthop_group_enable_vrf(vrf
);
313 * Disable a VRF - that is, let the VRF be unusable.
314 * The VRF_DELETE_HOOK callback will be called to inform
315 * that they must release the resources in the VRF.
317 void vrf_disable(struct vrf
*vrf
)
319 if (!vrf_is_enabled(vrf
))
322 UNSET_FLAG(vrf
->status
, VRF_ACTIVE
);
325 zlog_debug("VRF %s(%u) is to be disabled.", vrf
->name
,
328 /* Till now, nothing to be done for the default VRF. */
329 // Pending: see why this statement.
333 * When the vrf is disabled let's
334 * handle all nexthop-groups associated
337 nexthop_group_disable_vrf(vrf
);
339 if (vrf_master
.vrf_disable_hook
)
340 (*vrf_master
.vrf_disable_hook
)(vrf
);
343 const char *vrf_id_to_name(vrf_id_t vrf_id
)
347 if (vrf_id
== VRF_DEFAULT
)
348 return VRF_DEFAULT_NAME
;
350 vrf
= vrf_lookup_by_id(vrf_id
);
351 return VRF_LOGNAME(vrf
);
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
*))
489 struct vrf
*default_vrf
;
491 /* initialise NS, in case VRF backend if NETNS */
494 zlog_debug("%s: Initializing VRF subsystem", __func__
);
496 vrf_master
.vrf_new_hook
= create
;
497 vrf_master
.vrf_enable_hook
= enable
;
498 vrf_master
.vrf_disable_hook
= disable
;
499 vrf_master
.vrf_delete_hook
= destroy
;
501 /* The default VRF always exists. */
502 default_vrf
= vrf_get(VRF_DEFAULT
, VRF_DEFAULT_NAME
);
504 flog_err(EC_LIB_VRF_START
,
505 "vrf_init: failed to create the default VRF!");
508 if (vrf_is_backend_netns()) {
511 strlcpy(default_vrf
->data
.l
.netns_name
,
512 VRF_DEFAULT_NAME
, NS_NAMSIZ
);
513 ns
= ns_lookup(NS_DEFAULT
);
514 ns
->vrf_ctxt
= default_vrf
;
515 default_vrf
->ns_ctxt
= ns
;
518 /* Enable the default VRF. */
519 if (!vrf_enable(default_vrf
)) {
520 flog_err(EC_LIB_VRF_START
,
521 "vrf_init: failed to enable the default VRF!");
525 cmd_variable_handler_register(vrf_var_handlers
);
528 static void vrf_terminate_single(struct vrf
*vrf
)
530 /* Clear configured flag and invoke delete. */
531 UNSET_FLAG(vrf
->status
, VRF_CONFIGURED
);
536 /* Terminate VRF module. */
537 void vrf_terminate(void)
539 struct vrf
*vrf
, *tmp
;
542 zlog_debug("%s: Shutting down vrf subsystem", __func__
);
544 RB_FOREACH_SAFE (vrf
, vrf_id_head
, &vrfs_by_id
, tmp
) {
545 if (vrf
->vrf_id
== VRF_DEFAULT
)
548 vrf_terminate_single(vrf
);
551 RB_FOREACH_SAFE (vrf
, vrf_name_head
, &vrfs_by_name
, tmp
) {
552 if (vrf
->vrf_id
== VRF_DEFAULT
)
555 vrf_terminate_single(vrf
);
558 /* Finally terminate default VRF */
559 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
561 vrf_terminate_single(vrf
);
564 int vrf_socket(int domain
, int type
, int protocol
, vrf_id_t vrf_id
,
565 const char *interfacename
)
567 int ret
, save_errno
, ret2
;
569 ret
= vrf_switch_to_netns(vrf_id
);
571 flog_err_sys(EC_LIB_SOCKET
, "%s: Can't switch to VRF %u (%s)",
572 __func__
, vrf_id
, safe_strerror(errno
));
574 ret
= socket(domain
, type
, protocol
);
576 ret2
= vrf_switchback_to_initial();
578 flog_err_sys(EC_LIB_SOCKET
,
579 "%s: Can't switchback from VRF %u (%s)", __func__
,
580 vrf_id
, safe_strerror(errno
));
584 ret2
= vrf_bind(vrf_id
, ret
, interfacename
);
592 int vrf_is_backend_netns(void)
594 return (vrf_backend
== VRF_BACKEND_NETNS
);
597 int vrf_get_backend(void)
599 if (!vrf_backend_configured
)
600 return VRF_BACKEND_UNKNOWN
;
604 int vrf_configure_backend(enum vrf_backend_type backend
)
606 /* Work around issue in old gcc */
608 case VRF_BACKEND_UNKNOWN
:
609 case VRF_BACKEND_NETNS
:
610 case VRF_BACKEND_VRF_LITE
:
616 vrf_backend
= backend
;
617 vrf_backend_configured
= 1;
622 /* vrf CLI commands */
626 "Exit current mode and down to previous mode\n")
632 DEFUN_YANG_NOSH (vrf
,
635 "Select a VRF to configure\n"
639 const char *vrfname
= argv
[idx_name
]->arg
;
640 char xpath_list
[XPATH_MAXLEN
];
644 if (strlen(vrfname
) > VRF_NAMSIZ
) {
646 "%% VRF name %s invalid: length exceeds %d bytes\n",
647 vrfname
, VRF_NAMSIZ
);
648 return CMD_WARNING_CONFIG_FAILED
;
651 snprintf(xpath_list
, sizeof(xpath_list
), FRR_VRF_KEY_XPATH
, vrfname
);
653 nb_cli_enqueue_change(vty
, xpath_list
, NB_OP_CREATE
, NULL
);
654 ret
= nb_cli_apply_changes_clear_pending(vty
, xpath_list
);
655 if (ret
== CMD_SUCCESS
) {
656 VTY_PUSH_XPATH(VRF_NODE
, xpath_list
);
657 vrf
= vrf_lookup_by_name(vrfname
);
659 VTY_PUSH_CONTEXT(VRF_NODE
, vrf
);
669 "Delete a pseudo VRF's configuration\n"
672 const char *vrfname
= argv
[2]->arg
;
673 char xpath_list
[XPATH_MAXLEN
];
677 vrfp
= vrf_lookup_by_name(vrfname
);
682 if (CHECK_FLAG(vrfp
->status
, VRF_ACTIVE
)) {
683 vty_out(vty
, "%% Only inactive VRFs can be deleted\n");
684 return CMD_WARNING_CONFIG_FAILED
;
687 if (vrf_get_backend() == VRF_BACKEND_VRF_LITE
) {
689 * Remove the VRF interface config when removing the VRF.
691 snprintf(xpath_list
, sizeof(xpath_list
),
692 "/frr-interface:lib/interface[name='%s']", vrfname
);
693 nb_cli_enqueue_change(vty
, xpath_list
, NB_OP_DESTROY
, NULL
);
696 snprintf(xpath_list
, sizeof(xpath_list
), FRR_VRF_KEY_XPATH
, vrfname
);
698 nb_cli_enqueue_change(vty
, xpath_list
, NB_OP_DESTROY
, NULL
);
699 return nb_cli_apply_changes(vty
, NULL
);
703 static struct cmd_node vrf_node
= {
706 .parent_node
= CONFIG_NODE
,
707 .prompt
= "%s(config-vrf)# ",
711 * Debug CLI for vrf's
736 static int vrf_write_host(struct vty
*vty
)
739 vty_out(vty
, "debug vrf\n");
744 static int vrf_write_host(struct vty
*vty
);
745 static struct cmd_node vrf_debug_node
= {
747 .node
= VRF_DEBUG_NODE
,
749 .config_write
= vrf_write_host
,
752 void vrf_install_commands(void)
754 install_node(&vrf_debug_node
);
756 install_element(CONFIG_NODE
, &vrf_debug_cmd
);
757 install_element(ENABLE_NODE
, &vrf_debug_cmd
);
758 install_element(CONFIG_NODE
, &no_vrf_debug_cmd
);
759 install_element(ENABLE_NODE
, &no_vrf_debug_cmd
);
762 void vrf_cmd_init(int (*writefunc
)(struct vty
*vty
))
764 install_element(CONFIG_NODE
, &vrf_cmd
);
765 install_element(CONFIG_NODE
, &no_vrf_cmd
);
766 vrf_node
.config_write
= writefunc
;
767 install_node(&vrf_node
);
768 install_default(VRF_NODE
);
769 install_element(VRF_NODE
, &vrf_exit_cmd
);
772 void vrf_set_default_name(const char *default_name
)
774 snprintf(vrf_default_name
, VRF_NAMSIZ
, "%s", default_name
);
777 const char *vrf_get_default_name(void)
779 return vrf_default_name
;
782 int vrf_bind(vrf_id_t vrf_id
, int fd
, const char *ifname
)
785 struct interface
*ifp
;
791 if (vrf_id
== VRF_UNKNOWN
)
794 /* can't bind to a VRF that doesn't exist */
795 vrf
= vrf_lookup_by_id(vrf_id
);
796 if (!vrf_is_enabled(vrf
))
799 if (ifname
&& strcmp(ifname
, vrf
->name
)) {
800 /* binding to a regular interface */
802 /* can't bind to an interface that doesn't exist */
803 ifp
= if_lookup_by_name(ifname
, vrf_id
);
807 /* binding to a VRF device */
809 /* nothing to do for netns */
810 if (vrf_is_backend_netns())
813 /* nothing to do for default vrf */
814 if (vrf_id
== VRF_DEFAULT
)
820 #ifdef SO_BINDTODEVICE
821 ret
= setsockopt(fd
, SOL_SOCKET
, SO_BINDTODEVICE
, ifname
,
824 zlog_err("bind to interface %s failed, errno=%d", ifname
,
826 #endif /* SO_BINDTODEVICE */
829 int vrf_getaddrinfo(const char *node
, const char *service
,
830 const struct addrinfo
*hints
, struct addrinfo
**res
,
833 int ret
, ret2
, save_errno
;
835 ret
= vrf_switch_to_netns(vrf_id
);
837 flog_err_sys(EC_LIB_SOCKET
, "%s: Can't switch to VRF %u (%s)",
838 __func__
, vrf_id
, safe_strerror(errno
));
839 ret
= getaddrinfo(node
, service
, hints
, res
);
841 ret2
= vrf_switchback_to_initial();
843 flog_err_sys(EC_LIB_SOCKET
,
844 "%s: Can't switchback from VRF %u (%s)", __func__
,
845 vrf_id
, safe_strerror(errno
));
850 int vrf_ioctl(vrf_id_t vrf_id
, int d
, unsigned long request
, char *params
)
852 int ret
, saved_errno
, rc
;
854 ret
= vrf_switch_to_netns(vrf_id
);
856 flog_err_sys(EC_LIB_SOCKET
, "%s: Can't switch to VRF %u (%s)",
857 __func__
, vrf_id
, safe_strerror(errno
));
860 rc
= ioctl(d
, request
, params
);
862 ret
= vrf_switchback_to_initial();
864 flog_err_sys(EC_LIB_SOCKET
,
865 "%s: Can't switchback from VRF %u (%s)", __func__
,
866 vrf_id
, safe_strerror(errno
));
871 int vrf_sockunion_socket(const union sockunion
*su
, vrf_id_t vrf_id
,
872 const char *interfacename
)
874 int ret
, save_errno
, ret2
;
876 ret
= vrf_switch_to_netns(vrf_id
);
878 flog_err_sys(EC_LIB_SOCKET
, "%s: Can't switch to VRF %u (%s)",
879 __func__
, vrf_id
, safe_strerror(errno
));
880 ret
= sockunion_socket(su
);
882 ret2
= vrf_switchback_to_initial();
884 flog_err_sys(EC_LIB_SOCKET
,
885 "%s: Can't switchback from VRF %u (%s)", __func__
,
886 vrf_id
, safe_strerror(errno
));
891 ret2
= vrf_bind(vrf_id
, ret
, interfacename
);
899 /* ------- Northbound callbacks ------- */
902 * XPath: /frr-vrf:lib/vrf
904 static int lib_vrf_create(struct nb_cb_create_args
*args
)
909 vrfname
= yang_dnode_get_string(args
->dnode
, "./name");
911 if (args
->event
!= NB_EV_APPLY
)
914 vrfp
= vrf_get(VRF_UNKNOWN
, vrfname
);
916 SET_FLAG(vrfp
->status
, VRF_CONFIGURED
);
917 nb_running_set_entry(args
->dnode
, vrfp
);
922 static int lib_vrf_destroy(struct nb_cb_destroy_args
*args
)
926 switch (args
->event
) {
928 vrfp
= nb_running_get_entry(args
->dnode
, NULL
, true);
929 if (CHECK_FLAG(vrfp
->status
, VRF_ACTIVE
)) {
930 snprintf(args
->errmsg
, args
->errmsg_len
,
931 "Only inactive VRFs can be deleted");
932 return NB_ERR_VALIDATION
;
939 vrfp
= nb_running_unset_entry(args
->dnode
);
941 /* Clear configured flag and invoke delete. */
942 UNSET_FLAG(vrfp
->status
, VRF_CONFIGURED
);
950 static const void *lib_vrf_get_next(struct nb_cb_get_next_args
*args
)
952 struct vrf
*vrfp
= (struct vrf
*)args
->list_entry
;
954 if (args
->list_entry
== NULL
) {
955 vrfp
= RB_MIN(vrf_name_head
, &vrfs_by_name
);
957 vrfp
= RB_NEXT(vrf_name_head
, vrfp
);
963 static int lib_vrf_get_keys(struct nb_cb_get_keys_args
*args
)
965 struct vrf
*vrfp
= (struct vrf
*)args
->list_entry
;
968 strlcpy(args
->keys
->key
[0], vrfp
->name
, sizeof(args
->keys
->key
[0]));
973 static const void *lib_vrf_lookup_entry(struct nb_cb_lookup_entry_args
*args
)
975 const char *vrfname
= args
->keys
->key
[0];
977 struct vrf
*vrf
= vrf_lookup_by_name(vrfname
);
983 * XPath: /frr-vrf:lib/vrf/id
985 static struct yang_data
*
986 lib_vrf_state_id_get_elem(struct nb_cb_get_elem_args
*args
)
988 struct vrf
*vrfp
= (struct vrf
*)args
->list_entry
;
990 return yang_data_new_uint32(args
->xpath
, vrfp
->vrf_id
);
994 * XPath: /frr-vrf:lib/vrf/active
996 static struct yang_data
*
997 lib_vrf_state_active_get_elem(struct nb_cb_get_elem_args
*args
)
999 struct vrf
*vrfp
= (struct vrf
*)args
->list_entry
;
1001 if (vrfp
->status
== VRF_ACTIVE
)
1002 return yang_data_new_bool(
1003 args
->xpath
, vrfp
->status
== VRF_ACTIVE
? true : false);
1008 /* clang-format off */
1009 const struct frr_yang_module_info frr_vrf_info
= {
1013 .xpath
= "/frr-vrf:lib/vrf",
1015 .create
= lib_vrf_create
,
1016 .destroy
= lib_vrf_destroy
,
1017 .get_next
= lib_vrf_get_next
,
1018 .get_keys
= lib_vrf_get_keys
,
1019 .lookup_entry
= lib_vrf_lookup_entry
,
1021 .priority
= NB_DFLT_PRIORITY
- 2,
1024 .xpath
= "/frr-vrf:lib/vrf/state/id",
1026 .get_elem
= lib_vrf_state_id_get_elem
,
1030 .xpath
= "/frr-vrf:lib/vrf/state/active",
1032 .get_elem
= lib_vrf_state_active_get_elem
,