#!/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. # 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 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 cleanup() { for i in $(seq 0 4); do eval ip netns del \$ns$i;done } trap cleanup EXIT do_ping() { fromns="$1" dstip="$2" ip netns exec $fromns ping -c 1 -q $dstip > /dev/null if [ $? -ne 0 ]; then echo "ERROR: ping from $fromns to $dstip" ip netns exec ${ns0} nft list ruleset ret=1 fi } 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 echo "ERROR: ping -b from $fromns to $dstip" ip netns exec ${ns0} nft list ruleset fi done } ip link add veth1 netns ${ns0} type veth peer name eth0 netns ${ns1} if [ $? -ne 0 ]; 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 for i in $(seq 1 4); do 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 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 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 # 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 # 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 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 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 # 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 - <