summaryrefslogtreecommitdiffstats
path: root/src/vmspawn
diff options
context:
space:
mode:
authorSam Leonard <sam.leonard@codethink.co.uk>2024-04-12 16:46:04 +0200
committerSam Leonard <sam.leonard@codethink.co.uk>2024-04-15 12:42:06 +0200
commitc3dd4e20fe5d070dec6e789109ef6bdd41796ec3 (patch)
tree2e60f604fcc47344e0d06142301b226244bf68c0 /src/vmspawn
parentnspawn,shared/netif-util: move generate_mac and shorten_ifname to shared/neti... (diff)
downloadsystemd-c3dd4e20fe5d070dec6e789109ef6bdd41796ec3.tar.xz
systemd-c3dd4e20fe5d070dec6e789109ef6bdd41796ec3.zip
vmspawn: generate predicatable TAP device names and MAC addresses
Diffstat (limited to 'src/vmspawn')
-rw-r--r--src/vmspawn/vmspawn.c53
1 files changed, 50 insertions, 3 deletions
diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c
index fea154ae1f..0eba456971 100644
--- a/src/vmspawn/vmspawn.c
+++ b/src/vmspawn/vmspawn.c
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include <net/if.h>
+#include <linux/if.h>
#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
@@ -24,6 +26,7 @@
#include "discover-image.h"
#include "dissect-image.h"
#include "escape.h"
+#include "ether-addr-util.h"
#include "event-util.h"
#include "extract-word.h"
#include "fd-util.h"
@@ -40,6 +43,7 @@
#include "macro.h"
#include "main-func.h"
#include "mkdir.h"
+#include "netif-util.h"
#include "pager.h"
#include "parse-argument.h"
#include "parse-util.h"
@@ -65,6 +69,8 @@
#include "vmspawn-settings.h"
#include "vmspawn-util.h"
+#define VM_TAP_HASH_KEY SD_ID128_MAKE(01,d0,c6,4c,2b,df,24,fb,c0,f8,b2,09,7d,59,b2,93)
+
static bool arg_quiet = false;
static PagerFlags arg_pager_flags = 0;
static char *arg_directory = NULL;
@@ -98,6 +104,7 @@ static char *arg_background = NULL;
static bool arg_pass_ssh_key = true;
static char *arg_ssh_key_type = NULL;
static bool arg_discard_disk = true;
+struct ether_addr arg_network_provided_mac = {};
STATIC_DESTRUCTOR_REGISTER(arg_directory, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
@@ -188,6 +195,20 @@ static int help(void) {
return 0;
}
+static int parse_environment(void) {
+ const char *e;
+ int r;
+
+ e = getenv("SYSTEMD_VMSPAWN_NETWORK_MAC");
+ if (e) {
+ r = parse_ether_addr(e, &arg_network_provided_mac);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse provided MAC address via environment variable");
+ }
+
+ return 0;
+}
+
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
@@ -1287,9 +1308,31 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
}
}
- if (arg_network_stack == NETWORK_STACK_TAP)
- r = strv_extend_many(&cmdline, "-nic", "tap,script=no,model=virtio-net-pci");
- else if (arg_network_stack == NETWORK_STACK_USER)
+ if (arg_network_stack == NETWORK_STACK_TAP) {
+ _cleanup_free_ char *tap_name = NULL;
+ struct ether_addr mac_vm = {};
+
+ tap_name = strjoin("tp-", arg_machine);
+ if (!tap_name)
+ return log_oom();
+
+ (void) net_shorten_ifname(tap_name, /* check_naming_scheme= */ false);
+
+ if (ether_addr_is_null(&arg_network_provided_mac)){
+ r = net_generate_mac(arg_machine, &mac_vm, VM_TAP_HASH_KEY, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate predictable MAC address for VM side: %m");
+ } else
+ mac_vm = arg_network_provided_mac;
+
+ r = strv_extend(&cmdline, "-nic");
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&cmdline, "tap,ifname=%s,script=no,model=virtio-net-pci,mac=%s", tap_name, ETHER_ADDR_TO_STR(&mac_vm));
+ if (r < 0)
+ return log_oom();
+ } else if (arg_network_stack == NETWORK_STACK_USER)
r = strv_extend_many(&cmdline, "-nic", "user,model=virtio-net-pci");
else
r = strv_extend_many(&cmdline, "-nic", "none");
@@ -2014,6 +2057,10 @@ static int run(int argc, char *argv[]) {
/* don't attempt to register as a machine when running as a user */
arg_register = arg_privileged;
+ r = parse_environment();
+ if (r < 0)
+ return r;
+
r = parse_argv(argc, argv);
if (r <= 0)
return r;