summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_main.c9
-rw-r--r--bgpd/bgp_vty.c114
-rw-r--r--bgpd/bgpd.c6
-rw-r--r--doc/user/zebra.rst41
-rw-r--r--eigrpd/eigrp_main.c2
-rw-r--r--isisd/isis_main.c2
-rw-r--r--ldpd/ldpd.c2
-rw-r--r--lib/vrf.c59
-rw-r--r--lib/vrf.h12
-rw-r--r--lib/zclient.c3
-rw-r--r--nhrpd/nhrp_main.c2
-rw-r--r--ospf6d/ospf6_main.c2
-rw-r--r--ospfd/ospf_vty.c2
-rw-r--r--ospfd/ospfd.c13
-rw-r--r--pbrd/pbr_main.c2
-rw-r--r--pimd/pim_instance.c3
-rw-r--r--ripd/rip_main.c2
-rw-r--r--ripngd/ripng_main.c2
-rw-r--r--sharpd/sharp_main.c2
-rw-r--r--staticd/static_vrf.c2
-rw-r--r--tests/bgpd/test_capability.c2
-rw-r--r--tests/bgpd/test_mp_attr.c2
-rw-r--r--tests/bgpd/test_mpath.c2
-rw-r--r--tests/bgpd/test_packet.c2
-rw-r--r--tests/bgpd/test_peer_attr.c2
-rw-r--r--zebra/main.c7
-rw-r--r--zebra/zebra_netns_notify.c50
-rw-r--r--zebra/zebra_vrf.c15
28 files changed, 292 insertions, 72 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 138788194d..e0834604b2 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -266,6 +266,12 @@ static int bgp_vrf_enable(struct vrf *vrf)
bgp = bgp_lookup_by_name(vrf->name);
if (bgp) {
+ if (bgp->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) {
+ XFREE(MTYPE_BGP, bgp->name);
+ bgp->name = NULL;
+ XFREE(MTYPE_BGP, bgp->name_pretty);
+ bgp->name_pretty = XSTRDUP(MTYPE_BGP, "VRF default");
+ }
old_vrf_id = bgp->vrf_id;
/* We have instance configured, link to VRF and make it "up". */
bgp_vrf_link(bgp, vrf);
@@ -332,7 +338,8 @@ static int bgp_vrf_disable(struct vrf *vrf)
static void bgp_vrf_init(void)
{
- vrf_init(bgp_vrf_new, bgp_vrf_enable, bgp_vrf_disable, bgp_vrf_delete);
+ vrf_init(bgp_vrf_new, bgp_vrf_enable, bgp_vrf_disable,
+ bgp_vrf_delete, NULL);
}
static void bgp_vrf_terminate(void)
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 1460a26215..99c6f39230 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -312,10 +312,14 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
if (argv_find(argv, argc, "ip", idx))
*afi = AFI_IP;
- if (argv_find(argv, argc, "view", idx)
- || argv_find(argv, argc, "vrf", idx)) {
+ if (argv_find(argv, argc, "view", idx))
vrf_name = argv[*idx + 1]->arg;
-
+ else if (argv_find(argv, argc, "vrf", idx)) {
+ vrf_name = argv[*idx + 1]->arg;
+ if (strmatch(vrf_name, VRF_DEFAULT_NAME))
+ vrf_name = NULL;
+ }
+ if (vrf_name) {
if (strmatch(vrf_name, "all"))
*bgp = NULL;
else {
@@ -910,9 +914,12 @@ DEFUN_NOSH (router_bgp,
if (argc > 3) {
name = argv[idx_vrf]->arg;
- if (!strcmp(argv[idx_view_vrf]->text, "vrf"))
- inst_type = BGP_INSTANCE_TYPE_VRF;
- else if (!strcmp(argv[idx_view_vrf]->text, "view"))
+ if (!strcmp(argv[idx_view_vrf]->text, "vrf")) {
+ if (strmatch(name, VRF_DEFAULT_NAME))
+ name = NULL;
+ else
+ inst_type = BGP_INSTANCE_TYPE_VRF;
+ } else if (!strcmp(argv[idx_view_vrf]->text, "view"))
inst_type = BGP_INSTANCE_TYPE_VIEW;
}
@@ -7144,13 +7151,17 @@ DEFUN (clear_ip_bgp_all,
if (argv_find(argv, argc, "ip", &idx))
afi = AFI_IP;
- /* [<view|vrf> VIEWVRFNAME] */
- if (argv_find(argv, argc, "view", &idx)
- || argv_find(argv, argc, "vrf", &idx)) {
+ /* [<vrf> VIEWVRFNAME] */
+ if (argv_find(argv, argc, "vrf", &idx)) {
+ vrf = argv[idx + 1]->arg;
+ idx += 2;
+ if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+ vrf = NULL;
+ } else if (argv_find(argv, argc, "view", &idx)) {
+ /* [<view> VIEWVRFNAME] */
vrf = argv[idx + 1]->arg;
idx += 2;
}
-
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
if (argv_find_and_parse_afi(argv, argc, &idx, &afi))
argv_find_and_parse_safi(argv, argc, &idx, &safi);
@@ -7215,8 +7226,16 @@ DEFUN (clear_ip_bgp_prefix,
int idx = 0;
/* [<view|vrf> VIEWVRFNAME] */
- if (argv_find(argv, argc, "VIEWVRFNAME", &idx))
- vrf = argv[idx]->arg;
+ if (argv_find(argv, argc, "vrf", &idx)) {
+ vrf = argv[idx + 1]->arg;
+ idx += 2;
+ if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+ vrf = NULL;
+ } else if (argv_find(argv, argc, "view", &idx)) {
+ /* [<view> VIEWVRFNAME] */
+ vrf = argv[idx + 1]->arg;
+ idx += 2;
+ }
prefix = argv[argc - 1]->arg;
@@ -7258,16 +7277,23 @@ DEFUN (clear_bgp_instance_ipv6_safi_prefix,
"Clear bestpath and re-advertise\n"
"IPv6 prefix\n")
{
- int idx_word = 3;
int idx_safi = 0;
+ int idx_vrfview = 0;
int idx_ipv6_prefix = 0;
safi_t safi = SAFI_UNICAST;
char *prefix = argv_find(argv, argc, "X:X::X:X/M", &idx_ipv6_prefix) ?
argv[idx_ipv6_prefix]->arg : NULL;
- /* [<view|vrf> VIEWVRFNAME] */
- char *vrfview = argv_find(argv, argc, "VIEWVRFNAME", &idx_word) ?
- argv[idx_word]->arg : NULL;
+ char *vrfview = NULL;
+ /* [<view|vrf> VIEWVRFNAME] */
+ if (argv_find(argv, argc, "vrf", &idx_vrfview)) {
+ vrfview = argv[idx_vrfview + 1]->arg;
+ if (vrfview && strmatch(vrfview, VRF_DEFAULT_NAME))
+ vrfview = NULL;
+ } else if (argv_find(argv, argc, "view", &idx_vrfview)) {
+ /* [<view> VIEWVRFNAME] */
+ vrfview = argv[idx_vrfview + 1]->arg;
+ }
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
return bgp_clear_prefix(
@@ -7458,10 +7484,18 @@ DEFUN(show_bgp_martian_nexthop_db, show_bgp_martian_nexthop_db_cmd,
{
struct bgp *bgp = NULL;
int idx = 0;
-
- if (argv_find(argv, argc, "view", &idx)
- || argv_find(argv, argc, "vrf", &idx))
- bgp = bgp_lookup_by_name(argv[idx + 1]->arg);
+ char *name = NULL;
+
+ /* [<vrf> VIEWVRFNAME] */
+ if (argv_find(argv, argc, "vrf", &idx)) {
+ name = argv[idx + 1]->arg;
+ if (name && strmatch(name, VRF_DEFAULT_NAME))
+ name = NULL;
+ } else if (argv_find(argv, argc, "view", &idx))
+ /* [<view> VIEWVRFNAME] */
+ name = argv[idx + 1]->arg;
+ if (name)
+ bgp = bgp_lookup_by_name(name);
else
bgp = bgp_get_default();
@@ -8211,10 +8245,14 @@ DEFUN (show_ip_bgp_summary,
/* show [ip] bgp */
if (argv_find(argv, argc, "ip", &idx))
afi = AFI_IP;
- /* [<view|vrf> VIEWVRFNAME] */
- if (argv_find(argv, argc, "view", &idx)
- || argv_find(argv, argc, "vrf", &idx))
- vrf = argv[++idx]->arg;
+ /* [<vrf> VIEWVRFNAME] */
+ if (argv_find(argv, argc, "vrf", &idx)) {
+ vrf = argv[idx + 1]->arg;
+ if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+ vrf = NULL;
+ } else if (argv_find(argv, argc, "view", &idx))
+ /* [<view> VIEWVRFNAME] */
+ vrf = argv[idx + 1]->arg;
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
argv_find_and_parse_safi(argv, argc, &idx, &safi);
@@ -10888,8 +10926,13 @@ DEFUN (show_ip_bgp_neighbors,
int idx = 0;
- if (argv_find(argv, argc, "view", &idx)
- || argv_find(argv, argc, "vrf", &idx))
+ /* [<vrf> VIEWVRFNAME] */
+ if (argv_find(argv, argc, "vrf", &idx)) {
+ vrf = argv[idx + 1]->arg;
+ if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+ vrf = NULL;
+ } else if (argv_find(argv, argc, "view", &idx))
+ /* [<view> VIEWVRFNAME] */
vrf = argv[idx + 1]->arg;
idx++;
@@ -11183,8 +11226,11 @@ DEFUN (show_ip_bgp_route_leak,
return CMD_WARNING;
}
- if (argv_find(argv, argc, "vrf", &idx))
- vrf = argv[++idx]->arg;
+ if (argv_find(argv, argc, "vrf", &idx)) {
+ vrf = argv[idx + 1]->arg;
+ if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+ vrf = NULL;
+ }
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
argv_find_and_parse_safi(argv, argc, &idx, &safi);
@@ -11257,10 +11303,14 @@ DEFUN (show_ip_bgp_updgrps,
/* show [ip] bgp */
if (argv_find(argv, argc, "ip", &idx))
afi = AFI_IP;
- /* [<view|vrf> VIEWVRFNAME] */
- if (argv_find(argv, argc, "view", &idx)
- || argv_find(argv, argc, "vrf", &idx))
- vrf = argv[++idx]->arg;
+ /* [<vrf> VIEWVRFNAME] */
+ if (argv_find(argv, argc, "vrf", &idx)) {
+ vrf = argv[idx + 1]->arg;
+ if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+ vrf = NULL;
+ } else if (argv_find(argv, argc, "view", &idx))
+ /* [<view> VIEWVRFNAME] */
+ vrf = argv[idx + 1]->arg;
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
argv_find_and_parse_safi(argv, argc, &idx, &safi);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 7ff5053ce3..5d258a765b 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -7735,10 +7735,8 @@ static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
struct listnode *next;
struct bgp *bgp;
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (vrf->vrf_id != VRF_DEFAULT)
- vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
- }
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index af8e4b8d47..85f2a7af3e 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -48,6 +48,13 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
.. seealso:: :ref:`zebra-vrf`
+.. option:: -o, --vrfdefaultname
+
+ When *Zebra* starts with this option, the default VRF name is changed to the
+ parameter.
+
+ .. seealso:: :ref:`zebra-vrf`
+
.. option:: --v6-rr-semantics
The linux kernel is receiving the ability to use the same route
@@ -355,6 +362,40 @@ commands in relationship to VRF. Here is an extract of some of those commands:
will dump the routing table ``TABLENO`` of the *Linux network namespace*
``VRF``.
+By using the :option:`-n` option, the *Linux network namespace* will be mapped
+over the *Zebra* VRF. One nice feature that is possible by handling *Linux
+network namespace* is the ability to name default VRF. At startup, *Zebra*
+discovers the available *Linux network namespace* by parsing folder
+`/var/run/netns`. Each file stands for a *Linux network namespace*, but not all
+*Linux network namespaces* are available under that folder. This is the case for
+default VRF. It is possible to name the default VRF, by creating a file, by
+executing following commands.
+
+.. code-block:: shell
+
+ touch /var/run/netns/vrf0
+ mount --bind /proc/self/ns/net /var/run/netns/vrf0
+
+Above command illustrates what happens when the default VRF is visible under
+`var/run/netns/`. Here, the default VRF file is `vrf0`.
+At startup, FRR detects the presence of that file. It detects that the file
+statistics information matches the same file statistics information as
+`/proc/self/ns/net` ( through stat() function). As statistics information
+matches, then `vrf0` stands for the new default namespace name.
+Consequently, the VRF naming `Default` will be overriden by the new discovered
+namespace name `vrf0`.
+
+For those who don't use VRF backend with *Linux network namespace*, it is
+possible to statically configure and recompile FRR. It is possible to choose an
+alternate name for default VRF. Then, the default VRF naming will automatically
+be updated with the new name. To illustrate, if you want to recompile with
+`global` value, use the following command:
+
+.. code-block:: linux
+
+ ./configure --with-defaultvrfname=global
+
+More information about the option in :ref:`_frr-configuration`.
.. _zebra-mpls:
diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c
index 31101a52d4..9e9c4649fc 100644
--- a/eigrpd/eigrp_main.c
+++ b/eigrpd/eigrp_main.c
@@ -170,7 +170,7 @@ int main(int argc, char **argv, char **envp)
master = eigrp_om->master;
eigrp_error_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
/*EIGRPd init*/
eigrp_if_init();
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index 5b18ab0a2c..3b4168adb9 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -192,7 +192,7 @@ int main(int argc, char **argv, char **envp)
*/
isis_error_init();
access_list_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
prefix_list_init();
isis_init();
isis_circuit_init();
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index e830263ded..935e959596 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -330,7 +330,7 @@ main(int argc, char *argv[])
master = frr_init();
vty_config_lockless();
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
access_list_init();
ldp_vty_init();
ldp_zebra_init(master);
diff --git a/lib/vrf.c b/lib/vrf.c
index ecd09a6b91..1fb1b786c7 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -39,6 +39,7 @@
/* default VRF ID value used when VRF backend is not NETNS */
#define VRF_DEFAULT_INTERNAL 0
+#define VRF_DEFAULT_NAME_INTERNAL "default"
DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
@@ -56,6 +57,7 @@ struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name);
static int vrf_backend;
static struct zebra_privs_t *vrf_daemon_privs;
+static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL;
/*
* Turn on/off debug code
@@ -69,6 +71,7 @@ struct vrf_master {
int (*vrf_delete_hook)(struct vrf *);
int (*vrf_enable_hook)(struct vrf *);
int (*vrf_disable_hook)(struct vrf *);
+ int (*vrf_update_name_hook)(struct vrf *vrf);
} vrf_master = {
0,
};
@@ -165,6 +168,13 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name)
*/
if (name)
vrf = vrf_lookup_by_name(name);
+ if (vrf && vrf_id != VRF_UNKNOWN
+ && vrf->vrf_id != VRF_UNKNOWN
+ && vrf->vrf_id != vrf_id) {
+ zlog_debug("VRF_GET: avoid %s creation(%u), same name exists (%u)",
+ name, vrf_id, vrf->vrf_id);
+ return NULL;
+ }
/* Try to find VRF both by ID and name */
if (!vrf && vrf_id != VRF_UNKNOWN)
vrf = vrf_lookup_by_id(vrf_id);
@@ -445,10 +455,8 @@ static void vrf_autocomplete(vector comps, struct cmd_token *token)
{
struct vrf *vrf = NULL;
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (vrf->vrf_id != VRF_DEFAULT)
- vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
- }
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
}
static const struct cmd_variable_handler vrf_var_handlers[] = {
@@ -461,7 +469,8 @@ static const struct cmd_variable_handler vrf_var_handlers[] = {
/* Initialize VRF module. */
void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
- int (*disable)(struct vrf *), int (*delete)(struct vrf *))
+ int (*disable)(struct vrf *), int (*delete)(struct vrf *),
+ int ((*update)(struct vrf *)))
{
struct vrf *default_vrf;
@@ -475,6 +484,7 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
vrf_master.vrf_enable_hook = enable;
vrf_master.vrf_disable_hook = disable;
vrf_master.vrf_delete_hook = delete;
+ vrf_master.vrf_update_name_hook = update;
/* The default VRF always exists. */
default_vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
@@ -483,6 +493,9 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
"vrf_init: failed to create the default VRF!");
exit(1);
}
+ if (vrf_is_backend_netns())
+ strlcpy(default_vrf->data.l.netns_name,
+ VRF_DEFAULT_NAME, NS_NAMSIZ);
/* Enable the default VRF. */
if (!vrf_enable(default_vrf)) {
@@ -876,12 +889,40 @@ void vrf_cmd_init(int (*writefunc)(struct vty *vty),
}
}
-vrf_id_t vrf_get_default_id(void)
+void vrf_set_default_name(const char *default_name)
{
- struct vrf *vrf = vrf_lookup_by_name(VRF_DEFAULT_NAME);
+ struct vrf *def_vrf;
+ struct vrf *vrf_with_default_name = NULL;
- if (vrf)
- return vrf->vrf_id;
+ def_vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ assert(default_name);
+ vrf_with_default_name = vrf_lookup_by_name(default_name);
+ if (vrf_with_default_name && vrf_with_default_name != def_vrf) {
+ /* vrf name already used by an other VRF */
+ zlog_debug("VRF: %s, avoid changing name to %s, same name exists (%u)",
+ vrf_with_default_name->name, default_name,
+ vrf_with_default_name->vrf_id);
+ return;
+ }
+ snprintf(vrf_default_name, VRF_NAMSIZ, "%s", default_name);
+ if (def_vrf) {
+ RB_REMOVE(vrf_name_head, &vrfs_by_name, def_vrf);
+ strlcpy(def_vrf->data.l.netns_name,
+ vrf_default_name, NS_NAMSIZ);
+ strlcpy(def_vrf->name, vrf_default_name, sizeof(def_vrf->name));
+ RB_INSERT(vrf_name_head, &vrfs_by_name, def_vrf);
+ if (vrf_master.vrf_update_name_hook)
+ (*vrf_master.vrf_update_name_hook)(def_vrf);
+ }
+}
+
+const char *vrf_get_default_name(void)
+{
+ return vrf_default_name;
+}
+
+vrf_id_t vrf_get_default_id(void)
+{
/* backend netns is only known by zebra
* for other daemons, we return VRF_DEFAULT_INTERNAL
*/
diff --git a/lib/vrf.h b/lib/vrf.h
index 56ba101ff0..c962ac4c69 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -41,8 +41,6 @@ enum { IFLA_VRF_UNSPEC, IFLA_VRF_TABLE, __IFLA_VRF_MAX };
#define VRF_NAMSIZ 36
#define NS_NAMSIZ 16
-#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
-
/*
* The command strings
*/
@@ -201,8 +199,10 @@ extern int vrf_bitmap_check(vrf_bitmap_t, vrf_id_t);
* delete -> Called back when a vrf is being deleted from
* the system ( 2 and 3 ) above.
*/
-extern void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
- int (*disable)(struct vrf *), int (*delete)(struct vrf *));
+extern void vrf_init(int (*create)(struct vrf *vrf), int (*enable)(struct vrf *vrf),
+ int (*disable)(struct vrf *vrf), int (*delete)(struct vrf *vrf),
+ int ((*update)(struct vrf *vrf)));
+
/*
* Call vrf_terminate when the protocol is being shutdown
*/
@@ -236,6 +236,10 @@ extern vrf_id_t vrf_get_default_id(void);
/* The default VRF ID */
#define VRF_DEFAULT vrf_get_default_id()
+extern void vrf_set_default_name(const char *default_name);
+extern const char *vrf_get_default_name(void);
+#define VRF_DEFAULT_NAME vrf_get_default_name()
+
/* VRF is mapped on netns or not ? */
int vrf_is_mapped_on_netns(struct vrf *vrf);
diff --git a/lib/zclient.c b/lib/zclient.c
index b2bafcb7d8..c5a48c178a 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1366,6 +1366,9 @@ static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
vrf = vrf_get(vrf_id, vrfname_tmp);
vrf->data.l.table_id = data.l.table_id;
memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
+ /* overwrite default vrf */
+ if (vrf_id == VRF_DEFAULT)
+ vrf_set_default_name(vrfname_tmp);
vrf_enable(vrf);
}
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c
index e9f44e8558..737e70103e 100644
--- a/nhrpd/nhrp_main.c
+++ b/nhrpd/nhrp_main.c
@@ -130,7 +130,7 @@ int main(int argc, char **argv)
/* Library inits. */
master = frr_init();
nhrp_error_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
nhrp_interface_init();
resolver_init();
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index 9580d87cf0..eadc856cac 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -208,7 +208,7 @@ int main(int argc, char *argv[], char *envp[])
/* thread master */
master = frr_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
access_list_init();
prefix_list_init();
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index fb9770d09a..39f14a00c3 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -145,6 +145,8 @@ static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty,
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
+ if (vrf_name == NULL || strmatch(vrf_name, VRF_DEFAULT_NAME))
+ vrf_name = NULL;
if (enable) {
/* Allocate VRF aware instance */
ospf = ospf_get(*instance, vrf_name);
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index bfaedf2fe7..d311b4da6b 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -234,12 +234,10 @@ static struct ospf *ospf_new(unsigned short instance, const char *name)
new->instance = instance;
new->router_id.s_addr = htonl(0);
new->router_id_static.s_addr = htonl(0);
-
- if (name) {
+ if (name && !strmatch(name, VRF_DEFAULT_NAME)) {
new->vrf_id = VRF_UNKNOWN;
/* Freed in ospf_finish_final */
new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
- vrf = vrf_lookup_by_name(new->name);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"%s: Create new ospf instance with vrf_name %s vrf_id %u",
@@ -381,6 +379,9 @@ struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name)
struct ospf *ospf = NULL;
struct listnode *node, *nnode;
+ if (name == NULL || strmatch(name, VRF_DEFAULT_NAME))
+ return ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
if ((ospf->instance == instance)
&& ((ospf->name == NULL && name == NULL)
@@ -2078,6 +2079,10 @@ static int ospf_vrf_enable(struct vrf *vrf)
ospf = ospf_lookup_by_name(vrf->name);
if (ospf) {
+ if (ospf->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) {
+ XFREE(MTYPE_OSPF_TOP, ospf->name);
+ ospf->name = NULL;
+ }
old_vrf_id = ospf->vrf_id;
/* We have instance configured, link to VRF and make it "up". */
ospf_vrf_link(ospf, vrf);
@@ -2149,7 +2154,7 @@ static int ospf_vrf_disable(struct vrf *vrf)
void ospf_vrf_init(void)
{
vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
- ospf_vrf_delete);
+ ospf_vrf_delete, NULL);
}
void ospf_vrf_terminate(void)
diff --git a/pbrd/pbr_main.c b/pbrd/pbr_main.c
index ba09621083..f555ccc056 100644
--- a/pbrd/pbr_main.c
+++ b/pbrd/pbr_main.c
@@ -146,7 +146,7 @@ int main(int argc, char **argv, char **envp)
pbr_debug_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
nexthop_group_init(pbr_nhgroup_add_cb,
pbr_nhgroup_add_nexthop_cb,
pbr_nhgroup_del_nexthop_cb,
diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c
index 8dc48cc004..bf8d05d1e1 100644
--- a/pimd/pim_instance.c
+++ b/pimd/pim_instance.c
@@ -196,7 +196,8 @@ static int pim_vrf_config_write(struct vty *vty)
void pim_vrf_init(void)
{
- vrf_init(pim_vrf_new, pim_vrf_enable, pim_vrf_disable, pim_vrf_delete);
+ vrf_init(pim_vrf_new, pim_vrf_enable, pim_vrf_disable,
+ pim_vrf_delete, NULL);
vrf_cmd_init(pim_vrf_config_write, &pimd_privs);
}
diff --git a/ripd/rip_main.c b/ripd/rip_main.c
index e5a5c3e227..16087c2349 100644
--- a/ripd/rip_main.c
+++ b/ripd/rip_main.c
@@ -170,7 +170,7 @@ int main(int argc, char **argv)
/* Library initialization. */
rip_error_init();
keychain_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
/* RIP related initialization. */
rip_init();
diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c
index e4501d6f80..bc81a956d6 100644
--- a/ripngd/ripng_main.c
+++ b/ripngd/ripng_main.c
@@ -166,7 +166,7 @@ int main(int argc, char **argv)
master = frr_init();
/* Library inits. */
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
/* RIPngd inits. */
ripng_init();
diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c
index f0e6e3db4a..65b1837f68 100644
--- a/sharpd/sharp_main.c
+++ b/sharpd/sharp_main.c
@@ -146,7 +146,7 @@ int main(int argc, char **argv, char **envp)
master = frr_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
access_list_init();
route_map_init();
diff --git a/staticd/static_vrf.c b/staticd/static_vrf.c
index 6946f21271..d33c1539c8 100644
--- a/staticd/static_vrf.c
+++ b/staticd/static_vrf.c
@@ -190,7 +190,7 @@ int static_vrf_has_config(struct static_vrf *svrf)
void static_vrf_init(void)
{
vrf_init(static_vrf_new, static_vrf_enable,
- static_vrf_disable, static_vrf_delete);
+ static_vrf_disable, static_vrf_delete, NULL);
vrf_cmd_init(static_vrf_config_write, &static_privs);
}
diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c
index fef7d39ff5..83af5e9c6d 100644
--- a/tests/bgpd/test_capability.c
+++ b/tests/bgpd/test_capability.c
@@ -913,7 +913,7 @@ int main(void)
qobj_init();
master = thread_master_create(NULL);
bgp_master_init(master);
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
bgp_pthreads_init();
diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c
index 8db1cb2ca1..603b678cf1 100644
--- a/tests/bgpd/test_mp_attr.c
+++ b/tests/bgpd/test_mp_attr.c
@@ -1079,7 +1079,7 @@ int main(void)
bgp_vty_init();
master = thread_master_create("test mp attr");
bgp_master_init(master);
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
bgp_attr_init();
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
index d8d2286bf7..42f7d76759 100644
--- a/tests/bgpd/test_mpath.c
+++ b/tests/bgpd/test_mpath.c
@@ -379,7 +379,7 @@ static int global_test_init(void)
master = thread_master_create(NULL);
zclient = zclient_new_notify(master, &zclient_options_default);
bgp_master_init(master);
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
if (fileno(stdout) >= 0)
diff --git a/tests/bgpd/test_packet.c b/tests/bgpd/test_packet.c
index c58a85eed3..9719aceec9 100644
--- a/tests/bgpd/test_packet.c
+++ b/tests/bgpd/test_packet.c
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
bgp_attr_init();
master = thread_master_create(NULL);
bgp_master_init(master);
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c
index 16bd5d96da..452245ec16 100644
--- a/tests/bgpd/test_peer_attr.c
+++ b/tests/bgpd/test_peer_attr.c
@@ -1387,7 +1387,7 @@ static void bgp_startup(void)
master = thread_master_create(NULL);
bgp_master_init(master);
bgp_option_set(BGP_OPT_NO_LISTEN);
- vrf_init(NULL, NULL, NULL, NULL);
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_init();
bgp_pthreads_run();
}
diff --git a/zebra/main.c b/zebra/main.c
index 5e7c69382f..8db1c48f22 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -99,6 +99,7 @@ struct option longopts[] = {
{"ecmp", required_argument, NULL, 'e'},
{"label_socket", no_argument, NULL, 'l'},
{"retain", no_argument, NULL, 'r'},
+ {"vrfdefaultname", required_argument, NULL, 'o'},
#ifdef HAVE_NETLINK
{"vrfwnetns", no_argument, NULL, 'n'},
{"nl-bufsize", required_argument, NULL, 's'},
@@ -235,7 +236,7 @@ int main(int argc, char **argv)
frr_preinit(&zebra_di, argc, argv);
frr_opt_add(
- "bakz:e:l:r"
+ "bakz:e:l:o:r"
#ifdef HAVE_NETLINK
"s:n"
#endif
@@ -254,6 +255,7 @@ int main(int argc, char **argv)
" -l, --label_socket Socket to external label manager\n"
" -k, --keep_kernel Don't delete old routes which were installed by zebra.\n"
" -r, --retain When program terminates, retain added route by zebra.\n"
+ " -o, --vrfdefaultname Set default VRF name.\n"
#ifdef HAVE_NETLINK
" -n, --vrfwnetns Use NetNS as VRF backend\n"
" -s, --nl-bufsize Set netlink receive buffer size\n"
@@ -296,6 +298,9 @@ int main(int argc, char **argv)
return 1;
}
break;
+ case 'o':
+ vrf_set_default_name(optarg);
+ break;
case 'z':
zserv_path = optarg;
if (!frr_zclient_addr(&dummy, &dummylen, optarg)) {
diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c
index 2b7bf04ec3..12207805d9 100644
--- a/zebra/zebra_netns_notify.c
+++ b/zebra/zebra_netns_notify.c
@@ -149,6 +149,41 @@ static int zebra_ns_delete(char *name)
return 0;
}
+static int zebra_ns_notify_self_identify(struct stat *netst)
+{
+ char net_path[64];
+ int netns;
+
+ sprintf(net_path, "/proc/self/ns/net");
+ netns = open(net_path, O_RDONLY);
+ if (netns < 0)
+ return -1;
+ if (fstat(netns, netst) < 0) {
+ close(netns);
+ return -1;
+ }
+ close(netns);
+ return 0;
+}
+
+static bool zebra_ns_notify_is_default_netns(const char *name)
+{
+ struct stat default_netns_stat;
+ struct stat st;
+ char netnspath[64];
+
+ if (zebra_ns_notify_self_identify(&default_netns_stat))
+ return false;
+
+ memset(&st, 0, sizeof(struct stat));
+ snprintf(netnspath, 64, "%s/%s", NS_RUN_DIR, name);
+ /* compare with local stat */
+ if (stat(netnspath, &st) == 0 &&
+ (st.st_dev == default_netns_stat.st_dev) &&
+ (st.st_ino == default_netns_stat.st_ino))
+ return true;
+ return false;
+}
static int zebra_ns_ready_read(struct thread *t)
{
@@ -178,6 +213,14 @@ static int zebra_ns_ready_read(struct thread *t)
if (err < 0)
return zebra_ns_continue_read(zns_info, stop_retry);
+ if (zebra_ns_notify_is_default_netns(basename(netnspath))) {
+ zlog_warn(
+ "NS notify : NS %s is default VRF."
+ " Updating VRF Name", basename(netnspath));
+ vrf_set_default_name(basename(netnspath));
+ return zebra_ns_continue_read(zns_info, 1);
+ }
+
/* success : close fd and create zns context */
zebra_ns_notify_create_context_from_entry_name(basename(netnspath));
return zebra_ns_continue_read(zns_info, 1);
@@ -259,6 +302,13 @@ void zebra_ns_notify_parse(void)
dent->d_name);
continue;
}
+ if (zebra_ns_notify_is_default_netns(dent->d_name)) {
+ zlog_warn(
+ "NS notify : NS %s is default VRF."
+ " Updating VRF Name", dent->d_name);
+ vrf_set_default_name(dent->d_name);
+ continue;
+ }
zebra_ns_notify_create_context_from_entry_name(dent->d_name);
}
closedir(srcdir);
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 05ae418b57..be8f879246 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -282,6 +282,19 @@ static int zebra_vrf_delete(struct vrf *vrf)
return 0;
}
+static int zebra_vrf_update(struct vrf *vrf)
+{
+ struct zebra_vrf *zvrf = vrf->info;
+
+ assert(zvrf);
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("VRF %s id %u, name updated", vrf->name,
+ zvrf_id(zvrf));
+ zebra_vrf_add_update(zvrf);
+ return 0;
+}
+
+
/* Return if this VRF has any FRR configuration or not.
* IMPORTANT: This function needs to be updated when additional configuration
* is added for a VRF.
@@ -491,7 +504,7 @@ static int vrf_config_write(struct vty *vty)
void zebra_vrf_init(void)
{
vrf_init(zebra_vrf_new, zebra_vrf_enable, zebra_vrf_disable,
- zebra_vrf_delete);
+ zebra_vrf_delete, zebra_vrf_update);
vrf_cmd_init(vrf_config_write, &zserv_privs);
}