summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYi Chen <yiche@redhat.com>2025-07-15 17:19:13 +0800
committerFlorian Westphal <fw@strlen.de>2025-07-16 20:35:35 +0200
commitfda6e2a0486804a68c352f384aedd549b7e81a40 (patch)
treee411e33cdce7333282564888da99f4d522ef7ba8
parent8a1de0ec9709b58a80a86a20cfba107b11c85f6e (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.nodump0
-rwxr-xr-xtests/shell/testcases/packetpath/type_route_chain201
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