nspawn: add ipvlan support
This commit is contained in:
parent
c4a5ddc9f2
commit
4bbfe7ad22
|
@ -409,6 +409,30 @@
|
|||
container.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--network-ipvlan=</option></term>
|
||||
|
||||
<listitem><para>Create a
|
||||
<literal>ipvlan</literal> interface
|
||||
of the specified Ethernet network
|
||||
interface and add it to the
|
||||
container. An
|
||||
<literal>ipvlan</literal> interface
|
||||
is a virtual interface, similar to a
|
||||
<literal>macvlan</literal> interface, which
|
||||
uses the same MAC address as the underlying
|
||||
interface. The interface
|
||||
in the container will be named after
|
||||
the interface on the host, prefixed
|
||||
with <literal>iv-</literal>. Note that
|
||||
<option>--network-ipvlan=</option>
|
||||
implies
|
||||
<option>--private-network</option>. This
|
||||
option may be used more than once to
|
||||
add multiple network interfaces to the
|
||||
container.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-n</option></term>
|
||||
<term><option>--network-veth</option></term>
|
||||
|
|
|
@ -180,6 +180,7 @@ static bool arg_register = true;
|
|||
static bool arg_keep_unit = false;
|
||||
static char **arg_network_interfaces = NULL;
|
||||
static char **arg_network_macvlan = NULL;
|
||||
static char **arg_network_ipvlan = NULL;
|
||||
static bool arg_network_veth = false;
|
||||
static const char *arg_network_bridge = NULL;
|
||||
static unsigned long arg_personality = 0xffffffffLU;
|
||||
|
@ -211,6 +212,9 @@ static void help(void) {
|
|||
" --network-macvlan=INTERFACE\n"
|
||||
" Create a macvlan network interface based on an\n"
|
||||
" existing network interface to the container\n"
|
||||
" --network-ipvlan=INTERFACE\n"
|
||||
" Create a ipvlan network interface based on an\n"
|
||||
" existing network interface to the container\n"
|
||||
" -n --network-veth Add a virtual ethernet connection between host\n"
|
||||
" and container\n"
|
||||
" --network-bridge=INTERFACE\n"
|
||||
|
@ -285,6 +289,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||
ARG_KEEP_UNIT,
|
||||
ARG_NETWORK_INTERFACE,
|
||||
ARG_NETWORK_MACVLAN,
|
||||
ARG_NETWORK_IPVLAN,
|
||||
ARG_NETWORK_BRIDGE,
|
||||
ARG_PERSONALITY,
|
||||
ARG_VOLATILE,
|
||||
|
@ -319,6 +324,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||
{ "keep-unit", no_argument, NULL, ARG_KEEP_UNIT },
|
||||
{ "network-interface", required_argument, NULL, ARG_NETWORK_INTERFACE },
|
||||
{ "network-macvlan", required_argument, NULL, ARG_NETWORK_MACVLAN },
|
||||
{ "network-ipvlan", required_argument, NULL, ARG_NETWORK_IPVLAN },
|
||||
{ "network-veth", no_argument, NULL, 'n' },
|
||||
{ "network-bridge", required_argument, NULL, ARG_NETWORK_BRIDGE },
|
||||
{ "personality", required_argument, NULL, ARG_PERSONALITY },
|
||||
|
@ -401,6 +407,13 @@ static int parse_argv(int argc, char *argv[]) {
|
|||
if (strv_extend(&arg_network_macvlan, optarg) < 0)
|
||||
return log_oom();
|
||||
|
||||
arg_private_network = true;
|
||||
break;
|
||||
|
||||
case ARG_NETWORK_IPVLAN:
|
||||
if (strv_extend(&arg_network_ipvlan, optarg) < 0)
|
||||
return log_oom();
|
||||
|
||||
/* fall through */
|
||||
|
||||
case ARG_PRIVATE_NETWORK:
|
||||
|
@ -2381,6 +2394,87 @@ static int setup_macvlan(pid_t pid) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int setup_ipvlan(pid_t pid) {
|
||||
_cleanup_udev_unref_ struct udev *udev = NULL;
|
||||
_cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
|
||||
char **i;
|
||||
int r;
|
||||
|
||||
if (!arg_private_network)
|
||||
return 0;
|
||||
|
||||
if (strv_isempty(arg_network_ipvlan))
|
||||
return 0;
|
||||
|
||||
r = sd_rtnl_open(&rtnl, 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to netlink: %m");
|
||||
|
||||
udev = udev_new();
|
||||
if (!udev) {
|
||||
log_error("Failed to connect to udev.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
STRV_FOREACH(i, arg_network_ipvlan) {
|
||||
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
|
||||
_cleanup_free_ char *n = NULL;
|
||||
int ifi;
|
||||
|
||||
ifi = parse_interface(udev, *i);
|
||||
if (ifi < 0)
|
||||
return ifi;
|
||||
|
||||
r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate netlink message: %m");
|
||||
|
||||
r = sd_rtnl_message_append_u32(m, IFLA_LINK, ifi);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add netlink interface index: %m");
|
||||
|
||||
n = strappend("iv-", *i);
|
||||
if (!n)
|
||||
return log_oom();
|
||||
|
||||
strshorten(n, IFNAMSIZ-1);
|
||||
|
||||
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, n);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add netlink interface name: %m");
|
||||
|
||||
r = sd_rtnl_message_append_u32(m, IFLA_NET_NS_PID, pid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add netlink namespace field: %m");
|
||||
|
||||
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open netlink container: %m");
|
||||
|
||||
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "ipvlan");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open netlink container: %m");
|
||||
|
||||
r = sd_rtnl_message_append_u16(m, IFLA_IPVLAN_MODE, IPVLAN_MODE_L2);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add ipvlan mode: %m");
|
||||
|
||||
r = sd_rtnl_message_close_container(m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to close netlink container: %m");
|
||||
|
||||
r = sd_rtnl_message_close_container(m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to close netlink container: %m");
|
||||
|
||||
r = sd_rtnl_call(rtnl, m, 0, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add new ipvlan interfaces: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_seccomp(void) {
|
||||
|
||||
#ifdef HAVE_SECCOMP
|
||||
|
@ -4044,6 +4138,10 @@ int main(int argc, char *argv[]) {
|
|||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = setup_ipvlan(pid);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = register_machine(pid, ifi);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
@ -4201,6 +4299,7 @@ finish:
|
|||
strv_free(arg_setenv);
|
||||
strv_free(arg_network_interfaces);
|
||||
strv_free(arg_network_macvlan);
|
||||
strv_free(arg_network_ipvlan);
|
||||
strv_free(arg_bind);
|
||||
strv_free(arg_bind_ro);
|
||||
strv_free(arg_tmpfs);
|
||||
|
|
Loading…
Reference in a new issue