forked from Mirror/frr
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 \
|
||||
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 Determine routing get and set method
|
||||
dnl ------------------------------------
|
||||
|
|
|
@ -2902,6 +2902,7 @@ DEFUN (config_exit,
|
|||
vty_config_unlock (vty);
|
||||
break;
|
||||
case INTERFACE_NODE:
|
||||
case NS_NODE:
|
||||
case VRF_NODE:
|
||||
case ZEBRA_NODE:
|
||||
case BGP_NODE:
|
||||
|
@ -2960,6 +2961,7 @@ DEFUN (config_end,
|
|||
break;
|
||||
case CONFIG_NODE:
|
||||
case INTERFACE_NODE:
|
||||
case NS_NODE:
|
||||
case VRF_NODE:
|
||||
case ZEBRA_NODE:
|
||||
case RIP_NODE:
|
||||
|
|
|
@ -74,6 +74,7 @@ enum node_type
|
|||
AAA_NODE, /* AAA node. */
|
||||
KEYCHAIN_NODE, /* Key-chain node. */
|
||||
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
|
||||
NS_NODE, /* Logical-Router node. */
|
||||
VRF_NODE, /* VRF mode node. */
|
||||
INTERFACE_NODE, /* Interface mode node. */
|
||||
ZEBRA_NODE, /* zebra connection node. */
|
||||
|
|
247
lib/ns.c
247
lib/ns.c
|
@ -22,6 +22,13 @@
|
|||
|
||||
#include <zebra.h>
|
||||
|
||||
#ifdef HAVE_NETNS
|
||||
#undef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#include "if.h"
|
||||
#include "ns.h"
|
||||
#include "prefix.h"
|
||||
|
@ -29,14 +36,43 @@
|
|||
#include "log.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"
|
||||
|
||||
#endif /* HAVE_NETNS */
|
||||
|
||||
struct ns
|
||||
{
|
||||
/* Identifier, same as the vector index */
|
||||
ns_id_t ns_id;
|
||||
/* Name */
|
||||
char *name;
|
||||
/* File descriptor */
|
||||
int fd;
|
||||
|
||||
/* Master list of interfaces belonging to this NS */
|
||||
struct list *iflist;
|
||||
|
@ -90,6 +126,7 @@ ns_get (ns_id_t ns_id)
|
|||
|
||||
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
|
||||
ns->ns_id = ns_id;
|
||||
ns->fd = -1;
|
||||
rn->info = ns;
|
||||
|
||||
/*
|
||||
|
@ -114,8 +151,7 @@ ns_delete (struct ns *ns)
|
|||
{
|
||||
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)
|
||||
(*ns_master.ns_delete_hook) (ns->ns_id, &ns->info);
|
||||
|
@ -158,7 +194,11 @@ ns_lookup (ns_id_t ns_id)
|
|||
static int
|
||||
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
|
||||
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)
|
||||
(*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);
|
||||
|
||||
/* Till now, nothing to be done for the default NS. */
|
||||
|
||||
if (ns_master.ns_disable_hook)
|
||||
(*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;
|
||||
}
|
||||
|
||||
#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. */
|
||||
void
|
||||
ns_init (void)
|
||||
|
@ -464,6 +661,13 @@ ns_init (void)
|
|||
zlog_err ("ns_init: failed to enable the default NS!");
|
||||
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. */
|
||||
|
@ -485,19 +689,26 @@ ns_terminate (void)
|
|||
int
|
||||
ns_socket (int domain, int type, int protocol, ns_id_t ns_id)
|
||||
{
|
||||
struct ns *ns = ns_lookup (ns_id);
|
||||
int ret = -1;
|
||||
|
||||
if (!ns_is_enabled (ns_lookup (ns_id)))
|
||||
if (!ns_is_enabled (ns))
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ns_id == NS_DEFAULT)
|
||||
ret = socket (domain, type, protocol);
|
||||
else
|
||||
errno = ENOSYS;
|
||||
#ifdef HAVE_NETNS
|
||||
ret = (ns_id != NS_DEFAULT) ? setns (ns->fd, CLONE_NEWNET) : 0;
|
||||
if (ret >= 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
2
lib/ns.h
2
lib/ns.h
|
@ -33,7 +33,7 @@ typedef u_int16_t ns_id_t;
|
|||
/*
|
||||
* The command strings
|
||||
*/
|
||||
|
||||
#define NS_RUN_DIR "/var/run/netns"
|
||||
#define NS_CMD_STR "logical-router <0-65535>"
|
||||
#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/filter.c $(top_srcdir)/lib/plist.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/vty.c $(top_srcdir)/zebra/debug.c \
|
||||
$(top_srcdir)/lib/ns.c \
|
||||
$(top_srcdir)/zebra/interface.c \
|
||||
$(top_srcdir)/zebra/irdp_interface.c \
|
||||
$(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \
|
||||
|
|
|
@ -129,6 +129,9 @@ foreach (@ARGV) {
|
|||
elsif ($file =~ /lib\/filter\.c$/) {
|
||||
$protocol = "VTYSH_ALL";
|
||||
}
|
||||
elsif ($file =~ /lib\/ns\.c$/) {
|
||||
$protocol = "VTYSH_ZEBRA";
|
||||
}
|
||||
elsif ($file =~ /lib\/plist\.c$/) {
|
||||
if ($defun_array[1] =~ m/ipv6/) {
|
||||
$protocol = "VTYSH_RIPNGD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA";
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "vtysh/vtysh.h"
|
||||
#include "log.h"
|
||||
#include "bgpd/bgp_vty.h"
|
||||
#include "ns.h"
|
||||
#include "vrf.h"
|
||||
|
||||
/* Struct VTY. */
|
||||
|
@ -936,6 +937,12 @@ static struct cmd_node interface_node =
|
|||
"%s(config-if)# ",
|
||||
};
|
||||
|
||||
static struct cmd_node ns_node =
|
||||
{
|
||||
NS_NODE,
|
||||
"%s(config-logical-router)# ",
|
||||
};
|
||||
|
||||
static struct cmd_node vrf_node =
|
||||
{
|
||||
VRF_NODE,
|
||||
|
@ -1391,6 +1398,7 @@ vtysh_exit (struct vty *vty)
|
|||
vty->node = ENABLE_NODE;
|
||||
break;
|
||||
case INTERFACE_NODE:
|
||||
case NS_NODE:
|
||||
case VRF_NODE:
|
||||
case ZEBRA_NODE:
|
||||
case BGP_NODE:
|
||||
|
@ -1622,6 +1630,19 @@ DEFSH (VTYSH_ZEBRA,
|
|||
"Interface's name\n"
|
||||
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,
|
||||
vtysh_vrf,
|
||||
vtysh_vrf_cmd,
|
||||
|
@ -1640,6 +1661,20 @@ DEFSH (VTYSH_ZEBRA,
|
|||
"Delete a pseudo vrf's configuration\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,
|
||||
vtysh_exit_vrf,
|
||||
vtysh_exit_vrf_cmd,
|
||||
|
@ -2864,6 +2899,7 @@ vtysh_init_vty (void)
|
|||
install_node (&rip_node, NULL);
|
||||
install_node (&interface_node, NULL);
|
||||
install_node (&link_params_node, NULL);
|
||||
install_node (&ns_node, NULL);
|
||||
install_node (&vrf_node, NULL);
|
||||
install_node (&rmap_node, NULL);
|
||||
install_node (&zebra_node, NULL);
|
||||
|
@ -2894,6 +2930,7 @@ vtysh_init_vty (void)
|
|||
vtysh_install_default (RIP_NODE);
|
||||
vtysh_install_default (INTERFACE_NODE);
|
||||
vtysh_install_default (LINK_PARAMS_NODE);
|
||||
vtysh_install_default (NS_NODE);
|
||||
vtysh_install_default (VRF_NODE);
|
||||
vtysh_install_default (RMAP_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 (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_exit_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_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_NS VTYSH_ZEBRA
|
||||
#define VTYSH_VRF VTYSH_ZEBRA
|
||||
|
||||
/* vtysh local configuration file. */
|
||||
|
|
|
@ -171,6 +171,7 @@ vtysh_config_parse_line (const char *line)
|
|||
{
|
||||
if (config->index == RMAP_NODE ||
|
||||
config->index == INTERFACE_NODE ||
|
||||
config->index == NS_NODE ||
|
||||
config->index == VRF_NODE ||
|
||||
config->index == VTY_NODE)
|
||||
config_add_line_uniq (config->line, line);
|
||||
|
@ -183,6 +184,8 @@ vtysh_config_parse_line (const char *line)
|
|||
default:
|
||||
if (strncmp (line, "interface", strlen ("interface")) == 0)
|
||||
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)
|
||||
config = config_get (VRF_NODE, line);
|
||||
else if (strncmp (line, "router-id", strlen ("router-id")) == 0)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
#include "zebra.h"
|
||||
|
||||
#include "lib/ns.h"
|
||||
#include "lib/vrf.h"
|
||||
#include "lib/prefix.h"
|
||||
#include "lib/memory.h"
|
||||
|
@ -86,6 +87,8 @@ zebra_ns_init (void)
|
|||
{
|
||||
dzns = XCALLOC (MTYPE_ZEBRA_NS, sizeof (struct zebra_ns));
|
||||
|
||||
ns_init ();
|
||||
|
||||
zebra_vrf_init ();
|
||||
|
||||
zebra_ns_enable (0, (void **)&dzns);
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#if !defined(__ZEBRA_NS_H__)
|
||||
#define __ZEBRA_NS_H__
|
||||
|
||||
#include <lib/ns.h>
|
||||
|
||||
#ifdef HAVE_NETLINK
|
||||
/* Socket interface to kernel */
|
||||
struct nlsock
|
||||
|
@ -34,9 +36,6 @@ struct nlsock
|
|||
};
|
||||
#endif
|
||||
|
||||
/* NetNS ID type. */
|
||||
typedef u_int16_t ns_id_t;
|
||||
|
||||
struct zebra_ns
|
||||
{
|
||||
/* net-ns name. */
|
||||
|
|
Loading…
Reference in a new issue