File Index
Files and directories
Sign in
FILE

br_netfilter.sh

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/netfilter/br_netfilter.sh BASH
  1#!/bin/bash
  2# SPDX-License-Identifier: GPL-2.0
  3#
  4# Test for legacy br_netfilter module combined with connection tracking,
  5# a combination that doesn't really work.
  6# Multicast/broadcast packets race for hash table insertion.
  7
  8#           eth0    br0     eth0
  9# setup is: ns1 <->,ns0 <-> ns3
 10#           ns2 <-'    `'-> ns4
 11
 12source lib.sh
 13
 14checktool "nft --version" "run test without nft tool"
 15
 16read t < /proc/sys/kernel/tainted
 17if [ "$t" -ne 0 ];then
 18	echo SKIP: kernel is tainted
 19	exit $ksft_skip
 20fi
 21
 22cleanup() {
 23	cleanup_all_ns
 24}
 25
 26trap cleanup EXIT
 27
 28setup_ns ns0 ns1 ns2 ns3 ns4
 29
 30ret=0
 31
 32do_ping()
 33{
 34	fromns="$1"
 35	dstip="$2"
 36
 37	if ! ip netns exec "$fromns" ping -c 1 -q "$dstip" > /dev/null; then
 38		echo "ERROR: ping from $fromns to $dstip"
 39		ip netns exec "$ns0" nft list ruleset
 40		ret=1
 41	fi
 42}
 43
 44bcast_ping()
 45{
 46	fromns="$1"
 47	dstip="$2"
 48
 49	local packets=500
 50
 51	[ "$KSFT_MACHINE_SLOW" = yes ] && packets=100
 52
 53	for i in $(seq 1 $packets); do
 54		if ! ip netns exec "$fromns" ping -q -f -b -c 1 -q "$dstip" > /dev/null 2>&1; then
 55			echo "ERROR: ping -b from $fromns to $dstip"
 56			ip netns exec "$ns0" nft list ruleset
 57			ret=1
 58			break
 59		fi
 60	done
 61}
 62
 63if ! ip link add veth1 netns "$ns0" type veth peer name eth0 netns "$ns1"; then
 64	echo "SKIP: Can't create veth device"
 65	exit $ksft_skip
 66fi
 67
 68ip link add veth2 netns "$ns0" type veth peer name eth0 netns "$ns2"
 69ip link add veth3 netns "$ns0" type veth peer name eth0 netns "$ns3"
 70ip link add veth4 netns "$ns0" type veth peer name eth0 netns "$ns4"
 71
 72for i in $(seq 1 4); do
 73  ip -net "$ns0" link set "veth$i" up
 74done
 75
 76if ! 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
 77	echo "SKIP: Can't create bridge br0"
 78	exit $ksft_skip
 79fi
 80
 81# make veth0,1,2 part of bridge.
 82for i in $(seq 1 3); do
 83  ip -net "$ns0" link set "veth$i" master br0
 84done
 85
 86# add a macvlan on top of the bridge.
 87MACVLAN_ADDR=ba:f3:13:37:42:23
 88ip -net "$ns0" link add link br0 name macvlan0 type macvlan mode private
 89ip -net "$ns0" link set macvlan0 address ${MACVLAN_ADDR}
 90ip -net "$ns0" link set macvlan0 up
 91ip -net "$ns0" addr add 10.23.0.1/24 dev macvlan0
 92
 93# add a macvlan on top of veth4.
 94MACVLAN_ADDR=ba:f3:13:37:42:24
 95ip -net "$ns0" link add link veth4 name macvlan4 type macvlan mode passthru
 96ip -net "$ns0" link set macvlan4 address ${MACVLAN_ADDR}
 97ip -net "$ns0" link set macvlan4 up
 98
 99# make the macvlan part of the bridge.
100# veth4 is not a bridge port, only the macvlan on top of it.
101ip -net "$ns0" link set macvlan4 master br0
102
103ip -net "$ns0" link set br0 up
104ip -net "$ns0" addr add 10.0.0.1/24 dev br0
105
106modprobe -q br_netfilter
107if ! ip netns exec "$ns0" sysctl -q net.bridge.bridge-nf-call-iptables=1; then
108	echo "SKIP: bridge netfilter not available"
109	ret=$ksft_skip
110fi
111
112# for testing, so namespaces will reply to ping -b probes.
113ip netns exec "$ns0" sysctl -q net.ipv4.icmp_echo_ignore_broadcasts=0
114
115# enable conntrack in ns0 and drop broadcast packets in forward to
116# avoid them from getting confirmed in the postrouting hook before
117# the cloned skb is passed up the stack.
118ip netns exec "$ns0" nft -f - <<EOF
119table ip filter {
120	chain input {
121		type filter hook input priority 1; policy accept
122		iifname br0 counter
123		ct state new accept
124	}
125}
126
127table bridge filter {
128	chain forward {
129		type filter hook forward priority 0; policy accept
130		meta pkttype broadcast ip protocol icmp counter drop
131	}
132}
133EOF
134if [ "$?" -ne 0 ];then
135	echo "SKIP: could not add nftables ruleset"
136	exit $ksft_skip
137fi
138
139# place 1, 2 & 3 in same subnet, connected via ns0:br0.
140# ns4 is placed in same subnet as well, but its not
141# part of the bridge: the corresponding veth4 is not
142# part of the bridge, only its macvlan interface.
143for i in $(seq 1 4); do
144  eval ip -net \$ns"$i" link set eth0 up
145done
146for i in $(seq 1 2); do
147  eval ip -net \$ns"$i" addr add "10.0.0.1$i/24" dev eth0
148done
149
150ip -net "$ns3" addr add 10.23.0.13/24 dev eth0
151ip -net "$ns4" addr add 10.23.0.14/24 dev eth0
152
153# test basic connectivity
154do_ping "$ns1" 10.0.0.12
155do_ping "$ns3" 10.23.0.1
156do_ping "$ns4" 10.23.0.1
157
158bcast_ping "$ns1" 10.0.0.255
159
160# This should deliver broadcast to macvlan0, which is on top of ns0:br0.
161bcast_ping "$ns3" 10.23.0.255
162
163# same, this time via veth4:macvlan4.
164bcast_ping "$ns4" 10.23.0.255
165
166read t < /proc/sys/kernel/tainted
167if [ "$t" -eq 0 ];then
168	echo PASS: kernel not tainted
169else
170	echo ERROR: kernel is tainted
171	dmesg
172	ret=1
173fi
174
175exit $ret
~/ Read-only file preview.