mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
lib, vtysh: support multiple VRFs by using linux netns
We realize VRFs with linux netns by default. The main job is to associate a VRF with a netns. Currently this is done by the configuration: [no] vrf N netns <netns-name> This command is also available in vtysh and goes to only zebra, because presently only zebra supports multiple VRF. A file descriptor is added to "struct vrf". This is for the associated netns file. Once the command "vrf N netns NAME" is executed, the specified file is opened and the file descriptor is stored in the VRF N. In this way the association is formed. In vrf_socket(), we first switch to the specified VRF by using the stored file descriptor, and then can allocate a socket which is working in the associated netns. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> (cherry picked from commit 55cfa2f190620f7c711944637659bc208970324d)
This commit is contained in:
parent
32bcb8b0a5
commit
13460c44a2
|
@ -852,6 +852,14 @@ AC_CHECK_FUNCS([dup2 ftruncate getcwd gethostbyname getpagesize gettimeofday \
|
||||||
if_nametoindex if_indextoname getifaddrs \
|
if_nametoindex if_indextoname getifaddrs \
|
||||||
uname fcntl getgrouplist])
|
uname fcntl getgrouplist])
|
||||||
|
|
||||||
|
AC_CHECK_HEADER([asm-generic/unistd.h],
|
||||||
|
[AC_CHECK_DECL(__NR_setns,
|
||||||
|
AC_DEFINE(HAVE_NETNS,, Have netns),,
|
||||||
|
QUAGGA_INCLUDES [#include <asm-generic/unistd.h>
|
||||||
|
])
|
||||||
|
AC_CHECK_FUNCS(setns, AC_DEFINE(HAVE_SETNS,, Have setns))]
|
||||||
|
)
|
||||||
|
|
||||||
dnl ------------------------------------
|
dnl ------------------------------------
|
||||||
dnl Determine routing get and set method
|
dnl Determine routing get and set method
|
||||||
dnl ------------------------------------
|
dnl ------------------------------------
|
||||||
|
|
|
@ -2902,6 +2902,7 @@ DEFUN (config_exit,
|
||||||
vty_config_unlock (vty);
|
vty_config_unlock (vty);
|
||||||
break;
|
break;
|
||||||
case INTERFACE_NODE:
|
case INTERFACE_NODE:
|
||||||
|
case NS_NODE:
|
||||||
case VRF_NODE:
|
case VRF_NODE:
|
||||||
case ZEBRA_NODE:
|
case ZEBRA_NODE:
|
||||||
case BGP_NODE:
|
case BGP_NODE:
|
||||||
|
@ -2960,6 +2961,7 @@ DEFUN (config_end,
|
||||||
break;
|
break;
|
||||||
case CONFIG_NODE:
|
case CONFIG_NODE:
|
||||||
case INTERFACE_NODE:
|
case INTERFACE_NODE:
|
||||||
|
case NS_NODE:
|
||||||
case VRF_NODE:
|
case VRF_NODE:
|
||||||
case ZEBRA_NODE:
|
case ZEBRA_NODE:
|
||||||
case RIP_NODE:
|
case RIP_NODE:
|
||||||
|
|
|
@ -74,6 +74,7 @@ enum node_type
|
||||||
AAA_NODE, /* AAA node. */
|
AAA_NODE, /* AAA node. */
|
||||||
KEYCHAIN_NODE, /* Key-chain node. */
|
KEYCHAIN_NODE, /* Key-chain node. */
|
||||||
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
|
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
|
||||||
|
NS_NODE, /* Logical-Router node. */
|
||||||
VRF_NODE, /* VRF mode node. */
|
VRF_NODE, /* VRF mode node. */
|
||||||
INTERFACE_NODE, /* Interface mode node. */
|
INTERFACE_NODE, /* Interface mode node. */
|
||||||
ZEBRA_NODE, /* zebra connection node. */
|
ZEBRA_NODE, /* zebra connection node. */
|
||||||
|
|
247
lib/ns.c
247
lib/ns.c
|
@ -22,6 +22,13 @@
|
||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_NETNS
|
||||||
|
#undef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <sched.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "if.h"
|
#include "if.h"
|
||||||
#include "ns.h"
|
#include "ns.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
|
@ -29,14 +36,43 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
#include "command.h"
|
||||||
|
#include "vty.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_NETNS
|
||||||
|
|
||||||
|
#ifndef CLONE_NEWNET
|
||||||
|
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_SETNS
|
||||||
|
static inline int setns(int fd, int nstype)
|
||||||
|
{
|
||||||
|
#ifdef __NR_setns
|
||||||
|
return syscall(__NR_setns, fd, nstype);
|
||||||
|
#else
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SETNS */
|
||||||
|
|
||||||
|
#define NS_DEFAULT_NAME "/proc/self/ns/net"
|
||||||
|
|
||||||
|
#else /* !HAVE_NETNS */
|
||||||
|
|
||||||
#define NS_DEFAULT_NAME "Default-logical-router"
|
#define NS_DEFAULT_NAME "Default-logical-router"
|
||||||
|
|
||||||
|
#endif /* HAVE_NETNS */
|
||||||
|
|
||||||
struct ns
|
struct ns
|
||||||
{
|
{
|
||||||
/* Identifier, same as the vector index */
|
/* Identifier, same as the vector index */
|
||||||
ns_id_t ns_id;
|
ns_id_t ns_id;
|
||||||
/* Name */
|
/* Name */
|
||||||
char *name;
|
char *name;
|
||||||
|
/* File descriptor */
|
||||||
|
int fd;
|
||||||
|
|
||||||
/* Master list of interfaces belonging to this NS */
|
/* Master list of interfaces belonging to this NS */
|
||||||
struct list *iflist;
|
struct list *iflist;
|
||||||
|
@ -90,6 +126,7 @@ ns_get (ns_id_t ns_id)
|
||||||
|
|
||||||
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
|
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
|
||||||
ns->ns_id = ns_id;
|
ns->ns_id = ns_id;
|
||||||
|
ns->fd = -1;
|
||||||
rn->info = ns;
|
rn->info = ns;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -114,8 +151,7 @@ ns_delete (struct ns *ns)
|
||||||
{
|
{
|
||||||
zlog_info ("NS %u is to be deleted.", ns->ns_id);
|
zlog_info ("NS %u is to be deleted.", ns->ns_id);
|
||||||
|
|
||||||
if (ns_is_enabled (ns))
|
ns_disable (ns);
|
||||||
ns_disable (ns);
|
|
||||||
|
|
||||||
if (ns_master.ns_delete_hook)
|
if (ns_master.ns_delete_hook)
|
||||||
(*ns_master.ns_delete_hook) (ns->ns_id, &ns->info);
|
(*ns_master.ns_delete_hook) (ns->ns_id, &ns->info);
|
||||||
|
@ -158,7 +194,11 @@ ns_lookup (ns_id_t ns_id)
|
||||||
static int
|
static int
|
||||||
ns_is_enabled (struct ns *ns)
|
ns_is_enabled (struct ns *ns)
|
||||||
{
|
{
|
||||||
return ns && ns->ns_id == NS_DEFAULT;
|
#ifdef HAVE_NETNS
|
||||||
|
return ns && ns->fd >= 0;
|
||||||
|
#else
|
||||||
|
return ns && ns->fd == -2 && ns->ns_id == NS_DEFAULT;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -171,18 +211,34 @@ ns_is_enabled (struct ns *ns)
|
||||||
static int
|
static int
|
||||||
ns_enable (struct ns *ns)
|
ns_enable (struct ns *ns)
|
||||||
{
|
{
|
||||||
/* Till now, only the default NS can be enabled. */
|
|
||||||
if (ns->ns_id == NS_DEFAULT)
|
|
||||||
{
|
|
||||||
zlog_info ("NS %u is enabled.", ns->ns_id);
|
|
||||||
|
|
||||||
|
if (!ns_is_enabled (ns))
|
||||||
|
{
|
||||||
|
#ifdef HAVE_NETNS
|
||||||
|
ns->fd = open (ns->name, O_RDONLY);
|
||||||
|
#else
|
||||||
|
ns->fd = -2; /* Remember that ns_enable_hook has been called */
|
||||||
|
errno = -ENOTSUP;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!ns_is_enabled (ns))
|
||||||
|
{
|
||||||
|
zlog_err ("Can not enable NS %u: %s!",
|
||||||
|
ns->ns_id, safe_strerror (errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_NETNS
|
||||||
|
zlog_info ("NS %u is associated with NETNS %s.",
|
||||||
|
ns->ns_id, ns->name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
zlog_info ("NS %u is enabled.", ns->ns_id);
|
||||||
if (ns_master.ns_enable_hook)
|
if (ns_master.ns_enable_hook)
|
||||||
(*ns_master.ns_enable_hook) (ns->ns_id, &ns->info);
|
(*ns_master.ns_enable_hook) (ns->ns_id, &ns->info);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -197,10 +253,13 @@ ns_disable (struct ns *ns)
|
||||||
{
|
{
|
||||||
zlog_info ("NS %u is to be disabled.", ns->ns_id);
|
zlog_info ("NS %u is to be disabled.", ns->ns_id);
|
||||||
|
|
||||||
/* Till now, nothing to be done for the default NS. */
|
|
||||||
|
|
||||||
if (ns_master.ns_disable_hook)
|
if (ns_master.ns_disable_hook)
|
||||||
(*ns_master.ns_disable_hook) (ns->ns_id, &ns->info);
|
(*ns_master.ns_disable_hook) (ns->ns_id, &ns->info);
|
||||||
|
|
||||||
|
#ifdef HAVE_NETNS
|
||||||
|
close (ns->fd);
|
||||||
|
#endif
|
||||||
|
ns->fd = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,6 +497,144 @@ ns_bitmap_check (ns_bitmap_t bmap, ns_id_t ns_id)
|
||||||
NS_BITMAP_FLAG (offset)) ? 1 : 0;
|
NS_BITMAP_FLAG (offset)) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_NETNS
|
||||||
|
/*
|
||||||
|
* NS realization with NETNS
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ns_netns_pathname (struct vty *vty, const char *name)
|
||||||
|
{
|
||||||
|
static char pathname[PATH_MAX];
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
if (name[0] == '/') /* absolute pathname */
|
||||||
|
result = realpath (name, pathname);
|
||||||
|
else /* relevant pathname */
|
||||||
|
{
|
||||||
|
char tmp_name[PATH_MAX];
|
||||||
|
snprintf (tmp_name, PATH_MAX, "%s/%s", NS_RUN_DIR, name);
|
||||||
|
result = realpath (tmp_name, pathname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! result)
|
||||||
|
{
|
||||||
|
vty_out (vty, "Invalid pathname: %s%s", safe_strerror (errno),
|
||||||
|
VTY_NEWLINE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pathname;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (ns_netns,
|
||||||
|
ns_netns_cmd,
|
||||||
|
"logical-router <1-65535> ns NAME",
|
||||||
|
"Enable a logical-router\n"
|
||||||
|
"Specify the logical-router indentifier\n"
|
||||||
|
"The Name Space\n"
|
||||||
|
"The file name in " NS_RUN_DIR ", or a full pathname\n")
|
||||||
|
{
|
||||||
|
ns_id_t ns_id = NS_DEFAULT;
|
||||||
|
struct ns *ns = NULL;
|
||||||
|
char *pathname = ns_netns_pathname (vty, argv[1]);
|
||||||
|
|
||||||
|
if (!pathname)
|
||||||
|
return CMD_WARNING;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("NS ID", ns_id, argv[0]);
|
||||||
|
ns = ns_get (ns_id);
|
||||||
|
|
||||||
|
if (ns->name && strcmp (ns->name, pathname) != 0)
|
||||||
|
{
|
||||||
|
vty_out (vty, "NS %u is already configured with NETNS %s%s",
|
||||||
|
ns->ns_id, ns->name, VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ns->name)
|
||||||
|
ns->name = XSTRDUP (MTYPE_NS_NAME, pathname);
|
||||||
|
|
||||||
|
if (!ns_enable (ns))
|
||||||
|
{
|
||||||
|
vty_out (vty, "Can not associate NS %u with NETNS %s%s",
|
||||||
|
ns->ns_id, ns->name, VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_ns_netns,
|
||||||
|
no_ns_netns_cmd,
|
||||||
|
"no logical-router <1-65535> ns NAME",
|
||||||
|
NO_STR
|
||||||
|
"Enable a Logical-Router\n"
|
||||||
|
"Specify the Logical-Router identifier\n"
|
||||||
|
"The Name Space\n"
|
||||||
|
"The file name in " NS_RUN_DIR ", or a full pathname\n")
|
||||||
|
{
|
||||||
|
ns_id_t ns_id = NS_DEFAULT;
|
||||||
|
struct ns *ns = NULL;
|
||||||
|
char *pathname = ns_netns_pathname (vty, argv[1]);
|
||||||
|
|
||||||
|
if (!pathname)
|
||||||
|
return CMD_WARNING;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("NS ID", ns_id, argv[0]);
|
||||||
|
ns = ns_lookup (ns_id);
|
||||||
|
|
||||||
|
if (!ns)
|
||||||
|
{
|
||||||
|
vty_out (vty, "NS %u is not found%s", ns_id, VTY_NEWLINE);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ns->name && strcmp (ns->name, pathname) != 0)
|
||||||
|
{
|
||||||
|
vty_out (vty, "Incorrect NETNS file name%s", VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
ns_disable (ns);
|
||||||
|
|
||||||
|
if (ns->name)
|
||||||
|
{
|
||||||
|
XFREE (MTYPE_NS_NAME, ns->name);
|
||||||
|
ns->name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NS node. */
|
||||||
|
static struct cmd_node ns_node =
|
||||||
|
{
|
||||||
|
NS_NODE,
|
||||||
|
"", /* NS node has no interface. */
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* NS configuration write function. */
|
||||||
|
static int
|
||||||
|
ns_config_write (struct vty *vty)
|
||||||
|
{
|
||||||
|
struct route_node *rn;
|
||||||
|
struct ns *ns;
|
||||||
|
int write = 0;
|
||||||
|
|
||||||
|
for (rn = route_top (ns_table); rn; rn = route_next (rn))
|
||||||
|
if ((ns = rn->info) != NULL &&
|
||||||
|
ns->ns_id != NS_DEFAULT && ns->name)
|
||||||
|
{
|
||||||
|
vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE);
|
||||||
|
write++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return write;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_NETNS */
|
||||||
|
|
||||||
/* Initialize NS module. */
|
/* Initialize NS module. */
|
||||||
void
|
void
|
||||||
ns_init (void)
|
ns_init (void)
|
||||||
|
@ -464,6 +661,13 @@ ns_init (void)
|
||||||
zlog_err ("ns_init: failed to enable the default NS!");
|
zlog_err ("ns_init: failed to enable the default NS!");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_NETNS
|
||||||
|
/* Install NS commands. */
|
||||||
|
install_node (&ns_node, ns_config_write);
|
||||||
|
install_element (CONFIG_NODE, &ns_netns_cmd);
|
||||||
|
install_element (CONFIG_NODE, &no_ns_netns_cmd);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate NS module. */
|
/* Terminate NS module. */
|
||||||
|
@ -485,19 +689,26 @@ ns_terminate (void)
|
||||||
int
|
int
|
||||||
ns_socket (int domain, int type, int protocol, ns_id_t ns_id)
|
ns_socket (int domain, int type, int protocol, ns_id_t ns_id)
|
||||||
{
|
{
|
||||||
|
struct ns *ns = ns_lookup (ns_id);
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (!ns_is_enabled (ns_lookup (ns_id)))
|
if (!ns_is_enabled (ns))
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ns_id == NS_DEFAULT)
|
#ifdef HAVE_NETNS
|
||||||
ret = socket (domain, type, protocol);
|
ret = (ns_id != NS_DEFAULT) ? setns (ns->fd, CLONE_NEWNET) : 0;
|
||||||
else
|
if (ret >= 0)
|
||||||
errno = ENOSYS;
|
{
|
||||||
|
ret = socket (domain, type, protocol);
|
||||||
|
if (ns_id != NS_DEFAULT)
|
||||||
|
setns (ns_lookup (NS_DEFAULT)->fd, CLONE_NEWNET);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ret = socket (domain, type, protocol);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
lib/ns.h
2
lib/ns.h
|
@ -33,7 +33,7 @@ typedef u_int16_t ns_id_t;
|
||||||
/*
|
/*
|
||||||
* The command strings
|
* The command strings
|
||||||
*/
|
*/
|
||||||
|
#define NS_RUN_DIR "/var/run/netns"
|
||||||
#define NS_CMD_STR "logical-router <0-65535>"
|
#define NS_CMD_STR "logical-router <0-65535>"
|
||||||
#define NS_CMD_HELP_STR "Specify the Logical-Router\nThe Logical-Router ID\n"
|
#define NS_CMD_HELP_STR "Specify the Logical-Router\nThe Logical-Router ID\n"
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,9 @@ vtysh_cmd_FILES = $(vtysh_scan) \
|
||||||
$(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \
|
$(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \
|
||||||
$(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \
|
$(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \
|
||||||
$(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \
|
$(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \
|
||||||
$(top_srcdir)/lib/vty.c $(top_srcdir)/zebra/debug.c \
|
|
||||||
$(top_srcdir)/lib/vrf.c \
|
$(top_srcdir)/lib/vrf.c \
|
||||||
|
$(top_srcdir)/lib/vty.c $(top_srcdir)/zebra/debug.c \
|
||||||
|
$(top_srcdir)/lib/ns.c \
|
||||||
$(top_srcdir)/zebra/interface.c \
|
$(top_srcdir)/zebra/interface.c \
|
||||||
$(top_srcdir)/zebra/irdp_interface.c \
|
$(top_srcdir)/zebra/irdp_interface.c \
|
||||||
$(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \
|
$(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \
|
||||||
|
|
|
@ -129,6 +129,9 @@ foreach (@ARGV) {
|
||||||
elsif ($file =~ /lib\/filter\.c$/) {
|
elsif ($file =~ /lib\/filter\.c$/) {
|
||||||
$protocol = "VTYSH_ALL";
|
$protocol = "VTYSH_ALL";
|
||||||
}
|
}
|
||||||
|
elsif ($file =~ /lib\/ns\.c$/) {
|
||||||
|
$protocol = "VTYSH_ZEBRA";
|
||||||
|
}
|
||||||
elsif ($file =~ /lib\/plist\.c$/) {
|
elsif ($file =~ /lib\/plist\.c$/) {
|
||||||
if ($defun_array[1] =~ m/ipv6/) {
|
if ($defun_array[1] =~ m/ipv6/) {
|
||||||
$protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
|
$protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "vtysh/vtysh.h"
|
#include "vtysh/vtysh.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "bgpd/bgp_vty.h"
|
#include "bgpd/bgp_vty.h"
|
||||||
|
#include "ns.h"
|
||||||
#include "vrf.h"
|
#include "vrf.h"
|
||||||
|
|
||||||
/* Struct VTY. */
|
/* Struct VTY. */
|
||||||
|
@ -936,6 +937,12 @@ static struct cmd_node interface_node =
|
||||||
"%s(config-if)# ",
|
"%s(config-if)# ",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct cmd_node ns_node =
|
||||||
|
{
|
||||||
|
NS_NODE,
|
||||||
|
"%s(config-logical-router)# ",
|
||||||
|
};
|
||||||
|
|
||||||
static struct cmd_node vrf_node =
|
static struct cmd_node vrf_node =
|
||||||
{
|
{
|
||||||
VRF_NODE,
|
VRF_NODE,
|
||||||
|
@ -1391,6 +1398,7 @@ vtysh_exit (struct vty *vty)
|
||||||
vty->node = ENABLE_NODE;
|
vty->node = ENABLE_NODE;
|
||||||
break;
|
break;
|
||||||
case INTERFACE_NODE:
|
case INTERFACE_NODE:
|
||||||
|
case NS_NODE:
|
||||||
case VRF_NODE:
|
case VRF_NODE:
|
||||||
case ZEBRA_NODE:
|
case ZEBRA_NODE:
|
||||||
case BGP_NODE:
|
case BGP_NODE:
|
||||||
|
@ -1622,6 +1630,19 @@ DEFSH (VTYSH_ZEBRA,
|
||||||
"Interface's name\n"
|
"Interface's name\n"
|
||||||
VRF_CMD_HELP_STR)
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
|
DEFUNSH (VTYSH_NS,
|
||||||
|
vtysh_ns,
|
||||||
|
vtysh_ns_cmd,
|
||||||
|
"logical-router <1-65535 ns NAME",
|
||||||
|
"Enable a logical-router\n"
|
||||||
|
"Specify the logical-router indentifier\n"
|
||||||
|
"The Name Space\n"
|
||||||
|
"The file name in " NS_RUN_DIR ", or a full pathname\n")
|
||||||
|
{
|
||||||
|
vty->node = NS_NODE;
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUNSH (VTYSH_VRF,
|
DEFUNSH (VTYSH_VRF,
|
||||||
vtysh_vrf,
|
vtysh_vrf,
|
||||||
vtysh_vrf_cmd,
|
vtysh_vrf_cmd,
|
||||||
|
@ -1640,6 +1661,20 @@ DEFSH (VTYSH_ZEBRA,
|
||||||
"Delete a pseudo vrf's configuration\n"
|
"Delete a pseudo vrf's configuration\n"
|
||||||
"VRF's name\n")
|
"VRF's name\n")
|
||||||
|
|
||||||
|
DEFUNSH (VTYSH_NS,
|
||||||
|
vtysh_exit_ns,
|
||||||
|
vtysh_exit_ns_cmd,
|
||||||
|
"exit",
|
||||||
|
"Exit current mode and down to previous mode\n")
|
||||||
|
{
|
||||||
|
return vtysh_exit (vty);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIAS (vtysh_exit_ns,
|
||||||
|
vtysh_quit_ns_cmd,
|
||||||
|
"quit",
|
||||||
|
"Exit current mode and down to previous mode\n")
|
||||||
|
|
||||||
DEFUNSH (VTYSH_VRF,
|
DEFUNSH (VTYSH_VRF,
|
||||||
vtysh_exit_vrf,
|
vtysh_exit_vrf,
|
||||||
vtysh_exit_vrf_cmd,
|
vtysh_exit_vrf_cmd,
|
||||||
|
@ -2864,6 +2899,7 @@ vtysh_init_vty (void)
|
||||||
install_node (&rip_node, NULL);
|
install_node (&rip_node, NULL);
|
||||||
install_node (&interface_node, NULL);
|
install_node (&interface_node, NULL);
|
||||||
install_node (&link_params_node, NULL);
|
install_node (&link_params_node, NULL);
|
||||||
|
install_node (&ns_node, NULL);
|
||||||
install_node (&vrf_node, NULL);
|
install_node (&vrf_node, NULL);
|
||||||
install_node (&rmap_node, NULL);
|
install_node (&rmap_node, NULL);
|
||||||
install_node (&zebra_node, NULL);
|
install_node (&zebra_node, NULL);
|
||||||
|
@ -2894,6 +2930,7 @@ vtysh_init_vty (void)
|
||||||
vtysh_install_default (RIP_NODE);
|
vtysh_install_default (RIP_NODE);
|
||||||
vtysh_install_default (INTERFACE_NODE);
|
vtysh_install_default (INTERFACE_NODE);
|
||||||
vtysh_install_default (LINK_PARAMS_NODE);
|
vtysh_install_default (LINK_PARAMS_NODE);
|
||||||
|
vtysh_install_default (NS_NODE);
|
||||||
vtysh_install_default (VRF_NODE);
|
vtysh_install_default (VRF_NODE);
|
||||||
vtysh_install_default (RMAP_NODE);
|
vtysh_install_default (RMAP_NODE);
|
||||||
vtysh_install_default (ZEBRA_NODE);
|
vtysh_install_default (ZEBRA_NODE);
|
||||||
|
@ -2991,6 +3028,10 @@ vtysh_init_vty (void)
|
||||||
install_element (LINK_PARAMS_NODE, &vtysh_exit_interface_cmd);
|
install_element (LINK_PARAMS_NODE, &vtysh_exit_interface_cmd);
|
||||||
install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
|
install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
|
||||||
|
|
||||||
|
install_element (NS_NODE, &vtysh_end_all_cmd);
|
||||||
|
install_element (NS_NODE, &vtysh_exit_ns_cmd);
|
||||||
|
install_element (NS_NODE, &vtysh_quit_ns_cmd);
|
||||||
|
|
||||||
install_element (VRF_NODE, &vtysh_end_all_cmd);
|
install_element (VRF_NODE, &vtysh_end_all_cmd);
|
||||||
install_element (VRF_NODE, &vtysh_exit_vrf_cmd);
|
install_element (VRF_NODE, &vtysh_exit_vrf_cmd);
|
||||||
install_element (VRF_NODE, &vtysh_quit_vrf_cmd);
|
install_element (VRF_NODE, &vtysh_quit_vrf_cmd);
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD
|
#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD
|
||||||
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD
|
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD
|
||||||
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD
|
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD
|
||||||
|
#define VTYSH_NS VTYSH_ZEBRA
|
||||||
#define VTYSH_VRF VTYSH_ZEBRA
|
#define VTYSH_VRF VTYSH_ZEBRA
|
||||||
|
|
||||||
/* vtysh local configuration file. */
|
/* vtysh local configuration file. */
|
||||||
|
|
|
@ -171,6 +171,7 @@ vtysh_config_parse_line (const char *line)
|
||||||
{
|
{
|
||||||
if (config->index == RMAP_NODE ||
|
if (config->index == RMAP_NODE ||
|
||||||
config->index == INTERFACE_NODE ||
|
config->index == INTERFACE_NODE ||
|
||||||
|
config->index == NS_NODE ||
|
||||||
config->index == VRF_NODE ||
|
config->index == VRF_NODE ||
|
||||||
config->index == VTY_NODE)
|
config->index == VTY_NODE)
|
||||||
config_add_line_uniq (config->line, line);
|
config_add_line_uniq (config->line, line);
|
||||||
|
@ -183,6 +184,8 @@ vtysh_config_parse_line (const char *line)
|
||||||
default:
|
default:
|
||||||
if (strncmp (line, "interface", strlen ("interface")) == 0)
|
if (strncmp (line, "interface", strlen ("interface")) == 0)
|
||||||
config = config_get (INTERFACE_NODE, line);
|
config = config_get (INTERFACE_NODE, line);
|
||||||
|
else if (strncmp (line, "ns", strlen ("ns")) == 0)
|
||||||
|
config = config_get (NS_NODE, line);
|
||||||
else if (strncmp (line, "vrf", strlen ("vrf")) == 0)
|
else if (strncmp (line, "vrf", strlen ("vrf")) == 0)
|
||||||
config = config_get (VRF_NODE, line);
|
config = config_get (VRF_NODE, line);
|
||||||
else if (strncmp (line, "router-id", strlen ("router-id")) == 0)
|
else if (strncmp (line, "router-id", strlen ("router-id")) == 0)
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
#include "zebra.h"
|
#include "zebra.h"
|
||||||
|
|
||||||
|
#include "lib/ns.h"
|
||||||
#include "lib/vrf.h"
|
#include "lib/vrf.h"
|
||||||
#include "lib/prefix.h"
|
#include "lib/prefix.h"
|
||||||
#include "lib/memory.h"
|
#include "lib/memory.h"
|
||||||
|
@ -86,6 +87,8 @@ zebra_ns_init (void)
|
||||||
{
|
{
|
||||||
dzns = XCALLOC (MTYPE_ZEBRA_NS, sizeof (struct zebra_ns));
|
dzns = XCALLOC (MTYPE_ZEBRA_NS, sizeof (struct zebra_ns));
|
||||||
|
|
||||||
|
ns_init ();
|
||||||
|
|
||||||
zebra_vrf_init ();
|
zebra_vrf_init ();
|
||||||
|
|
||||||
zebra_ns_enable (0, (void **)&dzns);
|
zebra_ns_enable (0, (void **)&dzns);
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#if !defined(__ZEBRA_NS_H__)
|
#if !defined(__ZEBRA_NS_H__)
|
||||||
#define __ZEBRA_NS_H__
|
#define __ZEBRA_NS_H__
|
||||||
|
|
||||||
|
#include <lib/ns.h>
|
||||||
|
|
||||||
#ifdef HAVE_NETLINK
|
#ifdef HAVE_NETLINK
|
||||||
/* Socket interface to kernel */
|
/* Socket interface to kernel */
|
||||||
struct nlsock
|
struct nlsock
|
||||||
|
@ -34,9 +36,6 @@ struct nlsock
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* NetNS ID type. */
|
|
||||||
typedef u_int16_t ns_id_t;
|
|
||||||
|
|
||||||
struct zebra_ns
|
struct zebra_ns
|
||||||
{
|
{
|
||||||
/* net-ns name. */
|
/* net-ns name. */
|
||||||
|
|
Loading…
Reference in a new issue