Remove ability to override netns

This gives a lot of operational problems later. It's definitely reasonable
to be able to create tap interfaces in other namespaces, and this is
still possible (see below for syntax).

However, changing the runtime netns makes the netlink listener much more
complicated because it will have to listen on not just one netns, but all
of them, for netlink updates.

So, for now, let's remove the ability to set the namespace in the API.
Still possible:
- set at startup.conf in lcpng { netns <x> }
- force creating in 'lcpng create ... netns <x>'

This will nudge folks to create one singular namespace (say,
'dataplane', in the startup.conf), and then handle all netlink messages
in that namespace only.
This commit is contained in:
Pim van Pelt
2021-08-08 20:54:43 +02:00
parent f3fa25d897
commit ca273dc953
6 changed files with 47 additions and 88 deletions

28
lcpng.c
View File

@ -24,28 +24,28 @@
lcp_main_t lcp_main; lcp_main_t lcp_main;
u8 * u8 *
lcp_get_default_ns (void) lcp_get_netns (void)
{ {
lcp_main_t *lcpm = &lcp_main; lcp_main_t *lcpm = &lcp_main;
if (lcpm->default_namespace[0] == 0) if (lcpm->netns_name[0] == 0)
return 0; return 0;
return lcpm->default_namespace; return lcpm->netns_name;
} }
int int
lcp_get_default_ns_fd (void) lcp_get_netns_fd (void)
{ {
lcp_main_t *lcpm = &lcp_main; lcp_main_t *lcpm = &lcp_main;
return lcpm->default_ns_fd; return lcpm->netns_fd;
} }
/* /*
* ns is expected to be or look like a NUL-terminated C string. * ns is expected to be or look like a NUL-terminated C string.
*/ */
int int
lcp_set_default_ns (u8 *ns) lcp_set_netns (u8 *ns)
{ {
lcp_main_t *lcpm = &lcp_main; lcp_main_t *lcpm = &lcp_main;
char *p; char *p;
@ -59,18 +59,18 @@ lcp_set_default_ns (u8 *ns)
if (!p || *p == 0) if (!p || *p == 0)
{ {
clib_memset (lcpm->default_namespace, 0, clib_memset (lcpm->netns_name, 0,
sizeof (lcpm->default_namespace)); sizeof (lcpm->netns_name));
if (lcpm->default_ns_fd > 0) if (lcpm->netns_fd > 0)
close (lcpm->default_ns_fd); close (lcpm->netns_fd);
lcpm->default_ns_fd = 0; lcpm->netns_fd = 0;
return 0; return 0;
} }
clib_strncpy ((char *) lcpm->default_namespace, p, LCP_NS_LEN - 1); clib_strncpy ((char *) lcpm->netns_name, p, LCP_NS_LEN - 1);
s = format (0, "/var/run/netns/%s%c", (char *) lcpm->default_namespace, 0); s = format (0, "/var/run/netns/%s%c", (char *) lcpm->netns_name, 0);
lcpm->default_ns_fd = open ((char *) s, O_RDONLY); lcpm->netns_fd = open ((char *) s, O_RDONLY);
vec_free (s); vec_free (s);
return 0; return 0;

12
lcpng.h
View File

@ -22,8 +22,8 @@
typedef struct lcp_main_s typedef struct lcp_main_s
{ {
u16 msg_id_base; /* API message ID base */ u16 msg_id_base; /* API message ID base */
u8 default_namespace[LCP_NS_LEN]; /* default namespace if set */ u8 netns_name[LCP_NS_LEN]; /* namespace, if set */
int default_ns_fd; int netns_fd;
/* Set when Unit testing */ /* Set when Unit testing */
u8 test_mode; u8 test_mode;
} lcp_main_t; } lcp_main_t;
@ -31,11 +31,11 @@ typedef struct lcp_main_s
extern lcp_main_t lcp_main; extern lcp_main_t lcp_main;
/** /**
* Get/Set the default namespace for LCP host taps. * Get/Set the namespace in which to create LCP host taps.
*/ */
int lcp_set_default_ns (u8 *ns); int lcp_set_netns (u8 *ns);
u8 *lcp_get_default_ns (void); /* Returns NULL or shared string */ u8 *lcp_get_netns (void); /* Returns NULL or shared string */
int lcp_get_default_ns_fd (void); int lcp_get_netns_fd (void);
#endif #endif

View File

@ -21,34 +21,34 @@ option version = "1.0.0";
import "vnet/interface_types.api"; import "vnet/interface_types.api";
/** \brief Set the default Linux Control Plane namespace /** \brief Set the namespace for Linux Control Plane host taps
@param client_index - opaque cookie to identify the sender @param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request @param context - sender context, to match reply w/ request
@param namespace - the new default namespace; namespace[0] == 0 iff none @param namespace - the new namespace; namespace[0] == 0 iff none
*/ */
autoreply define lcp_default_ns_set autoreply define lcp_netns_set
{ {
u32 client_index; u32 client_index;
u32 context; u32 context;
string namespace[32]; /* LCP_NS_LEN */ string namespace[32]; /* LCP_NS_LEN */
}; };
/** \brief get the default Linux Control Plane namespace /** \brief get the Linux Control Plane namespace
@param client_index - opaque cookie to identify the sender @param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request @param context - sender context, to match reply w/ request
*/ */
define lcp_default_ns_get define lcp_netns_get
{ {
u32 client_index; u32 client_index;
u32 context; u32 context;
}; };
/** \brief get the default Linux Control Plane namespace /** \brief get the Linux Control Plane namespace
@param client_index - opaque cookie to identify the sender @param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request @param context - sender context, to match reply w/ request
@param namespace - the default namespace; namespace[0] == 0 iff none @param namespace - the namespace; namespace[0] == 0 iff none
*/ */
define lcp_default_ns_get_reply define lcp_netns_get_reply
{ {
u32 context; u32 context;
string namespace[32]; /* LCP_NS_LEN */ string namespace[32]; /* LCP_NS_LEN */

View File

@ -169,22 +169,22 @@ vl_api_lcp_itf_pair_get_t_handler (vl_api_lcp_itf_pair_get_t *mp)
} }
static void static void
vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp) vl_api_lcp_netns_set_t_handler (vl_api_lcp_netns_set_t *mp)
{ {
vl_api_lcp_default_ns_set_reply_t *rmp; vl_api_lcp_netns_set_reply_t *rmp;
int rv; int rv;
mp->namespace[LCP_NS_LEN - 1] = 0; mp->namespace[LCP_NS_LEN - 1] = 0;
rv = lcp_set_default_ns (mp->namespace); rv = lcp_set_netns (mp->namespace);
REPLY_MACRO (VL_API_LCP_DEFAULT_NS_SET_REPLY); REPLY_MACRO (VL_API_LCP_NETNS_SET_REPLY);
} }
static void static void
vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp) vl_api_lcp_netns_get_t_handler (vl_api_lcp_netns_get_t *mp)
{ {
lcp_main_t *lcpm = &lcp_main; lcp_main_t *lcpm = &lcp_main;
vl_api_lcp_default_ns_get_reply_t *rmp; vl_api_lcp_netns_get_reply_t *rmp;
vl_api_registration_t *reg; vl_api_registration_t *reg;
char *ns; char *ns;
@ -194,10 +194,10 @@ vl_api_lcp_default_ns_get_t_handler (vl_api_lcp_default_ns_get_t *mp)
rmp = vl_msg_api_alloc (sizeof (*rmp)); rmp = vl_msg_api_alloc (sizeof (*rmp));
clib_memset (rmp, 0, sizeof (*rmp)); clib_memset (rmp, 0, sizeof (*rmp));
rmp->_vl_msg_id = (VL_API_LCP_DEFAULT_NS_GET_REPLY + lcpm->msg_id_base); rmp->_vl_msg_id = (VL_API_LCP_NETNS_GET_REPLY + lcpm->msg_id_base);
rmp->context = mp->context; rmp->context = mp->context;
ns = (char *) lcp_get_default_ns (); ns = (char *) lcp_get_netns ();
if (ns) if (ns)
clib_strncpy ((char *) rmp->namespace, ns, LCP_NS_LEN - 1); clib_strncpy ((char *) rmp->namespace, ns, LCP_NS_LEN - 1);

View File

@ -111,45 +111,6 @@ VLIB_CLI_COMMAND (lcp_itf_pair_create_command, static) = {
.function = lcp_itf_pair_create_command_fn, .function = lcp_itf_pair_create_command_fn,
}; };
static clib_error_t *
lcp_default_netns_command_fn (vlib_main_t *vm, unformat_input_t *input,
vlib_cli_command_t *cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
u8 *ns;
int r;
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
ns = 0;
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (line_input, "netns %s", &ns))
;
else if (unformat (line_input, "clear netns"))
;
}
unformat_free (line_input);
vlib_cli_output (vm, "lcp set default netns '%s'\n", (char *) ns);
r = lcp_set_default_ns (ns);
if (r)
return clib_error_return (0, "lcnpg set default netns failed (%d)", r);
return 0;
}
VLIB_CLI_COMMAND (lcp_default_netns_command, static) = {
.path = "lcpng default",
.short_help = "lcpng default netns [<namespace>]",
.function = lcp_default_netns_command_fn,
};
static clib_error_t * static clib_error_t *
lcp_itf_pair_delete_command_fn (vlib_main_t *vm, unformat_input_t *input, lcp_itf_pair_delete_command_fn (vlib_main_t *vm, unformat_input_t *input,
vlib_cli_command_t *cmd) vlib_cli_command_t *cmd)

View File

@ -133,8 +133,8 @@ lcp_itf_pair_show (u32 phy_sw_if_index)
index_t api; index_t api;
vm = vlib_get_main (); vm = vlib_get_main ();
ns = lcp_get_default_ns (); ns = lcp_get_netns ();
vlib_cli_output (vm, "lcp default netns '%s'\n", vlib_cli_output (vm, "lcpng netns '%s'\n",
ns ? (char *) ns : "<unset>"); ns ? (char *) ns : "<unset>");
if (phy_sw_if_index == ~0) if (phy_sw_if_index == ~0)
@ -516,9 +516,9 @@ lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input)
{ {
u8 *host, *phy; u8 *host, *phy;
u8 *ns; u8 *ns;
u8 *default_ns; u8 *netns;
host = phy = ns = default_ns = NULL; host = phy = ns = netns = NULL;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{ {
@ -552,14 +552,13 @@ lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input)
lipn->lipn_phy_name = vec_dup (phy); lipn->lipn_phy_name = vec_dup (phy);
lipn->lipn_namespace = 0; lipn->lipn_namespace = 0;
} }
else if (unformat (input, "default netns %v", &default_ns)) else if (unformat (input, "netns %v", &netns))
{ {
vec_add1 (default_ns, 0); vec_add1 (netns, 0);
if (lcp_set_default_ns (default_ns) < 0) if (lcp_set_netns (netns) < 0)
{ {
return clib_error_return (0, return clib_error_return (0,
"lcpng default namespace must" "lcpng namespace must be less than %d characters",
" be less than %d characters",
LCP_NS_LEN); LCP_NS_LEN);
} }
} }
@ -569,7 +568,7 @@ lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input)
vec_free (host); vec_free (host);
vec_free (phy); vec_free (phy);
vec_free (default_ns); vec_free (netns);
return NULL; return NULL;
} }
@ -663,11 +662,10 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name,
/* /*
* Use interface-specific netns if supplied. * Use interface-specific netns if supplied.
* Otherwise, use default netns if defined. * Otherwise, use netns if defined, otherwise use the OS default.
* Otherwise ignore a netns and use the OS default.
*/ */
if (ns == 0 || ns[0] == 0) if (ns == 0 || ns[0] == 0)
ns = lcp_get_default_ns (); ns = lcp_get_netns ();
/* sub interfaces do not need a tap created */ /* sub interfaces do not need a tap created */
if (vnet_sw_interface_is_sub (vnm, phy_sw_if_index)) if (vnet_sw_interface_is_sub (vnm, phy_sw_if_index))