#!/usr/bin/env bats -*- bats -*- # # bridge driver tests with iptables firewall driver # load helpers fw_driver=iptables @test "check iptables driver is in use" { RUST_LOG=netavark=info run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json setup $(get_container_netns_path) assert "${lines[0]}" "==" "[INFO netavark::firewall] Using iptables firewall driver" "iptables driver is in use" } @test "$fw_driver - internal network" { run_in_host_netns iptables -t nat -nvL before="$output" run_netavark --file ${TESTSDIR}/testfiles/internal.json setup $(get_container_netns_path) run_in_host_netns iptables -t nat -nvL assert "$output" == "$before" "make sure tables have not changed" run_in_container_netns ip route show assert "$output" "!~" "default" "No default route for internal networks" run_in_container_netns ping -c 1 10.88.0.1 run_netavark --file ${TESTSDIR}/testfiles/internal.json teardown $(get_container_netns_path) } @test "$fw_driver - simple bridge" { run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json setup $(get_container_netns_path) result="$output" assert_json "$result" 'has("podman")' == "true" "object key exists" mac=$(jq -r '.podman.interfaces.eth0.mac_address' <<<"$result") # check that interface exists run_in_container_netns ip -j --details link show eth0 link_info="$output" assert_json "$link_info" ".[].address" == "$mac" "MAC matches container mac" assert_json "$link_info" '.[].flags[] | select(.=="UP")' == "UP" "Container interface is up" assert_json "$link_info" ".[].linkinfo.info_kind" == "veth" "Container interface is a veth device" ipaddr="10.88.0.2/16" run_in_container_netns ip addr show eth0 assert "$output" =~ "$ipaddr" "IP address matches container address" assert_json "$result" ".podman.interfaces.eth0.subnets[0].ipnet" == "$ipaddr" "Result contains correct IP address" run_in_host_netns ip -j --details link show podman0 link_info="$output" assert_json "$link_info" '.[].flags[] | select(.=="UP")' == "UP" "Host bridge interface is up" assert_json "$link_info" ".[].linkinfo.info_kind" == "bridge" "The bridge interface is actually a bridge" bridge_mac=$(jq -r '.[].address' <<<"$link_info") run_in_host_netns ip -j link show veth0 veth_info="$output" assert_json "$veth_info" ".[].address" != "$bridge_mac" "Bridge and Veth must have different mac address" ipaddr="10.88.0.1" run_in_host_netns ip addr show podman0 assert "$output" =~ "$ipaddr" "IP address matches bridge gateway address" assert_json "$result" ".podman.interfaces.eth0.subnets[0].gateway" == "$ipaddr" "Result contains gateway address" # check that the loopback adapter is up run_in_container_netns ip addr show lo assert "$output" =~ "127.0.0.1" "Loopback adapter is up (has address)" run_in_host_netns ping -c 1 10.88.0.2 check_simple_bridge_iptables run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json teardown $(get_container_netns_path) # now check that iptables rules are gone run_in_host_netns iptables -S # check FORWARD rules run_in_host_netns iptables -S FORWARD assert "${lines[1]}" == "-A FORWARD -m comment --comment \"netavark firewall rules\" -j NETAVARK_FORWARD" "FORWARD rule" assert "${#lines[@]}" = 2 "too many FORWARD rules after teardown" # rule 1 should be DROP for any existing networks run_in_host_netns iptables -S NETAVARK_FORWARD assert "${lines[1]}" == "-A NETAVARK_FORWARD -m conntrack --ctstate INVALID -j DROP" "NETAVARK_FORWARD rule 1" assert "${#lines[@]}" = 2 "too many NETAVARK_FORWARD rules after teardown" # check POSTROUTING nat rules run_in_host_netns iptables -S POSTROUTING -t nat assert "${lines[1]}" =~ "-A POSTROUTING -j NETAVARK-HOSTPORT-MASQ" "POSTROUTING HOSTPORT-MASQ rule" assert "${#lines[@]}" = 2 "too many POSTROUTING rules after teardown" # NETAVARK-1D8721804F16F chain should not exists expected_rc=1 run_in_host_netns iptables -nvL NETAVARK-1D8721804F16F -t nat # bridge should be removed on teardown expected_rc=1 run_in_host_netns ip addr show podman0 } @test "$fw_driver - bridge with static routes" { # add second interface and routes through that interface to test proper teardown run_in_container_netns ip link add type dummy run_in_container_netns ip a add 10.91.0.10/24 dev dummy0 run_in_container_netns ip link set dummy0 up run_netavark --file ${TESTSDIR}/testfiles/bridge-staticroutes.json setup $(get_container_netns_path) # check static routes run_in_container_netns ip r assert "$output" "=~" "10.89.0.0/24 via 10.88.0.2" "static route not set" assert "$output" "=~" "10.90.0.0/24 via 10.88.0.3" "static route not set" assert "$output" "=~" "10.92.0.0/24 via 10.91.0.1" "static route not set" run_netavark --file ${TESTSDIR}/testfiles/bridge-staticroutes.json teardown $(get_container_netns_path) # check static routes get removed assert "$output" "!~" "10.89.0.0/24 via 10.88.0.2" "static route not set" assert "$output" "!~" "10.90.0.0/24 via 10.88.0.3" "static route not set" assert "$output" "!~" "10.92.0.0/24 via 10.91.0.1" "static route not removed" } @test "$fw_driver - bridge with no default route" { run_netavark --file ${TESTSDIR}/testfiles/bridge-nodefaultroute.json setup $(get_container_netns_path) run_in_container_netns ip r assert "$output" "!~" "default" "default route exists" run_in_container_netns ip -6 r assert "$output" "!~" "default" "default route exists" run_netavark --file ${TESTSDIR}/testfiles/bridge-nodefaultroute.json teardown $(get_container_netns_path) assert "" "no errors" } @test "$fw_driver - bridge driver must generate config for aardvark with multiple custom dns server with network dns servers and perform update" { # get a random port directly to avoid low ports e.g. 53 would not create iptables dns_port=$((RANDOM+10000)) NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge-network-container-dns-server.json \ setup $(get_container_netns_path) # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1 127.0.0.1,3.3.3.3" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename 8.8.8.8,1.1.1.1$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" aardvark_pid=$(cat "$NETAVARK_TMPDIR/config/aardvark-dns/aardvark.pid") assert "$ardvark_pid" =~ "[0-9]*" "aardvark pid not found" run_helper ps "$aardvark_pid" assert "${lines[1]}" =~ ".*aardvark-dns --config $NETAVARK_TMPDIR/config/aardvark-dns -p $dns_port run" "aardvark not running or bad options" # Use run_helper instead of run_netavark here to check network namespace detection logic. # See https://github.com/containers/netavark/issues/911 for details. NETAVARK_DNS_PORT="$dns_port" run_helper $NETAVARK --config "$NETAVARK_TMPDIR/config" --rootless "$rootless" --file ${TESTSDIR}/testfiles/dualstack-bridge-network-container-dns-server.json \ update podman1 --network-dns-servers 8.8.8.8 assert "$output" = "" # after update the pid should never change aardvark_pid2=$(cat "$NETAVARK_TMPDIR/config/aardvark-dns/aardvark.pid") assert "$aardvark_pid2" == "$aardvark_pid" "aardvark-dns pid after nv update" # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1 8.8.8.8" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename 8.8.8.8,1.1.1.1$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" # remove network and check running and verify if aardvark config has no nameserver NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge-network-container-dns-server.json \ update podman1 --network-dns-servers "" # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" == "10.89.3.1,fd10:88:a::1" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename 8.8.8.8,1.1.1.1$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" } # netavark must do no-op on upates when no aardvark config is there @test "run netavark update - no-op" { # get a random port directly to avoid low ports e.g. 53 would not create iptables dns_port=$((RANDOM+10000)) NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge-network-container-dns-server.json \ update podman1 --network-dns-servers 8.8.8.8 } @test "$fw_driver - ipv6 bridge" { run_netavark --file ${TESTSDIR}/testfiles/ipv6-bridge.json setup $(get_container_netns_path) result="$output" assert_json "$result" 'has("podman1")' == "true" "object key exists" mac=$(jq -r '.podman1.interfaces.eth0.mac_address' <<<"$result") # check that interface exists run_in_container_netns ip -j --details link show eth0 link_info="$output" assert_json "$link_info" ".[].address" == "$mac" "MAC matches container mac" assert_json "$link_info" '.[].flags[] | select(.=="UP")' == "UP" "Container interface is up" assert_json "$link_info" ".[].linkinfo.info_kind" == "veth" "Container interface is a veth device" ipaddr="fd10:88:a::2/64" run_in_container_netns ip addr show eth0 assert "$output" =~ "$ipaddr" "IP address matches container address" assert_json "$result" ".podman1.interfaces.eth0.subnets[0].ipnet" == "$ipaddr" "Result contains correct IP address" run_in_host_netns ip -j --details link show podman1 link_info="$output" assert_json "$link_info" '.[].flags[] | select(.=="UP")' == "UP" "Host bridge interface is up" assert_json "$link_info" ".[].linkinfo.info_kind" == "bridge" "The bridge interface is actually a bridge" ipaddr="fd10:88:a::1" run_in_host_netns ip addr show podman1 assert "$output" =~ "$ipaddr" "IP address matches bridge gateway address" assert_json "$result" ".podman1.interfaces.eth0.subnets[0].gateway" == "$ipaddr" "Result contains gateway address" # check that the loopback adapter is up run_in_container_netns ip addr show lo assert "$output" =~ "127.0.0.1" "Loopback adapter is up (has address)" run_in_host_netns ping6 -c 1 fd10:88:a::2 run_netavark --file ${TESTSDIR}/testfiles/ipv6-bridge.json teardown $(get_container_netns_path) } @test "$fw_driver - ipv6 bridge with static routes" { # add second interface and routes through that interface to test proper teardown run_in_container_netns ip link add type dummy run_in_container_netns ip a add fd10:49:b::2/64 dev dummy0 run_in_container_netns ip link set dummy0 up run_netavark --file ${TESTSDIR}/testfiles/ipv6-bridge-staticroutes.json setup $(get_container_netns_path) # check static routes run_in_container_netns ip -6 -br r assert "$output" "=~" "fd10:89:b::/64 via fd10:88:a::ac02" "static route not set" assert "$output" "=~" "fd10:89:c::/64 via fd10:88:a::ac03" "static route not set" assert "$output" "=~" "fd10:51:b::/64 via fd10:49:b::30" "static route not set" run_netavark --file ${TESTSDIR}/testfiles/ipv6-bridge-staticroutes.json teardown $(get_container_netns_path) # check static routes get removed run_in_container_netns ip -6 -br r assert "$output" "!~" "fd10:89:b::/64 via fd10:88:a::ac02" "static route not removed" assert "$output" "!~" "fd10:89:c::/64 via fd10:88:a::ac03" "static route not removed" assert "$output" "!~" "fd10:51:b::/64 via fd10:49:b::30" "static route not removed" run_in_container_netns ip link delete dummy0 } @test "$fw_driver - bridge driver must generate config for aardvark with custom dns server" { # get a random port directly to avoid low ports e.g. 53 would not create iptables dns_port=$((RANDOM+10000)) NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge-custom-dns-server.json \ setup $(get_container_netns_path) # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename 8.8.8.8$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" aardvark_pid=$(cat "$NETAVARK_TMPDIR/config/aardvark-dns/aardvark.pid") assert "$ardvark_pid" =~ "[0-9]*" "aardvark pid not found" run_helper ps "$aardvark_pid" assert "${lines[1]}" =~ ".*aardvark-dns --config $NETAVARK_TMPDIR/config/aardvark-dns -p $dns_port run" "aardvark not running or bad options" } @test "$fw_driver - bridge driver must generate config for aardvark with multiple custom dns server" { # get a random port directly to avoid low ports e.g. 53 would not create iptables dns_port=$((RANDOM+10000)) NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge-multiple-custom-dns-server.json \ setup $(get_container_netns_path) # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename 8.8.8.8,1.1.1.1$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" aardvark_pid=$(cat "$NETAVARK_TMPDIR/config/aardvark-dns/aardvark.pid") assert "$ardvark_pid" =~ "[0-9]*" "aardvark pid not found" run_helper ps "$aardvark_pid" assert "${lines[1]}" =~ ".*aardvark-dns --config $NETAVARK_TMPDIR/config/aardvark-dns -p $dns_port run" "aardvark not running or bad options" } @test "$fw_driver - bridge driver must generate config for aardvark with multiple custom dns server with network dns servers" { # get a random port directly to avoid low ports e.g. 53 would not create iptables dns_port=$((RANDOM+10000)) NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge-network-container-dns-server.json \ setup $(get_container_netns_path) # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1 127.0.0.1,3.3.3.3" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename 8.8.8.8,1.1.1.1$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" aardvark_pid=$(cat "$NETAVARK_TMPDIR/config/aardvark-dns/aardvark.pid") assert "$ardvark_pid" =~ "[0-9]*" "aardvark pid not found" run_helper ps "$aardvark_pid" assert "${lines[1]}" =~ ".*aardvark-dns --config $NETAVARK_TMPDIR/config/aardvark-dns -p $dns_port run" "aardvark not running or bad options" } @test "$fw_driver - dual stack dns with alt port" { # get a random port directly to avoid low ports e.g. 53 would not create iptables dns_port=$((RANDOM+10000)) NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge.json \ setup $(get_container_netns_path) # check iptables run_in_host_netns iptables -t nat -S NETAVARK-HOSTPORT-DNAT assert "${lines[1]}" == "-A NETAVARK-HOSTPORT-DNAT -d 10.89.3.1/32 -p udp -m udp --dport 53 -j DNAT --to-destination 10.89.3.1:$dns_port" "ipv4 dns forward rule" run_in_host_netns ip6tables -t nat -S NETAVARK-HOSTPORT-DNAT assert "${lines[1]}" == "-A NETAVARK-HOSTPORT-DNAT -d fd10:88:a::1/128 -p udp -m udp --dport 53 -j DNAT --to-destination [fd10:88:a::1]:$dns_port" "ipv6 dns forward rule" # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" aardvark_pid=$(cat "$NETAVARK_TMPDIR/config/aardvark-dns/aardvark.pid") assert "$ardvark_pid" =~ "[0-9]*" "aardvark pid not found" run_helper ps "$aardvark_pid" assert "${lines[1]}" =~ ".*aardvark-dns --config $NETAVARK_TMPDIR/config/aardvark-dns -p $dns_port run" "aardvark not running or bad options" # test redirection actually works run_in_container_netns dig +short "somename.dns.podman" @10.89.3.1 A "somename.dns.podman" @10.89.3.1 AAAA assert "${lines[0]}" =~ "10.89.3.2" "ipv4 dns resolution works 1/2" assert "${lines[1]}" =~ "fd10:88:a::2" "ipv6 dns resolution works 2/2" run_in_container_netns dig +short "somename.dns.podman" @fd10:88:a::1 assert "${lines[0]}" =~ "10.89.3.2" "ipv6 dns resolution works" NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge.json \ teardown $(get_container_netns_path) # check iptables got removed run_in_host_netns iptables -t nat -S NETAVARK-HOSTPORT-DNAT assert "${#lines[@]}" = 1 "too many v4 NETAVARK_HOSTPORT-DNAT rules after teardown" run_in_host_netns ip6tables -t nat -S NETAVARK-HOSTPORT-DNAT assert "${#lines[@]}" = 1 "too many v6 NETAVARK_HOSTPORT-DNAT rules after teardown" # check aardvark config got cleared, process killed expected_rc=2 run_helper ls "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" expected_rc=1 run_helper ps "$aardvark_pid" } @test "$fw_driver - dns with default drop policy" { run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge.json \ setup $(get_container_netns_path) run_in_host_netns iptables -P INPUT DROP run_in_host_netns iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" # test redirection actually works run_in_container_netns dig +short "somename.dns.podman" @10.89.3.1 A "somename.dns.podman" @10.89.3.1 AAAA assert "${lines[0]}" =~ "10.89.3.2" "ipv4 dns resolution works 1/2" assert "${lines[1]}" =~ "fd10:88:a::2" "ipv6 dns resolution works 2/2" run_in_container_netns dig +short "somename.dns.podman" @fd10:88:a::1 assert "${lines[0]}" =~ "10.89.3.2" "ipv6 dns resolution works" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge.json \ teardown $(get_container_netns_path) # check iptables got removed run_in_host_netns iptables -t nat -S NETAVARK-HOSTPORT-DNAT assert "${#lines[@]}" = 1 "too many v4 NETAVARK_HOSTPORT-DNAT rules after teardown" run_in_host_netns ip6tables -t nat -S NETAVARK-HOSTPORT-DNAT assert "${#lines[@]}" = 1 "too many v6 NETAVARK_HOSTPORT-DNAT rules after teardown" # check aardvark config got cleared, process killed expected_rc=2 run_helper ls "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" expected_rc=1 run_helper ps "$aardvark_pid" } @test "$fw_driver - dns with default drop policy with non-default dns port" { # get a random port dns_port=$((RANDOM+10000)) NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge.json \ setup $(get_container_netns_path) # check iptables run_in_host_netns iptables -t filter -S NETAVARK_INPUT assert "${lines[1]}" == "-A NETAVARK_INPUT -s 10.89.3.0/24 -p udp -m udp --dport $dns_port -j ACCEPT" "ipv4 dns forward rule" run_in_host_netns ip6tables -t filter -S NETAVARK_INPUT assert "${lines[1]}" == "-A NETAVARK_INPUT -s fd10:88:a::/64 -p udp -m udp --dport $dns_port -j ACCEPT" "ipv6 dns forward rule" run_in_host_netns iptables -P INPUT DROP run_in_host_netns iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # check aardvark config and running run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1" "aardvark set to listen to all IPs" assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename$" "aardvark config's container" assert "${#lines[@]}" = 2 "too many lines in aardvark config" # test redirection actually works run_in_container_netns dig +short "somename.dns.podman" @10.89.3.1 A "somename.dns.podman" @10.89.3.1 AAAA assert "${lines[0]}" =~ "10.89.3.2" "ipv4 dns resolution works 1/2" assert "${lines[1]}" =~ "fd10:88:a::2" "ipv6 dns resolution works 2/2" run_in_container_netns dig +short "somename.dns.podman" @fd10:88:a::1 assert "${lines[0]}" =~ "10.89.3.2" "ipv6 dns resolution works" NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge.json \ teardown $(get_container_netns_path) # check iptables got removed run_in_host_netns iptables -t nat -S NETAVARK-HOSTPORT-DNAT assert "${#lines[@]}" = 1 "too many v4 NETAVARK_HOSTPORT-DNAT rules after teardown" run_in_host_netns ip6tables -t nat -S NETAVARK-HOSTPORT-DNAT assert "${#lines[@]}" = 1 "too many v6 NETAVARK_HOSTPORT-DNAT rules after teardown" # check aardvark config got cleared, process killed expected_rc=2 run_helper ls "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" expected_rc=1 run_helper ps "$aardvark_pid" } @test "$fw_driver - check error message from netns thread" { # create interface in netns to force error run_in_container_netns ip link add eth0 type dummy expected_rc=1 run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json setup $(get_container_netns_path) assert_json ".error" "create veth pair: interface eth0 already exists on container namespace: Netlink error: File exists (os error 17)" "interface exists on netns" } @test "$fw_driver - port forwarding ipv4 - tcp" { test_port_fw } @test "$fw_driver - port forwarding ipv6 - tcp" { test_port_fw ip=6 } @test "$fw_driver - port forwarding dualstack - tcp" { test_port_fw ip=dual } @test "$fw_driver - port forwarding ipv4 - udp" { test_port_fw proto=udp } @test "$fw_driver - port forwarding ipv6 - udp" { test_port_fw ip=6 proto=udp } @test "$fw_driver - port forwarding dualstack - udp" { test_port_fw ip=dual proto=udp } @test "$fw_driver - port forwarding ipv4 - sctp" { setup_sctp_kernel_module test_port_fw proto=sctp } @test "$fw_driver - port forwarding ipv6 - sctp" { setup_sctp_kernel_module test_port_fw ip=6 proto=sctp } @test "$fw_driver - port forwarding dualstack - sctp" { setup_sctp_kernel_module test_port_fw ip=dual proto=sctp } @test "$fw_driver - port range forwarding ipv4 - tcp" { test_port_fw range=3 } @test "$fw_driver - port range forwarding ipv6 - tcp" { test_port_fw ip=6 range=3 } @test "$fw_driver - port range forwarding ipv4 - udp" { test_port_fw proto=udp range=3 } @test "$fw_driver - port range forwarding ipv6 - udp" { test_port_fw ip=6 proto=udp range=3 } @test "$fw_driver - port range forwarding dual - udp" { test_port_fw ip=dual proto=udp range=3 } @test "$fw_driver - port range forwarding dual - tcp" { test_port_fw ip=dual proto=tcp range=3 } @test "$fw_driver - port forwarding with hostip ipv4 - tcp" { add_dummy_interface_on_host dummy0 "172.16.0.1/24" test_port_fw hostip="172.16.0.1" } @test "$fw_driver - port forwarding with hostip ipv4 dual stack - tcp" { add_dummy_interface_on_host dummy0 "172.16.0.1/24" test_port_fw ip=dual hostip="172.16.0.1" } @test "$fw_driver - port forwarding with hostip ipv6 - tcp" { add_dummy_interface_on_host dummy0 "fd65:8371:648b:0c06::1/64" test_port_fw ip=6 hostip="fd65:8371:648b:0c06::1" } @test "$fw_driver - port forwarding with hostip ipv6 dual stack - tcp" { add_dummy_interface_on_host dummy0 "fd65:8371:648b:0c06::1/64" test_port_fw ip=dual hostip="fd65:8371:648b:0c06::1" } @test "$fw_driver - port forwarding with wildcard hostip ipv4 - tcp" { add_dummy_interface_on_host dummy0 "172.16.0.1/24" test_port_fw hostip="0.0.0.0" connectip="172.16.0.1" } @test "$fw_driver - port forwarding with wildcard hostip ipv4 dual stack - tcp" { add_dummy_interface_on_host dummy0 "172.16.0.1/24" test_port_fw ip=dual hostip="0.0.0.0" connectip="172.16.0.1" } @test "$fw_driver - port forwarding with wildcard hostip ipv6 - tcp" { add_dummy_interface_on_host dummy0 "fd65:8371:648b:0c06::1/64" test_port_fw ip=6 hostip="::" connectip="fd65:8371:648b:0c06::1" } @test "$fw_driver - port forwarding with wildcard hostip ipv6 dual stack - tcp" { add_dummy_interface_on_host dummy0 "fd65:8371:648b:0c06::1/64" test_port_fw ip=dual hostip="::" connectip="fd65:8371:648b:0c06::1" } @test "$fw_driver - port forwarding with hostip ipv4 - udp" { add_dummy_interface_on_host dummy0 "172.16.0.1/24" test_port_fw proto=udp hostip="172.16.0.1" } @test "$fw_driver - port forwarding with hostip ipv6 - udp" { add_dummy_interface_on_host dummy0 "fd65:8371:648b:0c06::1/64" test_port_fw ip=6 proto=udp hostip="fd65:8371:648b:0c06::1" } # Test that port forwarding works with strict Reverse Path Forwarding enabled on the host @test "$fw_driver - port forwarding with two networks and RPF - tcp" { # First, enable strict RPF on host/container ns. run_in_host_netns sysctl -w net.ipv4.conf.all.rp_filter=1 run_in_host_netns sysctl -w net.ipv4.conf.default.rp_filter=1 run_in_container_netns sysctl -w net.ipv4.conf.all.rp_filter=1 run_in_container_netns sysctl -w net.ipv4.conf.default.rp_filter=1 # We need a dummy interface with a host ip, # if we connect directly to the bridge ip it doesn't reproduce. add_dummy_interface_on_host dummy0 "10.0.0.1/24" run_netavark --file ${TESTSDIR}/testfiles/two-networks.json setup $(get_container_netns_path) result="$output" run_in_host_netns cat /proc/sys/net/ipv4/conf/podman2/rp_filter assert "2" "rp_filter podman2 bridge" run_in_host_netns cat /proc/sys/net/ipv4/conf/podman3/rp_filter assert "2" "rp_filter podman3 bridge" run_in_container_netns cat /proc/sys/net/ipv4/conf/eth0/rp_filter assert "2" "rp_filter eth0 interface" run_in_container_netns cat /proc/sys/net/ipv4/conf/eth1/rp_filter assert "2" "rp_filter eth1 interface" # Important: Use the "host" ip here and not localhost or bridge ip. run_nc_test "0" "tcp" 8080 "10.0.0.1" 8080 } @test "bridge ipam none" { read -r -d '\0' config < /proc/sys/net/ipv4/ip_forward" run_in_container_netns sh -c "echo 1 > /proc/sys/net/ipv4/conf/default/arp_notify" run_in_host_netns sh -c "echo 2 > /proc/sys/net/ipv4/conf/default/rp_filter" run_in_container_netns sh -c "echo 2 > /proc/sys/net/ipv4/conf/default/rp_filter" run_in_host_netns mount -t proc -o ro,nosuid,nodev,noexec proc /proc run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json setup $(get_container_netns_path) run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json teardown $(get_container_netns_path) run_in_host_netns mount -t proc -o remount,rw /proc run_in_host_netns sh -c "echo 0 > /proc/sys/net/ipv4/ip_forward" run_in_host_netns mount -t proc -o remount,ro /proc expected_rc=1 run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json setup $(get_container_netns_path) assert_json ".error" "Sysctl error: IO Error: Read-only file system (os error 30)" "Sysctl error because fs is read only" } @test "$fw_driver - bridge static mac" { mac="aa:bb:cc:dd:ee:ff" read -r -d '\0' config <