mirror of
https://github.com/systemd/systemd.git
synced 2025-06-06 05:07:17 +03:00
nspawn: add ipvlan support
This commit is contained in:
parent
c4a5ddc9f2
commit
4bbfe7ad22
@ -409,6 +409,30 @@
|
|||||||
container.</para></listitem>
|
container.</para></listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><option>-n</option></term>
|
<term><option>-n</option></term>
|
||||||
<term><option>--network-veth</option></term>
|
<term><option>--network-veth</option></term>
|
||||||
|
@ -180,6 +180,7 @@ static bool arg_register = true;
|
|||||||
static bool arg_keep_unit = false;
|
static bool arg_keep_unit = false;
|
||||||
static char **arg_network_interfaces = NULL;
|
static char **arg_network_interfaces = NULL;
|
||||||
static char **arg_network_macvlan = NULL;
|
static char **arg_network_macvlan = NULL;
|
||||||
|
static char **arg_network_ipvlan = NULL;
|
||||||
static bool arg_network_veth = false;
|
static bool arg_network_veth = false;
|
||||||
static const char *arg_network_bridge = NULL;
|
static const char *arg_network_bridge = NULL;
|
||||||
static unsigned long arg_personality = 0xffffffffLU;
|
static unsigned long arg_personality = 0xffffffffLU;
|
||||||
@ -211,6 +212,9 @@ static void help(void) {
|
|||||||
" --network-macvlan=INTERFACE\n"
|
" --network-macvlan=INTERFACE\n"
|
||||||
" Create a macvlan network interface based on an\n"
|
" Create a macvlan network interface based on an\n"
|
||||||
" existing network interface to the container\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"
|
" -n --network-veth Add a virtual ethernet connection between host\n"
|
||||||
" and container\n"
|
" and container\n"
|
||||||
" --network-bridge=INTERFACE\n"
|
" --network-bridge=INTERFACE\n"
|
||||||
@ -285,6 +289,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_KEEP_UNIT,
|
ARG_KEEP_UNIT,
|
||||||
ARG_NETWORK_INTERFACE,
|
ARG_NETWORK_INTERFACE,
|
||||||
ARG_NETWORK_MACVLAN,
|
ARG_NETWORK_MACVLAN,
|
||||||
|
ARG_NETWORK_IPVLAN,
|
||||||
ARG_NETWORK_BRIDGE,
|
ARG_NETWORK_BRIDGE,
|
||||||
ARG_PERSONALITY,
|
ARG_PERSONALITY,
|
||||||
ARG_VOLATILE,
|
ARG_VOLATILE,
|
||||||
@ -319,6 +324,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "keep-unit", no_argument, NULL, ARG_KEEP_UNIT },
|
{ "keep-unit", no_argument, NULL, ARG_KEEP_UNIT },
|
||||||
{ "network-interface", required_argument, NULL, ARG_NETWORK_INTERFACE },
|
{ "network-interface", required_argument, NULL, ARG_NETWORK_INTERFACE },
|
||||||
{ "network-macvlan", required_argument, NULL, ARG_NETWORK_MACVLAN },
|
{ "network-macvlan", required_argument, NULL, ARG_NETWORK_MACVLAN },
|
||||||
|
{ "network-ipvlan", required_argument, NULL, ARG_NETWORK_IPVLAN },
|
||||||
{ "network-veth", no_argument, NULL, 'n' },
|
{ "network-veth", no_argument, NULL, 'n' },
|
||||||
{ "network-bridge", required_argument, NULL, ARG_NETWORK_BRIDGE },
|
{ "network-bridge", required_argument, NULL, ARG_NETWORK_BRIDGE },
|
||||||
{ "personality", required_argument, NULL, ARG_PERSONALITY },
|
{ "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)
|
if (strv_extend(&arg_network_macvlan, optarg) < 0)
|
||||||
return log_oom();
|
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 */
|
/* fall through */
|
||||||
|
|
||||||
case ARG_PRIVATE_NETWORK:
|
case ARG_PRIVATE_NETWORK:
|
||||||
@ -2381,6 +2394,87 @@ static int setup_macvlan(pid_t pid) {
|
|||||||
return 0;
|
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) {
|
static int setup_seccomp(void) {
|
||||||
|
|
||||||
#ifdef HAVE_SECCOMP
|
#ifdef HAVE_SECCOMP
|
||||||
@ -4044,6 +4138,10 @@ int main(int argc, char *argv[]) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
|
r = setup_ipvlan(pid);
|
||||||
|
if (r < 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
r = register_machine(pid, ifi);
|
r = register_machine(pid, ifi);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
@ -4201,6 +4299,7 @@ finish:
|
|||||||
strv_free(arg_setenv);
|
strv_free(arg_setenv);
|
||||||
strv_free(arg_network_interfaces);
|
strv_free(arg_network_interfaces);
|
||||||
strv_free(arg_network_macvlan);
|
strv_free(arg_network_macvlan);
|
||||||
|
strv_free(arg_network_ipvlan);
|
||||||
strv_free(arg_bind);
|
strv_free(arg_bind);
|
||||||
strv_free(arg_bind_ro);
|
strv_free(arg_bind_ro);
|
||||||
strv_free(arg_tmpfs);
|
strv_free(arg_tmpfs);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user