1
0
mirror of https://github.com/lxc/incus.git synced 2026-02-05 09:46:19 +01:00
Files
incus/test/suites/container_devices_nic_p2p.sh
2026-01-22 23:46:03 +00:00

396 lines
14 KiB
Bash

test_container_devices_nic_p2p() {
ensure_import_testimage
ensure_has_localhost_remote "${INCUS_ADDR}"
vethHostName="veth$$"
ctName="nt$$"
ctMAC="0a:92:a7:0d:b7:d9"
ipRand=$(shuf -i 0-9 -n 1)
# Record how many nics we started with.
startNicCount=$(find /sys/class/net | wc -l)
# Test pre-launch profile config is applied at launch.
incus profile copy default ${ctName}
incus profile device set ${ctName} eth0 ipv4.routes "192.0.2.1${ipRand}/32"
incus profile device set ${ctName} eth0 ipv6.routes "2001:db8::1${ipRand}/128"
incus profile device set ${ctName} eth0 limits.ingress 1Mbit
incus profile device set ${ctName} eth0 limits.egress 2Mbit
incus profile device set ${ctName} eth0 host_name "${vethHostName}"
incus profile device set ${ctName} eth0 mtu "1400"
incus profile device set ${ctName} eth0 hwaddr "${ctMAC}"
incus profile device set ${ctName} eth0 nictype "p2p"
incus launch testimage "${ctName}" -p ${ctName}
# Check profile routes are applied on boot.
if ! ip -4 r list dev "${vethHostName}" | grep "192.0.2.1${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list dev "${vethHostName}" | grep "2001:db8::1${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
# Check profile limits are applied on boot.
if ! tc class show dev "${vethHostName}" | grep "1Mbit"; then
echo "limits.ingress invalid"
false
fi
if ! tc filter show dev "${vethHostName}" egress | grep "2Mbit"; then
echo "limits.egress invalid"
false
fi
# Check profile custom MTU is applied in container on boot.
if ! incus exec "${ctName}" -- grep "1400" /sys/class/net/eth0/mtu; then
echo "container veth mtu invalid"
false
fi
# Check profile custom MTU is applied on host-side on boot.
if ! grep "1400" /sys/class/net/"${vethHostName}"/mtu; then
echo "host veth mtu invalid"
false
fi
# Check profile custom MAC is applied in container on boot.
if ! incus exec "${ctName}" -- grep -Fix "${ctMAC}" /sys/class/net/eth0/address; then
echo "mac invalid"
false
fi
# Add IP alias to container and check routes actually work.
ip -4 addr add 192.0.2.1/32 dev "${vethHostName}"
incus exec "${ctName}" -- ip -4 addr add "192.0.2.1${ipRand}/32" dev eth0
incus exec "${ctName}" -- ip -4 route add default dev eth0
wait_for_dad "${ctName}" eth0
ping -c2 -W5 "192.0.2.1${ipRand}"
ip -6 addr add 2001:db8::1/128 dev "${vethHostName}"
incus exec "${ctName}" -- ip -6 addr add "2001:db8::1${ipRand}/128" dev eth0
incus exec "${ctName}" -- ip -6 route add default dev eth0
wait_for_dad "${ctName}" eth0
ping6 -c2 -W5 "2001:db8::1${ipRand}"
# Test hot plugging a container nic with different settings to profile with the same name.
incus config device add "${ctName}" eth0 nic \
nictype=p2p \
name=eth0 \
ipv4.routes="192.0.2.3${ipRand}/32" \
ipv6.routes="2001:db8::3${ipRand}/128" \
limits.ingress=3Mbit \
limits.egress=4Mbit \
host_name="${vethHostName}p2p" \
hwaddr="${ctMAC}" \
mtu=1401
# Check routes are applied on hot-plug.
if ! ip -4 r list dev "${vethHostName}p2p" | grep "192.0.2.3${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list dev "${vethHostName}p2p" | grep "2001:db8::3${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
# Check limits are applied on hot-plug.
if ! tc class show dev "${vethHostName}p2p" | grep "3Mbit"; then
echo "limits.ingress invalid"
false
fi
if ! tc filter show dev "${vethHostName}p2p" egress | grep "4Mbit"; then
echo "limits.egress invalid"
false
fi
# Check custom MTU is applied on hot-plug.
if ! incus exec "${ctName}" -- grep "1401" /sys/class/net/eth0/mtu; then
echo "container veth mtu invalid"
false
fi
# Check custom MTU is applied on host-side on hot-plug.
if ! grep "1401" /sys/class/net/"${vethHostName}p2p"/mtu; then
echo "host veth mtu invalid"
false
fi
# Check custom MAC is applied on hot-plug.
if ! incus exec "${ctName}" -- grep -Fix "${ctMAC}" /sys/class/net/eth0/address; then
echo "mac invalid"
false
fi
# Test removing hot plugged device and check profile nic is restored.
incus config device remove "${ctName}" eth0
# Check profile routes are applied on hot-removal.
if ! ip -4 r list dev "${vethHostName}" | grep "192.0.2.1${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list dev "${vethHostName}" | grep "2001:db8::1${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! tc class show dev "${vethHostName}" | grep "1Mbit"; then
echo "limits.ingress invalid"
false
fi
# Check profile limits are applied on hot-removal.
if ! tc filter show dev "${vethHostName}" egress | grep "2Mbit"; then
echo "limits.egress invalid"
false
fi
# Check profile custom MTU is applied on hot-removal.
if ! incus exec "${ctName}" -- grep "1400" /sys/class/net/eth0/mtu; then
echo "container veth mtu invalid"
false
fi
# Check profile custom MTU is applied on host-side on hot-removal.
if ! grep "1400" /sys/class/net/"${vethHostName}"/mtu; then
echo "host veth mtu invalid"
false
fi
# Test hot plugging a container nic then updating it.
incus config device add "${ctName}" eth0 nic \
nictype=p2p \
name=eth0 \
host_name="${vethHostName}"
incus config device set "${ctName}" eth0 ipv4.routes "192.0.2.2${ipRand}/32"
incus config device set "${ctName}" eth0 ipv6.routes "2001:db8::2${ipRand}/128"
incus config device set "${ctName}" eth0 limits.ingress 3Mbit
incus config device set "${ctName}" eth0 limits.egress 4Mbit
incus config device set "${ctName}" eth0 mtu 1402
incus config device set "${ctName}" eth0 hwaddr "${ctMAC}"
# Check routes are applied on update.
if ! ip -4 r list dev "${vethHostName}" | grep "192.0.2.2${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list dev "${vethHostName}" | grep "2001:db8::2${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
# Check limits are applied on update.
if ! tc class show dev "${vethHostName}" | grep "3Mbit"; then
echo "limits.ingress invalid"
false
fi
if ! tc filter show dev "${vethHostName}" egress | grep "4Mbit"; then
echo "limits.egress invalid"
false
fi
# Check custom MTU is applied update.
if ! incus exec "${ctName}" -- grep "1402" /sys/class/net/eth0/mtu; then
echo "mtu invalid"
false
fi
# Check custom MAC is applied update.
if ! incus exec "${ctName}" -- grep -Fix "${ctMAC}" /sys/class/net/eth0/address; then
echo "mac invalid"
false
fi
# Cleanup.
incus config device remove "${ctName}" eth0
incus delete "${ctName}" -f
incus profile delete "${ctName}"
# Test adding a p2p device to a running container without host_name and no limits/routes.
incus launch testimage "${ctName}"
incus config device add "${ctName}" eth0 nic \
nictype=p2p
# Now add some routes
incus config device set "${ctName}" eth0 ipv4.routes "192.0.2.2${ipRand}/32"
incus config device set "${ctName}" eth0 ipv6.routes "2001:db8::2${ipRand}/128"
# Check routes are applied on update. The host name is dynamic, so just check routes exist.
if ! ip -4 r list | grep "192.0.2.2${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list | grep "2001:db8::2${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Now update routes, check old routes go and new routes added.
incus config device set "${ctName}" eth0 ipv4.routes "192.0.2.3${ipRand}/32"
incus config device set "${ctName}" eth0 ipv6.routes "2001:db8::3${ipRand}/128"
# Check routes are applied on update. The host name is dynamic, so just check routes exist.
if ! ip -4 r list | grep "192.0.2.3${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list | grep "2001:db8::3${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Check old routes removed
if ip -4 r list | grep "192.0.2.2${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ip -6 r list | grep "2001:db8::2${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Now remove device, check routes go
incus config device remove "${ctName}" eth0
if ip -4 r list | grep "192.0.2.3${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ip -6 r list | grep "2001:db8::3${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Check volatile cleanup on stop.
incus stop -f "${ctName}"
if incus config show "${ctName}" | grep volatile.eth0 | grep -v volatile.eth0.hwaddr; then
echo "unexpected volatile key remains"
false
fi
# Now add a nic to a stopped container with routes.
incus config device add "${ctName}" eth0 nic \
nictype=p2p \
ipv4.routes="192.0.2.2${ipRand}/32" \
ipv6.routes="2001:db8::2${ipRand}/128"
incus start "${ctName}"
# Check routes are applied on start. The host name is dynamic, so just check routes exist.
if ! ip -4 r list | grep "192.0.2.2${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list | grep "2001:db8::2${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Now update routes on boot time nic, check old routes go and new routes added.
incus config device set "${ctName}" eth0 ipv4.routes "192.0.2.3${ipRand}/32"
incus config device set "${ctName}" eth0 ipv6.routes "2001:db8::3${ipRand}/128"
# Check routes are applied on update. The host name is dynamic, so just check routes exist.
if ! ip -4 r list | grep "192.0.2.3${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list | grep "2001:db8::3${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Check old routes removed
if ip -4 r list | grep "192.0.2.2${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ip -6 r list | grep "2001:db8::2${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Now remove boot time device
incus config device remove "${ctName}" eth0
# Check old routes removed
if ip -4 r list | grep "192.0.2.3${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ip -6 r list | grep "2001:db8::3${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Add hot plug device with routes.
incus config device add "${ctName}" eth0 nic \
nictype=p2p
# Now update routes on hotplug nic
incus config device set "${ctName}" eth0 ipv4.routes "192.0.2.2${ipRand}/32"
incus config device set "${ctName}" eth0 ipv6.routes "2001:db8::2${ipRand}/128"
# Check routes are applied. The host name is dynamic, so just check routes exist.
if ! ip -4 r list | grep "192.0.2.2${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ! ip -6 r list | grep "2001:db8::2${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Now remove hotplug device
incus config device remove "${ctName}" eth0
# Check old routes removed
if ip -4 r list | grep "192.0.2.2${ipRand}"; then
echo "ipv4.routes invalid"
false
fi
if ip -6 r list | grep "2001:db8::2${ipRand}"; then
echo "ipv6.routes invalid"
false
fi
# Test hotplugging nic with new name (rather than updating existing nic).
incus config device add "${ctName}" eth1 nic nictype=p2p
incus config device remove "${ctName}" eth1
# Test attached and connected keys.
incus config device add "${ctName}" eth0 nic nictype=p2p name=eth0
incus exec "${ctName}" ip link set eth0 up
[ "$(incus file pull "${ctName}/sys/class/net/eth0/operstate" -)" = "up" ]
incus config device set "${ctName}" eth0 connected=false
incus exec "${ctName}" ip link set eth0 up
[ "$(incus file pull "${ctName}/sys/class/net/eth0/operstate" -)" = "down" ]
incus config device set "${ctName}" eth0 attached=false
! incus file pull "${ctName}/sys/class/net/eth0/operstate" - || false
incus config device set "${ctName}" eth0 connected=true
! incus file pull "${ctName}/sys/class/net/eth0/operstate" - || false
incus config device set "${ctName}" eth0 attached=true
incus exec "${ctName}" ip link set eth0 up
[ "$(incus file pull "${ctName}/sys/class/net/eth0/operstate" -)" = "up" ]
incus config device set "${ctName}" eth0 connected=false
incus exec "${ctName}" ip link set eth0 up
[ "$(incus file pull "${ctName}/sys/class/net/eth0/operstate" -)" = "down" ]
# Check that it survives a reboot.
incus restart "${ctName}"
incus exec "${ctName}" ip link set eth0 up
[ "$(incus file pull "${ctName}/sys/class/net/eth0/operstate" -)" = "down" ]
incus stop -f "${ctName}"
# Check we haven't left any NICS lying around.
endNicCount=$(find /sys/class/net | wc -l)
if [ "$startNicCount" != "$endNicCount" ]; then
echo "leftover NICS detected"
false
fi
incus delete "${ctName}" -f
}