blob: 62d7b461d810476c6d9600aec21f4890f5565963 [file]
#!/usr/bin/env bash
#
# Copyright 2023 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -Eeuxo pipefail
# The IPv4 address must be in the subnet declared in
# `//src/connectivity/network/tests/integration/guest/dhcpv4/data/dhcpd.conf`.
# Likewise the IPv6 address must be in the subnet declared in
# `//src/connectivity/network/tests/integration/guest/dhcpv6/data/dhcpd.conf`.
declare -Ar ADDRS=( [4]="192.0.2.1/24" [6]="2001:db8::1/64" )
readonly DHCP_CONFIG_FILE="/etc/default/isc-dhcp-server"
# Mask and stop NetworkManager to prevent interference from the DHCPv4 client
# that it runs.
systemctl mask NetworkManager.service
systemctl stop NetworkManager.service
# Wait for on-boot systemd services to start, in particular this ensures that
# the instance of isc-dhcp-server started at boot has finished starting so that
# this script can successfully restart it while applying the desired
# configuration.
#
# Ignore the return code because some systemd services might fail to start
# and result in a non-zero exit code.
systemctl is-system-running --wait >/dev/null || true
# Stop the DHCP server so that we can restart it later with our own
# configuration.
systemctl stop isc-dhcp-server.service
declare -a ip
# Parse arguments:
# -4 enables DHCPv4 server.
# -6 enables DHCPv6 server.
while getopts "46" arg; do
case "${arg}" in
4)
ip+=(4)
;;
6)
ip+=(6)
;;
*)
echo "usage: ${0} [-46]" >&2
exit 1
;;
esac
done
# If run without an IP version argument, start server with both DHCPv4 and
# DHCPv6 enabled.
if [[ "${#ip[@]}" == 0 ]]; then
ip=(4 6)
fi
readonly ip
# The ethernet interface's name varies depending on the number of block devices
# that are added when starting the guest. Discover the interface name prior to
# configuration.
iface_name=""
for iface_path in /sys/class/net/*; do
candidate=$(basename "${iface_path}")
if [[ "${candidate}" != "lo" ]]; then
iface_name="${candidate}"
readonly iface_name
break
fi
done
if [[ -z "${iface_name}" ]]; then
echo "Unable to find an interface other than loopback" >&2
exit 1
fi
# Overwrite the default configuration file to enable DHCPv4 or DHCPv6 on the
# selected interface as appropriate.
#
# The interface also needs an IP address or else isc-dhcp-server will not
# start.
rm "${DHCP_CONFIG_FILE}"
for ip_version in "${ip[@]}"; do
echo "INTERFACESv${ip_version}=\"${iface_name}\"" >> "${DHCP_CONFIG_FILE}"
ip addr add dev "${iface_name}" "${ADDRS[${ip_version}]}"
done
ip link set "${iface_name}" up
if ! systemctl restart isc-dhcp-server; then
# If restarting fails, print out the logs to aid in troubleshooting.
journalctl -b --no-pager -u isc-dhcp-server >&2
exit 1
fi
systemctl is-active --quiet isc-dhcp-server