From 73c6306075ada9c4cfbf5da57c57c2bb15e29497 Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Thu, 12 Oct 2023 15:46:26 -0400 Subject: [PATCH] Use kernel command line to initialize network Change-type: patch Signed-off-by: Kyle Harding --- README.md | 2 -- overlay/sbin/init | 22 ----------------- start.sh | 60 +++++++++++++++++++++++++++++++---------------- 3 files changed, 40 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 35ebc26..09fb14d 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,7 @@ Guest containers based on Alpine, Debian, and Ubuntu have been tested and must h available from a shell. - `sh` -- `ip` via `iproute2` - `mount` -- `awk` Distroless containers are not expected to work as the kernel init binary is a shell script. diff --git a/overlay/sbin/init b/overlay/sbin/init index 401d521..b06d13e 100644 --- a/overlay/sbin/init +++ b/overlay/sbin/init @@ -24,28 +24,6 @@ if ! mountpoint -q /run; then mount -t tmpfs none /run fi -# rngd -b - -# The IP is assigned by converting the last 4 hexa groups of the MAC into decimals. -# https://github.com/firecracker-microvm/firecracker/blob/main/resources/overlay/usr/local/bin/fcnet-setup.sh -for dev in $(ip link list | awk /'^[0-9]+:/ {print $2}' | sed 's/://'); do - dev="$(basename "$dev")" - case $dev in - *lo) continue ;; - esac - for octet in $( - ip link show dev "$dev" | - awk '/link\/ether/ {print $2}' | - awk -F: '{print $3" "$4" "$5" "$6}' - ); do - ip=$ip$(printf "%d" 0x"$octet"). - done - ip=${ip%?} - ip addr add "$ip/30" dev "$dev" - ip link set "$dev" up - ip route add default via "${ip%?}1" dev "$dev" -done - set +a # shellcheck disable=SC1091 . /etc/profile || true diff --git a/start.sh b/start.sh index 34b4072..721db9c 100644 --- a/start.sh +++ b/start.sh @@ -99,7 +99,8 @@ generate_config() { jq ".\"machine-config\".mem_size_mib = ${MEM_SIZE_MIB}" "${_dst_config}" >"${_dst_config}".tmp mv "${_dst_config}".tmp "${_dst_config}" - jq ".\"network-interfaces\"[0].iface_id = \"${GUEST_IFACE}\"" "${_dst_config}" >"${_dst_config}".tmp + # It doesn't seem to matter what we call this interface, it always shows up as 'eth0' in the guest + jq ".\"network-interfaces\"[0].iface_id = \"net0\"" "${_dst_config}" >"${_dst_config}".tmp mv "${_dst_config}".tmp "${_dst_config}" jq ".\"network-interfaces\"[0].guest_mac = \"${GUEST_MAC}\"" "${_dst_config}" >"${_dst_config}".tmp @@ -153,6 +154,23 @@ normalize_cidr() { echo "${_address}/${_short_netmask}" } +network_config() { + local _client_ip="${1}" + local _server_ip="" + local _gw_ip="${2}" + local _netmask + local _hostname="${3:-${HOSTNAME}}" + local _device="${4:-eth0}" + local _autoconf=off + + # normalize addresses to remove cidr suffix + _client_ip="$(ipcalc -nb "${_client_ip}" | awk '/^Address:/ {print $2}')" + _gw_ip="$(ipcalc -nb "${_gw_ip}" | awk '/^Address:/ {print $2}')" + _netmask="$(ipcalc -nb "${_client_ip}" | awk '/^Netmask:/ {print $2}')" + + echo "ip=${_client_ip}:${_server_ip}:${_gw_ip}:${_netmask}:${_hostname}:${_device}:${_autoconf}" +} + ip_to_mac() { # shellcheck disable=SC2183,SC2046 printf '52:54:%02X:%02X:%02X:%02X\n' $(echo "${1}" | tr '.' ' ') @@ -226,22 +244,10 @@ if [ -z "${DATAFS_SIZE:-}" ]; then DATAFS_SIZE=$(df -Ph . | tail -1 | awk '{print $4}') fi -if [ -z "${KERNEL_BOOT_ARGS:-}" ]; then - KERNEL_BOOT_ARGS="console=ttyS0 reboot=k panic=1 pci=off random.trust_cpu=on" - - if [ "$(uname -m)" = "aarch64" ]; then - KERNEL_BOOT_ARGS="keep_bootcon ${KERNEL_BOOT_ARGS}" - fi -fi - if [ -z "${HOST_IFACE:-}" ]; then HOST_IFACE="$(ip route | awk '/default/ {print $5}')" fi -if [ -z "${GUEST_IFACE:-}" ]; then - GUEST_IFACE="net0" -fi - if [ -z "${TAP_IP:-}" ]; then # generate random number between 1 and 254 TAP_IP=10.$((1 + RANDOM % 254)).$((1 + RANDOM % 254)).1/30 @@ -249,27 +255,41 @@ fi TAP_IP="$(normalize_cidr "${TAP_IP}")" +if [ -z "${GUEST_IP:-}" ]; then + # the default guest IP is the TAP IP + 1 + GUEST_IP="$(echo "${TAP_IP}" | awk -F'[./]' '{print $1"."$2"."$3"."$4+1}')" +fi + if [ -z "${TAP_DEVICE:-}" ]; then # must be less than 16 characters TAP_DEVICE="$(echo "${TAP_IP}" | awk -F'[./]' '{print "tap-"$1"-"$2"-"$3}')" fi if [ -z "${GUEST_MAC:-}" ]; then - # Guest MAC is '52:54' followed by the first 3 octets of the TAP IP, - # followed by the last octet of the TAP IP incremented by 1. - GUEST_MAC="$(ip_to_mac "$(echo "${TAP_IP}" | awk -F'[./]' '{print $1"."$2"."$3"."$4+1}')")" + # guest MAC is '52:54' followed by the hex encoded guest IP octets + GUEST_MAC="$(ip_to_mac "${GUEST_IP}")" fi -echo "VCPUs: ${VCPU_COUNT}" +if [ -z "${KERNEL_BOOT_ARGS:-}" ]; then + KERNEL_BOOT_ARGS="console=ttyS0 reboot=k panic=1 pci=off random.trust_cpu=on" + + if [ "$(uname -m)" = "aarch64" ]; then + KERNEL_BOOT_ARGS="keep_bootcon ${KERNEL_BOOT_ARGS}" + fi +fi + +KERNEL_BOOT_ARGS="${KERNEL_BOOT_ARGS} $(network_config "${GUEST_IP}" "${TAP_IP}" "$(hostname)" eth0)" + +echo "Virtual CPUs: ${VCPU_COUNT}" echo "Memory: ${MEM_SIZE_MIB}M" echo "Root Drive (vda): ${ROOTFS_SIZE}" echo "Data Drive (vdb): ${DATAFS_SIZE}" -echo "Kernel boot args: ${KERNEL_BOOT_ARGS}" echo "Host Interface: ${HOST_IFACE}" -echo "Guest Interface: ${GUEST_IFACE}" -echo "TAP Device ID: ${TAP_DEVICE}" +echo "TAP Device: ${TAP_DEVICE}" echo "TAP IP Address: ${TAP_IP}" +echo "Guest IP Address: ${GUEST_IP}" echo "Guest MAC Address: ${GUEST_MAC}" +echo "Kernel Boot Args: ${KERNEL_BOOT_ARGS}" trap cleanup EXIT