Merge pull request #2337 from pguibert6WIND/netns_alias

default VRF naming update
This commit is contained in:
Renato Westphal 2018-08-28 17:10:04 -03:00 committed by GitHub
commit efd1f138cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 291 additions and 71 deletions

View File

@ -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)

View File

@ -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;
char *name = NULL;
if (argv_find(argv, argc, "view", &idx)
|| argv_find(argv, argc, "vrf", &idx))
bgp = bgp_lookup_by_name(argv[idx + 1]->arg);
/* [<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);

View File

@ -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)

View File

@ -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:

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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),
}
}
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)
{
struct vrf *vrf = vrf_lookup_by_name(VRF_DEFAULT_NAME);
if (vrf)
return vrf->vrf_id;
/* backend netns is only known by zebra
* for other daemons, we return VRF_DEFAULT_INTERNAL
*/

View File

@ -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);

View File

@ -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);
}

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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)

View File

@ -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,

View File

@ -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);
}

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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);
}

View File

@ -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();

View File

@ -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();

View File

@ -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)

View File

@ -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))

View File

@ -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();
}

View File

@ -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)) {

View File

@ -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);

View File

@ -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);
}