1
0
mirror of https://github.com/systemd/systemd synced 2024-07-09 04:26:06 +00:00

vmspawn: generate predicatable TAP device names and MAC addresses

This commit is contained in:
Sam Leonard 2024-04-12 15:46:04 +01:00
parent c50e7dcaf6
commit c3dd4e20fe
No known key found for this signature in database
GPG Key ID: 96850F0978CE78F0
2 changed files with 58 additions and 3 deletions

View File

@ -183,6 +183,14 @@ All tools:
expected format is six groups of two hexadecimal digits separated by colons,
e.g. `SYSTEMD_NSPAWN_NETWORK_MAC=12:34:56:78:90:AB`
`systemd-vmspawn`:
* `$SYSTEMD_VMSPAWN_NETWORK_MAC=...` — if set, allows users to set a specific MAC
address for a VM, ensuring that it uses the provided value instead of
generating a random one. It is effective when used with `--network-tap`. The
expected format is six groups of two hexadecimal digits separated by colons,
e.g. `SYSTEMD_VMSPAWN_NETWORK_MAC=12:34:56:78:90:AB`
`systemd-logind`:
* `$SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1` — if set, report that

View File

@ -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;