Skip to content

Commit

Permalink
Merge pull request #4 from balena-io-experimental/kyle/kernel-ip
Browse files Browse the repository at this point in the history
Use kernel command line to initialize network
  • Loading branch information
flowzone-app[bot] authored Oct 12, 2023
2 parents 8763555 + 73c6306 commit 4d1ebdf
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 44 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
22 changes: 0 additions & 22 deletions overlay/sbin/init
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
60 changes: 40 additions & 20 deletions start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 '.' ' ')
Expand Down Expand Up @@ -226,50 +244,52 @@ 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
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

Expand Down

0 comments on commit 4d1ebdf

Please sign in to comment.