[PATCH net-next v3 3/3] selftests: net: add coverage for fdb nexthop dst port

From: Jack Ma

Date: Tue Jul 21 2026 - 21:51:14 EST


Extend the existing fdb nexthop group tests with cases for the new
per-nexthop VXLAN destination port (NHA_FDB_PORT).

In fib_nexthops.sh, ipv4_fdb_grp_fcnal() and ipv6_fdb_grp_fcnal() now
check that a port is accepted on an fdb nexthop that has a gateway and
echoed back on dump, that it is rejected without a gateway and rejected
when zero, that a group may hold legs that differ only in UDP port, and
that a portless fdb nexthop omits the attribute. The cases SKIP when
iproute2 lacks the "port" keyword.

In test_vxlan_nh.sh, basic_tx_common() gains a second fdb nexthop group
whose nexthop carries a destination port that differs from the VXLAN
device default, plus a flower filter keyed on that port, to confirm the
per-nexthop port is used on the wire.

Signed-off-by: Jack Ma <jack4it@xxxxxxxxx>
---
tools/testing/selftests/net/fib_nexthops.sh | 59 ++++++++++++++++++++++++++++
tools/testing/selftests/net/test_vxlan_nh.sh | 31 +++++++++++++++
2 files changed, 90 insertions(+)

diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh
index ac868a731694..1ce4f45fa651 100755
--- a/tools/testing/selftests/net/fib_nexthops.sh
+++ b/tools/testing/selftests/net/fib_nexthops.sh
@@ -432,6 +432,15 @@ check_nexthop_fdb_support()
fi
}

+check_nexthop_fdb_port_support()
+{
+ $IP nexthop help 2>&1 | grep -q "fdb \[ port"
+ if [ $? -ne 0 ]; then
+ echo "SKIP: iproute2 too old, missing fdb nexthop port support"
+ return $ksft_skip
+ fi
+}
+
check_nexthop_res_support()
{
$IP nexthop help 2>&1 | grep -q resilient
@@ -514,6 +523,31 @@ ipv6_fdb_grp_fcnal()
run_cmd "$IP nexthop replace id 72 via 2001:db8:91::2 fdb"
log_test $? 2 "Replace non-FDB nexthop to FDB nexthop while in a group"

+ # NHA_FDB_PORT: optional per-nexthop VXLAN destination UDP port,
+ # letting an fdb nexthop group balance a flow across legs that share
+ # an underlay IP but listen on different UDP ports.
+ if check_nexthop_fdb_port_support; then
+ run_cmd "$IP nexthop add id 80 via 2001:db8:91::2 fdb port 4790"
+ check_nexthop "id 80" "id 80 via 2001:db8:91::2 scope link fdb port 4790"
+ log_test $? 0 "Fdb nexthop with port"
+
+ run_cmd "$IP nexthop add id 81 fdb port 4790"
+ log_test $? 2 "Fdb nexthop with port but no gateway"
+
+ run_cmd "$IP nexthop add id 81 via 2001:db8:91::2 fdb port 0"
+ log_test $? 2 "Fdb nexthop with port 0"
+
+ run_cmd "$IP nexthop add id 82 via 2001:db8:91::2 fdb port 4789"
+ run_cmd "$IP nexthop add id 83 via 2001:db8:91::3 fdb port 5789"
+ run_cmd "$IP nexthop add id 106 group 82/83 fdb"
+ check_nexthop "id 106" "id 106 group 82/83 fdb"
+ log_test $? 0 "Fdb nexthop group with legs differing in port"
+
+ run_cmd "$IP nexthop add id 84 via 2001:db8:91::2 fdb"
+ check_nexthop "id 84" "id 84 via 2001:db8:91::2 scope link fdb"
+ log_test $? 0 "Fdb nexthop without port omits port"
+ fi
+
run_cmd "$IP link add name vx10 type vxlan id 1010 local 2001:db8:91::9 remote 2001:db8:91::10 dstport 4789 nolearning noudpcsum tos inherit ttl 100"
run_cmd "$BRIDGE fdb add 02:02:00:00:00:13 dev vx10 nhid 102 self"
log_test $? 0 "Fdb mac add with nexthop group"
@@ -614,6 +648,31 @@ ipv4_fdb_grp_fcnal()
run_cmd "$IP nexthop replace id 20 via 172.16.1.2 fdb"
log_test $? 2 "Replace non-FDB nexthop to FDB nexthop while in a group"

+ # NHA_FDB_PORT: optional per-nexthop VXLAN destination UDP port,
+ # letting an fdb nexthop group balance a flow across legs that share
+ # an underlay IP but listen on different UDP ports.
+ if check_nexthop_fdb_port_support; then
+ run_cmd "$IP nexthop add id 30 via 172.16.1.2 fdb port 4790"
+ check_nexthop "id 30" "id 30 via 172.16.1.2 scope link fdb port 4790"
+ log_test $? 0 "Fdb nexthop with port"
+
+ run_cmd "$IP nexthop add id 31 fdb port 4790"
+ log_test $? 2 "Fdb nexthop with port but no gateway"
+
+ run_cmd "$IP nexthop add id 31 via 172.16.1.2 fdb port 0"
+ log_test $? 2 "Fdb nexthop with port 0"
+
+ run_cmd "$IP nexthop add id 32 via 172.16.1.2 fdb port 4789"
+ run_cmd "$IP nexthop add id 33 via 172.16.1.3 fdb port 5789"
+ run_cmd "$IP nexthop add id 105 group 32/33 fdb"
+ check_nexthop "id 105" "id 105 group 32/33 fdb"
+ log_test $? 0 "Fdb nexthop group with legs differing in port"
+
+ run_cmd "$IP nexthop add id 34 via 172.16.1.2 fdb"
+ check_nexthop "id 34" "id 34 via 172.16.1.2 scope link fdb"
+ log_test $? 0 "Fdb nexthop without port omits port"
+ fi
+
run_cmd "$IP link add name vx10 type vxlan id 1010 local 10.0.0.1 remote 10.0.0.2 dstport 4789 nolearning noudpcsum tos inherit ttl 100"
run_cmd "$BRIDGE fdb add 02:02:00:00:00:13 dev vx10 nhid 102 self"
log_test $? 0 "Fdb mac add with nexthop group"
diff --git a/tools/testing/selftests/net/test_vxlan_nh.sh b/tools/testing/selftests/net/test_vxlan_nh.sh
index 20f3369f776b..34a24a4f95bf 100755
--- a/tools/testing/selftests/net/test_vxlan_nh.sh
+++ b/tools/testing/selftests/net/test_vxlan_nh.sh
@@ -56,6 +56,16 @@ tc_stats_get()
tc_rule_handle_stats_get "dev dummy1 egress" 101 ".packets" "-n $ns1"
}

+nh_stats_get_port()
+{
+ ip -n "$ns1" -s -j nexthop show id 20 | jq ".[][\"group_stats\"][][\"packets\"]"
+}
+
+tc_stats_get_port()
+{
+ tc_rule_handle_stats_get "dev dummy1 egress" 102 ".packets" "-n $ns1"
+}
+
basic_tx_common()
{
local af_str=$1; shift
@@ -90,6 +100,27 @@ basic_tx_common()
busywait "$BUSYWAIT_TIMEOUT" until_counter_is "== 1" tc_stats_get > /dev/null
check_err $? "tc filter stats did not increase"

+ # Add a second FDB nexthop group whose nexthop carries a per-nexthop
+ # destination port (NHA_FDB_PORT) that differs from the VXLAN device
+ # default. Matching outer traffic must egress with that port, so a
+ # separate flower filter keyed on the new port catches it.
+ if ip nexthop help 2>&1 | grep -q "fdb \[ port"; then
+ run_cmd "tc -n $ns1 filter add dev dummy1 egress proto $proto pref 1 handle 102 flower ip_proto udp dst_ip $remote_addr dst_port 4790 action pass"
+
+ run_cmd "ip -n $ns1 nexthop add id 2 via $remote_addr fdb port 4790"
+ run_cmd "ip -n $ns1 nexthop add id 20 group 2 fdb"
+
+ run_cmd "bridge -n $ns1 fdb add 00:11:22:33:44:66 dev vx0 self static nhid 20"
+
+ run_cmd "ip netns exec $ns1 mausezahn vx0 -a own -b 00:11:22:33:44:66 -c 1 -q"
+
+ busywait "$BUSYWAIT_TIMEOUT" until_counter_is "== 1" nh_stats_get_port > /dev/null
+ check_err $? "FDB nexthop group stats did not increase (with port)"
+
+ busywait "$BUSYWAIT_TIMEOUT" until_counter_is "== 1" tc_stats_get_port > /dev/null
+ check_err $? "tc filter stats did not increase (with port)"
+ fi
+
log_test "VXLAN FDB nexthop: $af_str basic Tx"
}


--
2.43.0