mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-25 21:37:29 +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);
|
||||
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)
|
||||
|
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))
|
||||
*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);
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
59
lib/vrf.c
59
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),
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
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 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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user