mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-26 00:10:24 +00:00
Merge pull request #2337 from pguibert6WIND/netns_alias
default VRF naming update
This commit is contained in:
commit
efd1f138cc
@ -266,6 +266,12 @@ static int bgp_vrf_enable(struct vrf *vrf)
|
|||||||
|
|
||||||
bgp = bgp_lookup_by_name(vrf->name);
|
bgp = bgp_lookup_by_name(vrf->name);
|
||||||
if (bgp) {
|
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;
|
old_vrf_id = bgp->vrf_id;
|
||||||
/* We have instance configured, link to VRF and make it "up". */
|
/* We have instance configured, link to VRF and make it "up". */
|
||||||
bgp_vrf_link(bgp, vrf);
|
bgp_vrf_link(bgp, vrf);
|
||||||
@ -332,7 +338,8 @@ static int bgp_vrf_disable(struct vrf *vrf)
|
|||||||
|
|
||||||
static void bgp_vrf_init(void)
|
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)
|
static void bgp_vrf_terminate(void)
|
||||||
|
112
bgpd/bgp_vty.c
112
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))
|
if (argv_find(argv, argc, "ip", idx))
|
||||||
*afi = AFI_IP;
|
*afi = AFI_IP;
|
||||||
|
|
||||||
if (argv_find(argv, argc, "view", idx)
|
if (argv_find(argv, argc, "view", idx))
|
||||||
|| argv_find(argv, argc, "vrf", idx)) {
|
|
||||||
vrf_name = argv[*idx + 1]->arg;
|
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"))
|
if (strmatch(vrf_name, "all"))
|
||||||
*bgp = NULL;
|
*bgp = NULL;
|
||||||
else {
|
else {
|
||||||
@ -910,9 +914,12 @@ DEFUN_NOSH (router_bgp,
|
|||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
name = argv[idx_vrf]->arg;
|
name = argv[idx_vrf]->arg;
|
||||||
|
|
||||||
if (!strcmp(argv[idx_view_vrf]->text, "vrf"))
|
if (!strcmp(argv[idx_view_vrf]->text, "vrf")) {
|
||||||
inst_type = BGP_INSTANCE_TYPE_VRF;
|
if (strmatch(name, VRF_DEFAULT_NAME))
|
||||||
else if (!strcmp(argv[idx_view_vrf]->text, "view"))
|
name = NULL;
|
||||||
|
else
|
||||||
|
inst_type = BGP_INSTANCE_TYPE_VRF;
|
||||||
|
} else if (!strcmp(argv[idx_view_vrf]->text, "view"))
|
||||||
inst_type = BGP_INSTANCE_TYPE_VIEW;
|
inst_type = BGP_INSTANCE_TYPE_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7144,13 +7151,17 @@ DEFUN (clear_ip_bgp_all,
|
|||||||
if (argv_find(argv, argc, "ip", &idx))
|
if (argv_find(argv, argc, "ip", &idx))
|
||||||
afi = AFI_IP;
|
afi = AFI_IP;
|
||||||
|
|
||||||
/* [<view|vrf> VIEWVRFNAME] */
|
/* [<vrf> VIEWVRFNAME] */
|
||||||
if (argv_find(argv, argc, "view", &idx)
|
if (argv_find(argv, argc, "vrf", &idx)) {
|
||||||
|| 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;
|
vrf = argv[idx + 1]->arg;
|
||||||
idx += 2;
|
idx += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
|
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
|
||||||
if (argv_find_and_parse_afi(argv, argc, &idx, &afi))
|
if (argv_find_and_parse_afi(argv, argc, &idx, &afi))
|
||||||
argv_find_and_parse_safi(argv, argc, &idx, &safi);
|
argv_find_and_parse_safi(argv, argc, &idx, &safi);
|
||||||
@ -7215,8 +7226,16 @@ DEFUN (clear_ip_bgp_prefix,
|
|||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
/* [<view|vrf> VIEWVRFNAME] */
|
/* [<view|vrf> VIEWVRFNAME] */
|
||||||
if (argv_find(argv, argc, "VIEWVRFNAME", &idx))
|
if (argv_find(argv, argc, "vrf", &idx)) {
|
||||||
vrf = argv[idx]->arg;
|
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;
|
prefix = argv[argc - 1]->arg;
|
||||||
|
|
||||||
@ -7258,16 +7277,23 @@ DEFUN (clear_bgp_instance_ipv6_safi_prefix,
|
|||||||
"Clear bestpath and re-advertise\n"
|
"Clear bestpath and re-advertise\n"
|
||||||
"IPv6 prefix\n")
|
"IPv6 prefix\n")
|
||||||
{
|
{
|
||||||
int idx_word = 3;
|
|
||||||
int idx_safi = 0;
|
int idx_safi = 0;
|
||||||
|
int idx_vrfview = 0;
|
||||||
int idx_ipv6_prefix = 0;
|
int idx_ipv6_prefix = 0;
|
||||||
safi_t safi = SAFI_UNICAST;
|
safi_t safi = SAFI_UNICAST;
|
||||||
char *prefix = argv_find(argv, argc, "X:X::X:X/M", &idx_ipv6_prefix) ?
|
char *prefix = argv_find(argv, argc, "X:X::X:X/M", &idx_ipv6_prefix) ?
|
||||||
argv[idx_ipv6_prefix]->arg : NULL;
|
argv[idx_ipv6_prefix]->arg : NULL;
|
||||||
/* [<view|vrf> VIEWVRFNAME] */
|
char *vrfview = NULL;
|
||||||
char *vrfview = argv_find(argv, argc, "VIEWVRFNAME", &idx_word) ?
|
|
||||||
argv[idx_word]->arg : 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);
|
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
|
||||||
|
|
||||||
return bgp_clear_prefix(
|
return bgp_clear_prefix(
|
||||||
@ -7458,10 +7484,18 @@ DEFUN(show_bgp_martian_nexthop_db, show_bgp_martian_nexthop_db_cmd,
|
|||||||
{
|
{
|
||||||
struct bgp *bgp = NULL;
|
struct bgp *bgp = NULL;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
char *name = NULL;
|
||||||
|
|
||||||
if (argv_find(argv, argc, "view", &idx)
|
/* [<vrf> VIEWVRFNAME] */
|
||||||
|| argv_find(argv, argc, "vrf", &idx))
|
if (argv_find(argv, argc, "vrf", &idx)) {
|
||||||
bgp = bgp_lookup_by_name(argv[idx + 1]->arg);
|
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
|
else
|
||||||
bgp = bgp_get_default();
|
bgp = bgp_get_default();
|
||||||
|
|
||||||
@ -8211,10 +8245,14 @@ DEFUN (show_ip_bgp_summary,
|
|||||||
/* show [ip] bgp */
|
/* show [ip] bgp */
|
||||||
if (argv_find(argv, argc, "ip", &idx))
|
if (argv_find(argv, argc, "ip", &idx))
|
||||||
afi = AFI_IP;
|
afi = AFI_IP;
|
||||||
/* [<view|vrf> VIEWVRFNAME] */
|
/* [<vrf> VIEWVRFNAME] */
|
||||||
if (argv_find(argv, argc, "view", &idx)
|
if (argv_find(argv, argc, "vrf", &idx)) {
|
||||||
|| argv_find(argv, argc, "vrf", &idx))
|
vrf = argv[idx + 1]->arg;
|
||||||
vrf = argv[++idx]->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"]] */
|
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
|
||||||
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
|
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
|
||||||
argv_find_and_parse_safi(argv, argc, &idx, &safi);
|
argv_find_and_parse_safi(argv, argc, &idx, &safi);
|
||||||
@ -10888,8 +10926,13 @@ DEFUN (show_ip_bgp_neighbors,
|
|||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
if (argv_find(argv, argc, "view", &idx)
|
/* [<vrf> VIEWVRFNAME] */
|
||||||
|| argv_find(argv, argc, "vrf", &idx))
|
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;
|
vrf = argv[idx + 1]->arg;
|
||||||
|
|
||||||
idx++;
|
idx++;
|
||||||
@ -11183,8 +11226,11 @@ DEFUN (show_ip_bgp_route_leak,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv_find(argv, argc, "vrf", &idx))
|
if (argv_find(argv, argc, "vrf", &idx)) {
|
||||||
vrf = argv[++idx]->arg;
|
vrf = argv[idx + 1]->arg;
|
||||||
|
if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
|
||||||
|
vrf = NULL;
|
||||||
|
}
|
||||||
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
|
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
|
||||||
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
|
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
|
||||||
argv_find_and_parse_safi(argv, argc, &idx, &safi);
|
argv_find_and_parse_safi(argv, argc, &idx, &safi);
|
||||||
@ -11257,10 +11303,14 @@ DEFUN (show_ip_bgp_updgrps,
|
|||||||
/* show [ip] bgp */
|
/* show [ip] bgp */
|
||||||
if (argv_find(argv, argc, "ip", &idx))
|
if (argv_find(argv, argc, "ip", &idx))
|
||||||
afi = AFI_IP;
|
afi = AFI_IP;
|
||||||
/* [<view|vrf> VIEWVRFNAME] */
|
/* [<vrf> VIEWVRFNAME] */
|
||||||
if (argv_find(argv, argc, "view", &idx)
|
if (argv_find(argv, argc, "vrf", &idx)) {
|
||||||
|| argv_find(argv, argc, "vrf", &idx))
|
vrf = argv[idx + 1]->arg;
|
||||||
vrf = argv[++idx]->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"]] */
|
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
|
||||||
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
|
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
|
||||||
argv_find_and_parse_safi(argv, argc, &idx, &safi);
|
argv_find_and_parse_safi(argv, argc, &idx, &safi);
|
||||||
|
@ -7735,10 +7735,8 @@ static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
|
|||||||
struct listnode *next;
|
struct listnode *next;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
|
|
||||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||||
if (vrf->vrf_id != VRF_DEFAULT)
|
vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
|
||||||
vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
|
for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
|
||||||
if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
|
if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
|
||||||
|
@ -48,6 +48,13 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
|
|||||||
|
|
||||||
.. seealso:: :ref:`zebra-vrf`
|
.. 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
|
.. option:: --v6-rr-semantics
|
||||||
|
|
||||||
The linux kernel is receiving the ability to use the same route
|
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*
|
will dump the routing table ``TABLENO`` of the *Linux network namespace*
|
||||||
``VRF``.
|
``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:
|
.. _zebra-mpls:
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
master = eigrp_om->master;
|
master = eigrp_om->master;
|
||||||
|
|
||||||
eigrp_error_init();
|
eigrp_error_init();
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
/*EIGRPd init*/
|
/*EIGRPd init*/
|
||||||
eigrp_if_init();
|
eigrp_if_init();
|
||||||
|
@ -192,7 +192,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
*/
|
*/
|
||||||
isis_error_init();
|
isis_error_init();
|
||||||
access_list_init();
|
access_list_init();
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
prefix_list_init();
|
prefix_list_init();
|
||||||
isis_init();
|
isis_init();
|
||||||
isis_circuit_init();
|
isis_circuit_init();
|
||||||
|
@ -330,7 +330,7 @@ main(int argc, char *argv[])
|
|||||||
master = frr_init();
|
master = frr_init();
|
||||||
|
|
||||||
vty_config_lockless();
|
vty_config_lockless();
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
access_list_init();
|
access_list_init();
|
||||||
ldp_vty_init();
|
ldp_vty_init();
|
||||||
ldp_zebra_init(master);
|
ldp_zebra_init(master);
|
||||||
|
59
lib/vrf.c
59
lib/vrf.c
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
/* default VRF ID value used when VRF backend is not NETNS */
|
/* default VRF ID value used when VRF backend is not NETNS */
|
||||||
#define VRF_DEFAULT_INTERNAL 0
|
#define VRF_DEFAULT_INTERNAL 0
|
||||||
|
#define VRF_DEFAULT_NAME_INTERNAL "default"
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
|
DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
|
||||||
DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
|
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 int vrf_backend;
|
||||||
static struct zebra_privs_t *vrf_daemon_privs;
|
static struct zebra_privs_t *vrf_daemon_privs;
|
||||||
|
static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Turn on/off debug code
|
* Turn on/off debug code
|
||||||
@ -69,6 +71,7 @@ struct vrf_master {
|
|||||||
int (*vrf_delete_hook)(struct vrf *);
|
int (*vrf_delete_hook)(struct vrf *);
|
||||||
int (*vrf_enable_hook)(struct vrf *);
|
int (*vrf_enable_hook)(struct vrf *);
|
||||||
int (*vrf_disable_hook)(struct vrf *);
|
int (*vrf_disable_hook)(struct vrf *);
|
||||||
|
int (*vrf_update_name_hook)(struct vrf *vrf);
|
||||||
} vrf_master = {
|
} vrf_master = {
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
@ -165,6 +168,13 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name)
|
|||||||
*/
|
*/
|
||||||
if (name)
|
if (name)
|
||||||
vrf = vrf_lookup_by_name(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 */
|
/* Try to find VRF both by ID and name */
|
||||||
if (!vrf && vrf_id != VRF_UNKNOWN)
|
if (!vrf && vrf_id != VRF_UNKNOWN)
|
||||||
vrf = vrf_lookup_by_id(vrf_id);
|
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;
|
struct vrf *vrf = NULL;
|
||||||
|
|
||||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||||
if (vrf->vrf_id != VRF_DEFAULT)
|
vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
|
||||||
vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct cmd_variable_handler vrf_var_handlers[] = {
|
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. */
|
/* Initialize VRF module. */
|
||||||
void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
|
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;
|
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_enable_hook = enable;
|
||||||
vrf_master.vrf_disable_hook = disable;
|
vrf_master.vrf_disable_hook = disable;
|
||||||
vrf_master.vrf_delete_hook = delete;
|
vrf_master.vrf_delete_hook = delete;
|
||||||
|
vrf_master.vrf_update_name_hook = update;
|
||||||
|
|
||||||
/* The default VRF always exists. */
|
/* The default VRF always exists. */
|
||||||
default_vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
|
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!");
|
"vrf_init: failed to create the default VRF!");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (vrf_is_backend_netns())
|
||||||
|
strlcpy(default_vrf->data.l.netns_name,
|
||||||
|
VRF_DEFAULT_NAME, NS_NAMSIZ);
|
||||||
|
|
||||||
/* Enable the default VRF. */
|
/* Enable the default VRF. */
|
||||||
if (!vrf_enable(default_vrf)) {
|
if (!vrf_enable(default_vrf)) {
|
||||||
@ -876,12 +889,40 @@ void vrf_cmd_init(int (*writefunc)(struct vty *vty),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vrf_set_default_name(const char *default_name)
|
||||||
|
{
|
||||||
|
struct vrf *def_vrf;
|
||||||
|
struct vrf *vrf_with_default_name = NULL;
|
||||||
|
|
||||||
|
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)
|
vrf_id_t vrf_get_default_id(void)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_name(VRF_DEFAULT_NAME);
|
|
||||||
|
|
||||||
if (vrf)
|
|
||||||
return vrf->vrf_id;
|
|
||||||
/* backend netns is only known by zebra
|
/* backend netns is only known by zebra
|
||||||
* for other daemons, we return VRF_DEFAULT_INTERNAL
|
* for other daemons, we return VRF_DEFAULT_INTERNAL
|
||||||
*/
|
*/
|
||||||
|
12
lib/vrf.h
12
lib/vrf.h
@ -41,8 +41,6 @@ enum { IFLA_VRF_UNSPEC, IFLA_VRF_TABLE, __IFLA_VRF_MAX };
|
|||||||
#define VRF_NAMSIZ 36
|
#define VRF_NAMSIZ 36
|
||||||
#define NS_NAMSIZ 16
|
#define NS_NAMSIZ 16
|
||||||
|
|
||||||
#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The command strings
|
* 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
|
* delete -> Called back when a vrf is being deleted from
|
||||||
* the system ( 2 and 3 ) above.
|
* the system ( 2 and 3 ) above.
|
||||||
*/
|
*/
|
||||||
extern void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
|
extern void vrf_init(int (*create)(struct vrf *vrf), int (*enable)(struct vrf *vrf),
|
||||||
int (*disable)(struct vrf *), int (*delete)(struct 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
|
* 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 */
|
/* The default VRF ID */
|
||||||
#define VRF_DEFAULT vrf_get_default_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 ? */
|
/* VRF is mapped on netns or not ? */
|
||||||
int vrf_is_mapped_on_netns(struct vrf *vrf);
|
int vrf_is_mapped_on_netns(struct vrf *vrf);
|
||||||
|
|
||||||
|
@ -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 = vrf_get(vrf_id, vrfname_tmp);
|
||||||
vrf->data.l.table_id = data.l.table_id;
|
vrf->data.l.table_id = data.l.table_id;
|
||||||
memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
|
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);
|
vrf_enable(vrf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ int main(int argc, char **argv)
|
|||||||
/* Library inits. */
|
/* Library inits. */
|
||||||
master = frr_init();
|
master = frr_init();
|
||||||
nhrp_error_init();
|
nhrp_error_init();
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
nhrp_interface_init();
|
nhrp_interface_init();
|
||||||
resolver_init();
|
resolver_init();
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ int main(int argc, char *argv[], char *envp[])
|
|||||||
/* thread master */
|
/* thread master */
|
||||||
master = frr_init();
|
master = frr_init();
|
||||||
|
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
access_list_init();
|
access_list_init();
|
||||||
prefix_list_init();
|
prefix_list_init();
|
||||||
|
|
||||||
|
@ -145,6 +145,8 @@ static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty,
|
|||||||
|
|
||||||
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
|
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
|
||||||
vrf_name = argv[idx_vrf + 1]->arg;
|
vrf_name = argv[idx_vrf + 1]->arg;
|
||||||
|
if (vrf_name == NULL || strmatch(vrf_name, VRF_DEFAULT_NAME))
|
||||||
|
vrf_name = NULL;
|
||||||
if (enable) {
|
if (enable) {
|
||||||
/* Allocate VRF aware instance */
|
/* Allocate VRF aware instance */
|
||||||
ospf = ospf_get(*instance, vrf_name);
|
ospf = ospf_get(*instance, vrf_name);
|
||||||
|
@ -234,12 +234,10 @@ static struct ospf *ospf_new(unsigned short instance, const char *name)
|
|||||||
new->instance = instance;
|
new->instance = instance;
|
||||||
new->router_id.s_addr = htonl(0);
|
new->router_id.s_addr = htonl(0);
|
||||||
new->router_id_static.s_addr = htonl(0);
|
new->router_id_static.s_addr = htonl(0);
|
||||||
|
if (name && !strmatch(name, VRF_DEFAULT_NAME)) {
|
||||||
if (name) {
|
|
||||||
new->vrf_id = VRF_UNKNOWN;
|
new->vrf_id = VRF_UNKNOWN;
|
||||||
/* Freed in ospf_finish_final */
|
/* Freed in ospf_finish_final */
|
||||||
new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
|
new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
|
||||||
vrf = vrf_lookup_by_name(new->name);
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: Create new ospf instance with vrf_name %s vrf_id %u",
|
"%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 ospf *ospf = NULL;
|
||||||
struct listnode *node, *nnode;
|
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)) {
|
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
|
||||||
if ((ospf->instance == instance)
|
if ((ospf->instance == instance)
|
||||||
&& ((ospf->name == NULL && name == NULL)
|
&& ((ospf->name == NULL && name == NULL)
|
||||||
@ -2078,6 +2079,10 @@ static int ospf_vrf_enable(struct vrf *vrf)
|
|||||||
|
|
||||||
ospf = ospf_lookup_by_name(vrf->name);
|
ospf = ospf_lookup_by_name(vrf->name);
|
||||||
if (ospf) {
|
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;
|
old_vrf_id = ospf->vrf_id;
|
||||||
/* We have instance configured, link to VRF and make it "up". */
|
/* We have instance configured, link to VRF and make it "up". */
|
||||||
ospf_vrf_link(ospf, vrf);
|
ospf_vrf_link(ospf, vrf);
|
||||||
@ -2149,7 +2154,7 @@ static int ospf_vrf_disable(struct vrf *vrf)
|
|||||||
void ospf_vrf_init(void)
|
void ospf_vrf_init(void)
|
||||||
{
|
{
|
||||||
vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
|
vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
|
||||||
ospf_vrf_delete);
|
ospf_vrf_delete, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ospf_vrf_terminate(void)
|
void ospf_vrf_terminate(void)
|
||||||
|
@ -146,7 +146,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
|
|
||||||
pbr_debug_init();
|
pbr_debug_init();
|
||||||
|
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
nexthop_group_init(pbr_nhgroup_add_cb,
|
nexthop_group_init(pbr_nhgroup_add_cb,
|
||||||
pbr_nhgroup_add_nexthop_cb,
|
pbr_nhgroup_add_nexthop_cb,
|
||||||
pbr_nhgroup_del_nexthop_cb,
|
pbr_nhgroup_del_nexthop_cb,
|
||||||
|
@ -196,7 +196,8 @@ static int pim_vrf_config_write(struct vty *vty)
|
|||||||
|
|
||||||
void pim_vrf_init(void)
|
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);
|
vrf_cmd_init(pim_vrf_config_write, &pimd_privs);
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ int main(int argc, char **argv)
|
|||||||
/* Library initialization. */
|
/* Library initialization. */
|
||||||
rip_error_init();
|
rip_error_init();
|
||||||
keychain_init();
|
keychain_init();
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
/* RIP related initialization. */
|
/* RIP related initialization. */
|
||||||
rip_init();
|
rip_init();
|
||||||
|
@ -166,7 +166,7 @@ int main(int argc, char **argv)
|
|||||||
master = frr_init();
|
master = frr_init();
|
||||||
|
|
||||||
/* Library inits. */
|
/* Library inits. */
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
/* RIPngd inits. */
|
/* RIPngd inits. */
|
||||||
ripng_init();
|
ripng_init();
|
||||||
|
@ -146,7 +146,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
|
|
||||||
master = frr_init();
|
master = frr_init();
|
||||||
|
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
access_list_init();
|
access_list_init();
|
||||||
route_map_init();
|
route_map_init();
|
||||||
|
@ -190,7 +190,7 @@ int static_vrf_has_config(struct static_vrf *svrf)
|
|||||||
void static_vrf_init(void)
|
void static_vrf_init(void)
|
||||||
{
|
{
|
||||||
vrf_init(static_vrf_new, static_vrf_enable,
|
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);
|
vrf_cmd_init(static_vrf_config_write, &static_privs);
|
||||||
}
|
}
|
||||||
|
@ -913,7 +913,7 @@ int main(void)
|
|||||||
qobj_init();
|
qobj_init();
|
||||||
master = thread_master_create(NULL);
|
master = thread_master_create(NULL);
|
||||||
bgp_master_init(master);
|
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_option_set(BGP_OPT_NO_LISTEN);
|
||||||
|
|
||||||
bgp_pthreads_init();
|
bgp_pthreads_init();
|
||||||
|
@ -1079,7 +1079,7 @@ int main(void)
|
|||||||
bgp_vty_init();
|
bgp_vty_init();
|
||||||
master = thread_master_create("test mp attr");
|
master = thread_master_create("test mp attr");
|
||||||
bgp_master_init(master);
|
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_option_set(BGP_OPT_NO_LISTEN);
|
||||||
bgp_attr_init();
|
bgp_attr_init();
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ static int global_test_init(void)
|
|||||||
master = thread_master_create(NULL);
|
master = thread_master_create(NULL);
|
||||||
zclient = zclient_new_notify(master, &zclient_options_default);
|
zclient = zclient_new_notify(master, &zclient_options_default);
|
||||||
bgp_master_init(master);
|
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_option_set(BGP_OPT_NO_LISTEN);
|
||||||
|
|
||||||
if (fileno(stdout) >= 0)
|
if (fileno(stdout) >= 0)
|
||||||
|
@ -59,7 +59,7 @@ int main(int argc, char *argv[])
|
|||||||
bgp_attr_init();
|
bgp_attr_init();
|
||||||
master = thread_master_create(NULL);
|
master = thread_master_create(NULL);
|
||||||
bgp_master_init(master);
|
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_option_set(BGP_OPT_NO_LISTEN);
|
||||||
|
|
||||||
if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
|
if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
|
||||||
|
@ -1387,7 +1387,7 @@ static void bgp_startup(void)
|
|||||||
master = thread_master_create(NULL);
|
master = thread_master_create(NULL);
|
||||||
bgp_master_init(master);
|
bgp_master_init(master);
|
||||||
bgp_option_set(BGP_OPT_NO_LISTEN);
|
bgp_option_set(BGP_OPT_NO_LISTEN);
|
||||||
vrf_init(NULL, NULL, NULL, NULL);
|
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||||
bgp_init();
|
bgp_init();
|
||||||
bgp_pthreads_run();
|
bgp_pthreads_run();
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@ struct option longopts[] = {
|
|||||||
{"ecmp", required_argument, NULL, 'e'},
|
{"ecmp", required_argument, NULL, 'e'},
|
||||||
{"label_socket", no_argument, NULL, 'l'},
|
{"label_socket", no_argument, NULL, 'l'},
|
||||||
{"retain", no_argument, NULL, 'r'},
|
{"retain", no_argument, NULL, 'r'},
|
||||||
|
{"vrfdefaultname", required_argument, NULL, 'o'},
|
||||||
#ifdef HAVE_NETLINK
|
#ifdef HAVE_NETLINK
|
||||||
{"vrfwnetns", no_argument, NULL, 'n'},
|
{"vrfwnetns", no_argument, NULL, 'n'},
|
||||||
{"nl-bufsize", required_argument, NULL, 's'},
|
{"nl-bufsize", required_argument, NULL, 's'},
|
||||||
@ -235,7 +236,7 @@ int main(int argc, char **argv)
|
|||||||
frr_preinit(&zebra_di, argc, argv);
|
frr_preinit(&zebra_di, argc, argv);
|
||||||
|
|
||||||
frr_opt_add(
|
frr_opt_add(
|
||||||
"bakz:e:l:r"
|
"bakz:e:l:o:r"
|
||||||
#ifdef HAVE_NETLINK
|
#ifdef HAVE_NETLINK
|
||||||
"s:n"
|
"s:n"
|
||||||
#endif
|
#endif
|
||||||
@ -254,6 +255,7 @@ int main(int argc, char **argv)
|
|||||||
" -l, --label_socket Socket to external label manager\n"
|
" -l, --label_socket Socket to external label manager\n"
|
||||||
" -k, --keep_kernel Don't delete old routes which were installed by zebra.\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"
|
" -r, --retain When program terminates, retain added route by zebra.\n"
|
||||||
|
" -o, --vrfdefaultname Set default VRF name.\n"
|
||||||
#ifdef HAVE_NETLINK
|
#ifdef HAVE_NETLINK
|
||||||
" -n, --vrfwnetns Use NetNS as VRF backend\n"
|
" -n, --vrfwnetns Use NetNS as VRF backend\n"
|
||||||
" -s, --nl-bufsize Set netlink receive buffer size\n"
|
" -s, --nl-bufsize Set netlink receive buffer size\n"
|
||||||
@ -296,6 +298,9 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
|
vrf_set_default_name(optarg);
|
||||||
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
zserv_path = optarg;
|
zserv_path = optarg;
|
||||||
if (!frr_zclient_addr(&dummy, &dummylen, optarg)) {
|
if (!frr_zclient_addr(&dummy, &dummylen, optarg)) {
|
||||||
|
@ -149,6 +149,41 @@ static int zebra_ns_delete(char *name)
|
|||||||
return 0;
|
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)
|
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)
|
if (err < 0)
|
||||||
return zebra_ns_continue_read(zns_info, stop_retry);
|
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 */
|
/* success : close fd and create zns context */
|
||||||
zebra_ns_notify_create_context_from_entry_name(basename(netnspath));
|
zebra_ns_notify_create_context_from_entry_name(basename(netnspath));
|
||||||
return zebra_ns_continue_read(zns_info, 1);
|
return zebra_ns_continue_read(zns_info, 1);
|
||||||
@ -259,6 +302,13 @@ void zebra_ns_notify_parse(void)
|
|||||||
dent->d_name);
|
dent->d_name);
|
||||||
continue;
|
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);
|
zebra_ns_notify_create_context_from_entry_name(dent->d_name);
|
||||||
}
|
}
|
||||||
closedir(srcdir);
|
closedir(srcdir);
|
||||||
|
@ -282,6 +282,19 @@ static int zebra_vrf_delete(struct vrf *vrf)
|
|||||||
return 0;
|
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.
|
/* Return if this VRF has any FRR configuration or not.
|
||||||
* IMPORTANT: This function needs to be updated when additional configuration
|
* IMPORTANT: This function needs to be updated when additional configuration
|
||||||
* is added for a VRF.
|
* is added for a VRF.
|
||||||
@ -491,7 +504,7 @@ static int vrf_config_write(struct vty *vty)
|
|||||||
void zebra_vrf_init(void)
|
void zebra_vrf_init(void)
|
||||||
{
|
{
|
||||||
vrf_init(zebra_vrf_new, zebra_vrf_enable, zebra_vrf_disable,
|
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);
|
vrf_cmd_init(vrf_config_write, &zserv_privs);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user