Commit 5e317a2f authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'selftests-move-netfilter-tests-to-net'

Florian Westphal says:

====================
selftests: move netfilter tests to net

First patch in this series moves selftests/netfilter/
to selftests/net/netfilter/.

Passing this via net-next rather than nf-next for this reason.

Main motivation is that a lot of these scripts only work on my old
development VM, I hope that placing this in net/ will get these
tests to get run in more regular intervals (and tests get more robust).

Changes are:

- make use of existing 'setup_ns' and 'busywait' helpers
- fix shellcheck warnings
- add more SKIP checks to avoid failures
- get rid of netcat in favor of socat, too many test
  failures due to 'wrong' netcat flavor
- do not assume rp_filter sysctl is off

I have more patches that fix up the remaining test scripts,
but the series was too large to send them at once (34 patches).

After all scripts are fixed up, tests pass on both my Debian
and Fedora test machines.

MAINTAINERS is updated to reflect that future updates should be handled
via netfilter-devel@.
====================

Link: https://lore.kernel.org/r/20240411233624.8129-1-fw@strlen.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 982a73c7 49af681b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15264,6 +15264,7 @@ F: net/*/netfilter.c
F:	net/*/netfilter/
F:	net/bridge/br_netfilter*.c
F:	net/netfilter/
F:	tools/testing/selftests/net/netfilter/
NETROM NETWORK LAYER
M:	Ralf Baechle <ralf@linux-mips.org>
+2 −2
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only
nf-queue
connect_close
audit_logread
connect_close
conntrack_dump_flush
sctp_collision
nf_queue
+44 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

top_srcdir = ../../../../..

HOSTPKG_CONFIG := pkg-config
MNL_CFLAGS := $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null)
MNL_LDLIBS := $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl)

TEST_PROGS := br_netfilter.sh bridge_brouter.sh
TEST_PROGS += conntrack_icmp_related.sh
TEST_PROGS += conntrack_ipip_mtu.sh
TEST_PROGS += conntrack_tcp_unreplied.sh
TEST_PROGS += conntrack_sctp_collision.sh
TEST_PROGS += conntrack_vrf.sh
TEST_PROGS += ipvs.sh
TEST_PROGS += nf_nat_edemux.sh
TEST_PROGS += nft_audit.sh
TEST_PROGS += nft_concat_range.sh
TEST_PROGS += nft_conntrack_helper.sh
TEST_PROGS += nft_fib.sh
TEST_PROGS += nft_flowtable.sh
TEST_PROGS += nft_meta.sh
TEST_PROGS += nft_nat.sh
TEST_PROGS += nft_nat_zones.sh
TEST_PROGS += nft_queue.sh
TEST_PROGS += nft_synproxy.sh
TEST_PROGS += nft_zones_many.sh
TEST_PROGS += rpath.sh
TEST_PROGS += xt_string.sh

TEST_CUSTOM_PROGS += conntrack_dump_flush

TEST_GEN_FILES = audit_logread
TEST_GEN_FILES += conntrack_dump_flush
TEST_GEN_FILES += connect_close nf_queue
TEST_GEN_FILES += sctp_collision

include ../../lib.mk

$(OUTPUT)/nf_queue: CFLAGS += $(MNL_CFLAGS)
$(OUTPUT)/nf_queue: LDLIBS += $(MNL_LDLIBS)

$(OUTPUT)/conntrack_dump_flush: CFLAGS += $(MNL_CFLAGS)
$(OUTPUT)/conntrack_dump_flush: LDLIBS += $(MNL_LDLIBS)
+163 −0
Original line number Diff line number Diff line
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Test bridge netfilter + conntrack, a combination that doesn't really work,
# with multicast/broadcast packets racing for hash table insertion.
# Test for legacy br_netfilter module combined with connection tracking,
# a combination that doesn't really work.
# Multicast/broadcast packets race for hash table insertion.

#           eth0    br0     eth0
# setup is: ns1 <->,ns0 <-> ns3
#           ns2 <-'    `'-> ns4

# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
ret=0

sfx=$(mktemp -u "XXXXXXXX")
ns0="ns0-$sfx"
ns1="ns1-$sfx"
ns2="ns2-$sfx"
ns3="ns3-$sfx"
ns4="ns4-$sfx"

ebtables -V > /dev/null 2>&1
if [ $? -ne 0 ];then
	echo "SKIP: Could not run test without ebtables"
	exit $ksft_skip
fi
source lib.sh

ip -Version > /dev/null 2>&1
if [ $? -ne 0 ];then
	echo "SKIP: Could not run test without ip tool"
	exit $ksft_skip
fi

for i in $(seq 0 4); do
  eval ip netns add \$ns$i
done
checktool "nft --version" "run test without nft tool"

cleanup() {
  for i in $(seq 0 4); do eval ip netns del \$ns$i;done
	cleanup_all_ns
}

trap cleanup EXIT

setup_ns ns0 ns1 ns2 ns3 ns4

ret=0

do_ping()
{
	fromns="$1"
	dstip="$2"

	ip netns exec $fromns ping -c 1 -q $dstip > /dev/null
	if [ $? -ne 0 ]; then
	if ! ip netns exec "$fromns" ping -c 1 -q "$dstip" > /dev/null; then
		echo "ERROR: ping from $fromns to $dstip"
		ip netns exec ${ns0} nft list ruleset
		ip netns exec "$ns0" nft list ruleset
		ret=1
	fi
}
@@ -59,75 +40,75 @@ bcast_ping()
	fromns="$1"
	dstip="$2"

	for i in $(seq 1 1000); do
		ip netns exec $fromns ping -q -f -b -c 1 -q $dstip > /dev/null 2>&1
		if [ $? -ne 0 ]; then
	for i in $(seq 1 500); do
		if ! ip netns exec "$fromns" ping -q -f -b -c 1 -q "$dstip" > /dev/null 2>&1; then
			echo "ERROR: ping -b from $fromns to $dstip"
			ip netns exec ${ns0} nft list ruleset
			ip netns exec "$ns0" nft list ruleset
			ret=1
			break
		fi
	done
}

ip link add veth1 netns ${ns0} type veth peer name eth0 netns ${ns1}
if [ $? -ne 0 ]; then
ip netns exec "$ns0" sysctl -q net.ipv4.conf.all.rp_filter=0
ip netns exec "$ns0" sysctl -q net.ipv4.conf.default.rp_filter=0

if ! ip link add veth1 netns "$ns0" type veth peer name eth0 netns "$ns1"; then
	echo "SKIP: Can't create veth device"
	exit $ksft_skip
fi

ip link add veth2 netns ${ns0} type veth peer name eth0 netns $ns2
ip link add veth3 netns ${ns0} type veth peer name eth0 netns $ns3
ip link add veth4 netns ${ns0} type veth peer name eth0 netns $ns4

ip -net ${ns0} link set lo up
ip link add veth2 netns "$ns0" type veth peer name eth0 netns "$ns2"
ip link add veth3 netns "$ns0" type veth peer name eth0 netns "$ns3"
ip link add veth4 netns "$ns0" type veth peer name eth0 netns "$ns4"

for i in $(seq 1 4); do
  ip -net ${ns0} link set veth$i up
  ip -net "$ns0" link set "veth$i" up
done

ip -net ${ns0} link add br0 type bridge stp_state 0 forward_delay 0 nf_call_iptables 1 nf_call_ip6tables 1 nf_call_arptables 1
if [ $? -ne 0 ]; then
if ! ip -net "$ns0" link add br0 type bridge stp_state 0 forward_delay 0 nf_call_iptables 1 nf_call_ip6tables 1 nf_call_arptables 1; then
	echo "SKIP: Can't create bridge br0"
	exit $ksft_skip
fi

# make veth0,1,2 part of bridge.
for i in $(seq 1 3); do
  ip -net ${ns0} link set veth$i master br0
  ip -net "$ns0" link set "veth$i" master br0
done

# add a macvlan on top of the bridge.
MACVLAN_ADDR=ba:f3:13:37:42:23
ip -net ${ns0} link add link br0 name macvlan0 type macvlan mode private
ip -net ${ns0} link set macvlan0 address ${MACVLAN_ADDR}
ip -net ${ns0} link set macvlan0 up
ip -net ${ns0} addr add 10.23.0.1/24 dev macvlan0
ip -net "$ns0" link add link br0 name macvlan0 type macvlan mode private
ip -net "$ns0" link set macvlan0 address ${MACVLAN_ADDR}
ip -net "$ns0" link set macvlan0 up
ip -net "$ns0" addr add 10.23.0.1/24 dev macvlan0

# add a macvlan on top of veth4.
MACVLAN_ADDR=ba:f3:13:37:42:24
ip -net ${ns0} link add link veth4 name macvlan4 type macvlan mode vepa
ip -net ${ns0} link set macvlan4 address ${MACVLAN_ADDR}
ip -net ${ns0} link set macvlan4 up
ip -net "$ns0" link add link veth4 name macvlan4 type macvlan mode passthru
ip -net "$ns0" link set macvlan4 address ${MACVLAN_ADDR}
ip -net "$ns0" link set macvlan4 up

# make the macvlan part of the bridge.
# veth4 is not a bridge port, only the macvlan on top of it.
ip -net ${ns0} link set macvlan4 master br0
ip -net "$ns0" link set macvlan4 master br0

ip -net ${ns0} link set br0 up
ip -net ${ns0} addr add 10.0.0.1/24 dev br0
ip netns exec ${ns0} sysctl -q net.bridge.bridge-nf-call-iptables=1
ret=$?
if [ $ret -ne 0 ] ; then
ip -net "$ns0" link set br0 up
ip -net "$ns0" addr add 10.0.0.1/24 dev br0

modprobe -q br_netfilter
if ! ip netns exec "$ns0" sysctl -q net.bridge.bridge-nf-call-iptables=1; then
	echo "SKIP: bridge netfilter not available"
	ret=$ksft_skip
fi

# for testing, so namespaces will reply to ping -b probes.
ip netns exec ${ns0} sysctl -q net.ipv4.icmp_echo_ignore_broadcasts=0
ip netns exec "$ns0" sysctl -q net.ipv4.icmp_echo_ignore_broadcasts=0

# enable conntrack in ns0 and drop broadcast packets in forward to
# avoid them from getting confirmed in the postrouting hook before
# the cloned skb is passed up the stack.
ip netns exec ${ns0} nft -f - <<EOF
ip netns exec "$ns0" nft -f - <<EOF
table ip filter {
	chain input {
		type filter hook input priority 1; policy accept
@@ -149,36 +130,30 @@ EOF
# part of the bridge: the corresponding veth4 is not
# part of the bridge, only its macvlan interface.
for i in $(seq 1 4); do
  eval ip -net \$ns$i link set lo up
  eval ip -net \$ns$i link set eth0 up
  eval ip -net \$ns"$i" link set eth0 up
done
for i in $(seq 1 2); do
  eval ip -net \$ns$i addr add 10.0.0.1$i/24 dev eth0
  eval ip -net \$ns"$i" addr add "10.0.0.1$i/24" dev eth0
done

ip -net ${ns3} addr add 10.23.0.13/24 dev eth0
ip -net ${ns4} addr add 10.23.0.14/24 dev eth0
ip -net "$ns3" addr add 10.23.0.13/24 dev eth0
ip -net "$ns4" addr add 10.23.0.14/24 dev eth0

# test basic connectivity
do_ping ${ns1} 10.0.0.12
do_ping ${ns3} 10.23.0.1
do_ping ${ns4} 10.23.0.1

if [ $ret -eq 0 ];then
	echo "PASS: netns connectivity: ns1 can reach ns2, ns3 and ns4 can reach ns0"
fi
do_ping "$ns1" 10.0.0.12
do_ping "$ns3" 10.23.0.1
do_ping "$ns4" 10.23.0.1

bcast_ping ${ns1} 10.0.0.255
bcast_ping "$ns1" 10.0.0.255

# This should deliver broadcast to macvlan0, which is on top of ns0:br0.
bcast_ping ${ns3} 10.23.0.255
bcast_ping "$ns3" 10.23.0.255

# same, this time via veth4:macvlan4.
bcast_ping ${ns4} 10.23.0.255
bcast_ping "$ns4" 10.23.0.255

read t < /proc/sys/kernel/tainted

if [ $t -eq 0 ];then
if [ "$t" -eq 0 ];then
	echo PASS: kernel not tainted
else
	echo ERROR: kernel is tainted
Loading