diff options
author | Yi Chen <yiche@redhat.com> | 2025-07-15 17:19:13 +0800 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2025-07-16 20:35:35 +0200 |
commit | fda6e2a0486804a68c352f384aedd549b7e81a40 (patch) | |
tree | e411e33cdce7333282564888da99f4d522ef7ba8 | |
parent | 8a1de0ec9709b58a80a86a20cfba107b11c85f6e (diff) |
tests: shell: add type route chain test case
This test case verifies the functionality of nft type route chain
when used with policy routing based on dscp and fwmark.
Signed-off-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
-rw-r--r-- | tests/shell/testcases/packetpath/dumps/type_route_chain.nodump | 0 | ||||
-rwxr-xr-x | tests/shell/testcases/packetpath/type_route_chain | 201 |
2 files changed, 201 insertions, 0 deletions
diff --git a/tests/shell/testcases/packetpath/dumps/type_route_chain.nodump b/tests/shell/testcases/packetpath/dumps/type_route_chain.nodump new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/shell/testcases/packetpath/dumps/type_route_chain.nodump diff --git a/tests/shell/testcases/packetpath/type_route_chain b/tests/shell/testcases/packetpath/type_route_chain new file mode 100755 index 00000000..b4052fd9 --- /dev/null +++ b/tests/shell/testcases/packetpath/type_route_chain @@ -0,0 +1,201 @@ +#!/bin/bash + +# NFT_TEST_REQUIRES(NFT_TEST_HAVE_tcpdump) + +. $NFT_TEST_LIBRARY_FILE + +cleanup() +{ + for i in $C $S $R1 $R2 $B0 $B1;do + kill $(ip netns pid $i) 2>/dev/null + ip netns del $i + done + rm -rf $WORKDIR +} +trap cleanup EXIT + +# r1_ route1 r1_ +# │ │ +# s_──br0 br1──c_ +# │ │ +# r2_ route2 r2_ + +rnd=$(mktemp -u XXXXXXXX) +C="route-type-chain-client-$rnd" +S="route-type-chain-server-$rnd" +R1="route-type-chain-route1-$rnd" +R2="route-type-chain-route2-$rnd" +B0="route-type-chain-bridge0-$rnd" +B1="route-type-chain-bridge1-$rnd" +WORKDIR="/tmp/route-type-chain-$rnd" + +umask 022 +mkdir -p "$WORKDIR" +assert_pass "mkdir $WORKDIR" + +ip netns add $S +ip netns add $C +ip netns add $R1 +ip netns add $R2 +ip netns add $B0 +ip netns add $B1 + +ip -net $S link set lo up +ip -net $C link set lo up +ip -net $R1 link set lo up +ip -net $R2 link set lo up +ip -net $B0 link set lo up +ip -net $B1 link set lo up + +ip -n $B0 link add br0 up type bridge +ip -n $B1 link add br1 up type bridge + +ip link add s_br0 up netns $S type veth peer name br0_s netns $B0 +ip link add c_br1 up netns $C type veth peer name br1_c netns $B1 +ip link add r1_br0 up netns $R1 type veth peer name br0_r1 netns $B0 +ip link add r1_br1 up netns $R1 type veth peer name br1_r1 netns $B1 +ip link add r2_br0 up netns $R2 type veth peer name br0_r2 netns $B0 +ip link add r2_br1 up netns $R2 type veth peer name br1_r2 netns $B1 + +ip -n $B0 link set br0_s up master br0 +ip -n $B0 link set br0_r1 up master br0 +ip -n $B0 link set br0_r2 up master br0 +ip -n $B1 link set br1_c up master br1 +ip -n $B1 link set br1_r1 up master br1 +ip -n $B1 link set br1_r2 up master br1 + +ip6_s_br0=2000::1 +ip6_r1_br0=2000::a +ip6_r2_br0=2000::b +ip6_c_br1=2001::1 +ip6_r1_br1=2001::a +ip6_r2_br1=2001::b + +ip netns exec $R1 sysctl -wq net.ipv6.conf.all.forwarding=1 +ip netns exec $R2 sysctl -wq net.ipv6.conf.all.forwarding=1 + +ip -n $S addr add ${ip6_s_br0}/64 dev s_br0 nodad +ip -n $C addr add ${ip6_c_br1}/64 dev c_br1 nodad +ip -n $R1 addr add ${ip6_r1_br0}/64 dev r1_br0 nodad +ip -n $R1 addr add ${ip6_r1_br1}/64 dev r1_br1 nodad +ip -n $R2 addr add ${ip6_r2_br0}/64 dev r2_br0 nodad +ip -n $R2 addr add ${ip6_r2_br1}/64 dev r2_br1 nodad + +ip -n $S route add default via ${ip6_r1_br0} dev s_br0 +ip -n $C route add default via ${ip6_r1_br1} dev c_br1 + +ip4_s_br0=192.168.0.1 +ip4_r1_br0=192.168.0.254 +ip4_r2_br0=192.168.0.253 +ip4_c_br1=192.168.1.1 +ip4_r1_br1=192.168.1.254 +ip4_r2_br1=192.168.1.253 + +ip netns exec $R1 sysctl -wq net.ipv4.conf.all.forwarding=1 +ip netns exec $R2 sysctl -wq net.ipv4.conf.all.forwarding=1 + +ip -n $S addr add ${ip4_s_br0}/24 dev s_br0 +ip -n $C addr add ${ip4_c_br1}/24 dev c_br1 +ip -n $R1 addr add ${ip4_r1_br0}/24 dev r1_br0 +ip -n $R1 addr add ${ip4_r1_br1}/24 dev r1_br1 +ip -n $R2 addr add ${ip4_r2_br0}/24 dev r2_br0 +ip -n $R2 addr add ${ip4_r2_br1}/24 dev r2_br1 + +ip -n $S route add default via ${ip4_r1_br0} dev s_br0 +ip -n $C route add default via ${ip4_r1_br1} dev c_br1 + +ip netns exec $C ping -W 10 ${ip4_s_br0} -c2 > /dev/null +assert_pass "topo ipv4 initialization" +ip netns exec $C ping -W 10 ${ip6_s_br0} -c2 > /dev/null +assert_pass "topo ipv6 initialization" + +check_icmp_in_r1() +{ + local dst_addr="$1" + local PCAP="${WORKDIR}/$(mktemp -u XXXX).pcap" + ip netns exec $R1 tcpdump --immediate-mode -Ui r1_br0 -w ${PCAP} 2>/dev/null & + local pid=$! + ip netns exec $C ping -W 1 ${dst_addr} -c2 > /dev/null + assert_pass "ping pass" + + kill $pid; sync + tcpdump -nr ${PCAP} 2> /dev/null| grep -q "echo request" + assert_fail "echo request should be routed to r2" + + ip netns exec $R1 tcpdump -nr ${PCAP} 2> /dev/null | grep -q "echo reply" + assert_pass "echo relpy was observed" +} + +echo -e "\nTest ipv6 dscp reroute" +# The last two bits of the DSCP field are reserved for ECN. +# So nft dscp set 0x02 becomes 0x08 after a left shift by 2, +# which matches ip rule dsfield 0x08. +ip -6 -n $C route add default via ${ip6_r2_br1} dev c_br1 table 100 +ip -6 -n $C rule add dsfield 0x08 pref 1010 table 100 +assert_pass "Add ipv6 dscp policy routing rule" +ip netns exec $C nft -f - <<-EOF +table inet outgoing { + chain output_route { + type route hook output priority filter; policy accept; + icmpv6 type echo-request ip6 dscp set 0x02 counter + } +} +EOF +assert_pass "Restore nft ruleset" +check_icmp_in_r1 ${ip6_s_br0} +ip -6 -n $C rule del dsfield 0x08 pref 1010 table 100 +ip -6 -n $C route del default via ${ip6_r2_br1} dev c_br1 table 100 + + +echo -e "\nTest ipv4 dscp reroute" +ip -n $C route add default via ${ip4_r2_br1} dev c_br1 table 100 +ip -n $C rule add dsfield 0x08 pref 1010 table 100 +assert_pass "Add ipv4 dscp policy routing rule" +ip netns exec $C nft -f - <<-EOF +table inet outgoing { + chain output_route { + type route hook output priority filter; policy accept; + icmp type echo-request ip dscp set 0x02 counter + } +} +EOF +assert_pass "Restore nft ruleset" +check_icmp_in_r1 ${ip4_s_br0} +ip -n $C rule del dsfield 0x08 pref 1010 table 100 +ip -n $C route del default via ${ip4_r2_br1} dev c_br1 table 100 + + +echo -e "\nTest ipv4 fwmark reroute" +ip -n $C route add default via ${ip4_r2_br1} dev c_br1 table 100 +ip -n $C rule add fwmark 0x0100 lookup 100 +assert_pass "Add ipv4 fwmark policy routing rule" +ip netns exec $C nft -f - <<-EOF +table inet outgoing { + chain output_route { + type route hook output priority filter; policy accept; + icmp type echo-request meta mark set 0x0100 counter + } +} +EOF +assert_pass "Restore nft ruleset" +check_icmp_in_r1 ${ip4_s_br0} +ip -n $C rule del fwmark 0x0100 lookup 100 +ip -n $C route del default via ${ip4_r2_br1} dev c_br1 table 100 + + +echo -e "\nTest ipv6 fwmark reroute" +ip -6 -n $C route add default via ${ip6_r2_br1} dev c_br1 table 100 +ip -6 -n $C rule add fwmark 0x0100 lookup 100 +assert_pass "Add ipv6 fwmark policy routing rule" +ip netns exec $C nft -f - <<-EOF +table inet outgoing { + chain output_route { + type route hook output priority filter; policy accept; + icmpv6 type echo-request meta mark set 0x0100 counter + } +} +EOF +assert_pass "Restore nft ruleset" +check_icmp_in_r1 ${ip6_s_br0} +ip -6 -n $C rule del fwmark 0x0100 lookup 100 +ip -6 -n $C route del default via ${ip6_r2_br1} dev c_br1 table 100 |