Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: netfilter: add ebtables broute test case

ebtables -t broute allows to redirect packets in a way that
they get pushed up the stack, even if the interface is part
of a bridge.

In case of IP packets to non-local address, this means
those IP packets are routed instead of bridged-forwarded, just
as if the bridge would not have existed.

Expected test output is:
PASS: netns connectivity: ns1 and ns2 can reach each other
PASS: ns1/ns2 connectivity with active broute rule
PASS: ns1/ns2 connectivity with active broute rule and bridge forward drop

Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
26f7fe4a 610a4314

+147 -1
+1 -1
tools/testing/selftests/netfilter/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 # Makefile for netfilter selftests 3 3 4 - TEST_PROGS := nft_trans_stress.sh nft_nat.sh 4 + TEST_PROGS := nft_trans_stress.sh nft_nat.sh bridge_brouter.sh 5 5 6 6 include ../lib.mk
+146
tools/testing/selftests/netfilter/bridge_brouter.sh
··· 1 + #!/bin/bash 2 + # 3 + # This test is for bridge 'brouting', i.e. make some packets being routed 4 + # rather than getting bridged even though they arrive on interface that is 5 + # part of a bridge. 6 + 7 + # eth0 br0 eth0 8 + # setup is: ns1 <-> ns0 <-> ns2 9 + 10 + # Kselftest framework requirement - SKIP code is 4. 11 + ksft_skip=4 12 + ret=0 13 + 14 + ebtables -V > /dev/null 2>&1 15 + if [ $? -ne 0 ];then 16 + echo "SKIP: Could not run test without ebtables" 17 + exit $ksft_skip 18 + fi 19 + 20 + ip -Version > /dev/null 2>&1 21 + if [ $? -ne 0 ];then 22 + echo "SKIP: Could not run test without ip tool" 23 + exit $ksft_skip 24 + fi 25 + 26 + ip netns add ns0 27 + ip netns add ns1 28 + ip netns add ns2 29 + 30 + ip link add veth0 netns ns0 type veth peer name eth0 netns ns1 31 + if [ $? -ne 0 ]; then 32 + echo "SKIP: Can't create veth device" 33 + exit $ksft_skip 34 + fi 35 + ip link add veth1 netns ns0 type veth peer name eth0 netns ns2 36 + 37 + ip -net ns0 link set lo up 38 + ip -net ns0 link set veth0 up 39 + ip -net ns0 link set veth1 up 40 + 41 + ip -net ns0 link add br0 type bridge 42 + if [ $? -ne 0 ]; then 43 + echo "SKIP: Can't create bridge br0" 44 + exit $ksft_skip 45 + fi 46 + 47 + ip -net ns0 link set veth0 master br0 48 + ip -net ns0 link set veth1 master br0 49 + ip -net ns0 link set br0 up 50 + ip -net ns0 addr add 10.0.0.1/24 dev br0 51 + 52 + # place both in same subnet, ns1 and ns2 connected via ns0:br0 53 + for i in 1 2; do 54 + ip -net ns$i link set lo up 55 + ip -net ns$i link set eth0 up 56 + ip -net ns$i addr add 10.0.0.1$i/24 dev eth0 57 + done 58 + 59 + test_ebtables_broute() 60 + { 61 + local cipt 62 + 63 + # redirect is needed so the dstmac is rewritten to the bridge itself, 64 + # ip stack won't process OTHERHOST (foreign unicast mac) packets. 65 + ip netns exec ns0 ebtables -t broute -A BROUTING -p ipv4 --ip-protocol icmp -j redirect --redirect-target=DROP 66 + if [ $? -ne 0 ]; then 67 + echo "SKIP: Could not add ebtables broute redirect rule" 68 + return $ksft_skip 69 + fi 70 + 71 + # ping netns1, expected to not work (ip forwarding is off) 72 + ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null 2>&1 73 + if [ $? -eq 0 ]; then 74 + echo "ERROR: ping works, should have failed" 1>&2 75 + return 1 76 + fi 77 + 78 + # enable forwarding on both interfaces. 79 + # neither needs an ip address, but at least the bridge needs 80 + # an ip address in same network segment as ns1 and ns2 (ns0 81 + # needs to be able to determine route for to-be-forwarded packet). 82 + ip netns exec ns0 sysctl -q net.ipv4.conf.veth0.forwarding=1 83 + ip netns exec ns0 sysctl -q net.ipv4.conf.veth1.forwarding=1 84 + 85 + sleep 1 86 + 87 + ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null 88 + if [ $? -ne 0 ]; then 89 + echo "ERROR: ping did not work, but it should (broute+forward)" 1>&2 90 + return 1 91 + fi 92 + 93 + echo "PASS: ns1/ns2 connectivity with active broute rule" 94 + ip netns exec ns0 ebtables -t broute -F 95 + 96 + # ping netns1, expected to work (frames are bridged) 97 + ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null 98 + if [ $? -ne 0 ]; then 99 + echo "ERROR: ping did not work, but it should (bridged)" 1>&2 100 + return 1 101 + fi 102 + 103 + ip netns exec ns0 ebtables -t filter -A FORWARD -p ipv4 --ip-protocol icmp -j DROP 104 + 105 + # ping netns1, expected to not work (DROP in bridge forward) 106 + ip netns exec ns1 ping -q -c 1 10.0.0.12 > /dev/null 2>&1 107 + if [ $? -eq 0 ]; then 108 + echo "ERROR: ping works, should have failed (icmp forward drop)" 1>&2 109 + return 1 110 + fi 111 + 112 + # re-activate brouter 113 + ip netns exec ns0 ebtables -t broute -A BROUTING -p ipv4 --ip-protocol icmp -j redirect --redirect-target=DROP 114 + 115 + ip netns exec ns2 ping -q -c 1 10.0.0.11 > /dev/null 116 + if [ $? -ne 0 ]; then 117 + echo "ERROR: ping did not work, but it should (broute+forward 2)" 1>&2 118 + return 1 119 + fi 120 + 121 + echo "PASS: ns1/ns2 connectivity with active broute rule and bridge forward drop" 122 + return 0 123 + } 124 + 125 + # test basic connectivity 126 + ip netns exec ns1 ping -c 1 -q 10.0.0.12 > /dev/null 127 + if [ $? -ne 0 ]; then 128 + echo "ERROR: Could not reach ns2 from ns1" 1>&2 129 + ret=1 130 + fi 131 + 132 + ip netns exec ns2 ping -c 1 -q 10.0.0.11 > /dev/null 133 + if [ $? -ne 0 ]; then 134 + echo "ERROR: Could not reach ns1 from ns2" 1>&2 135 + ret=1 136 + fi 137 + 138 + if [ $ret -eq 0 ];then 139 + echo "PASS: netns connectivity: ns1 and ns2 can reach each other" 140 + fi 141 + 142 + test_ebtables_broute 143 + ret=$? 144 + for i in 0 1 2; do ip netns del ns$i;done 145 + 146 + exit $ret