On 11/20/25 6:49 PM, Dmitry Skorodumov wrote:
diff --git a/tools/testing/selftests/net/ipvtap_macnat_bridge.py b/tools/testing/selftests/net/ipvtap_macnat_bridge.py new file mode 100755 index 000000000000..7dc4a626e5bb --- /dev/null +++ b/tools/testing/selftests/net/ipvtap_macnat_bridge.py
[...]
- TAP = sys.argv[1]
- IPVTAP = sys.argv[2]
- print(f"Starting TAP bridge between {TAP} and {IPVTAP} in {ns_name}")
- bridge = TapBridge(TAP, IPVTAP)
- bridge.run()
This is not a complete review, but you need to add CONFIG_IPVTAP and CONFIG_TAP to tools/testing/selftests/net/config.
diff --git a/tools/testing/selftests/net/ipvtap_macnat_test.sh b/tools/testing/selftests/net/ipvtap_macnat_test.sh new file mode 100755 index 000000000000..927d75af776b --- /dev/null +++ b/tools/testing/selftests/net/ipvtap_macnat_test.sh @@ -0,0 +1,333 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Tests for ipvtap in macnat mode
+NS_TST0=ipvlan-tst-0 +NS_TST1=ipvlan-tst-1 +NS_PHY=ipvlan-tst-phy
Please use lib.sh / setup_ns instead, to avoid netns name conflicts and leverage automatic cleanup
+IP_HOST=172.25.0.1 +IP_PHY=172.25.0.2 +IP_TST0=172.25.0.10 +IP_TST1=172.25.0.30
+IP_OK0=("172.25.0.10" "172.25.0.11" "172.25.0.12" "172.25.0.13") +IP6_OK0=("fc00::10" "fc00::11" "fc00::12" "fc00::13" )
+IP_OVFL0="172.25.0.14" +IP6_OVFL0="fc00::14"
+IP6_HOST=fc00::1 +IP6_PHY=fc00::2 +IP6_TST0=fc00::10 +IP6_TST1=fc00::30
+MAC_HOST="92:3a:00:00:00:01" +MAC_PHY="92:3a:00:00:00:02" +MAC_TST0="92:3a:00:00:00:10" +MAC_TST1="92:3a:00:00:00:30"
+VETH_HOST=vethtst +VETH_PHY=vethtst.p
+# +# The testing environment looks this way: +# +# |------HOST------| |------PHY-------| +# | veth<----------------->veth | +# |------|--|------| |----------------| +# | | +# | | |-----TST0-------| +# | |------------|----ipvtap | +# | |----------------| +# | +# | |-----TST1-------| +# |---------------|----ivtap | +# |----------------| +# +# The macnat mode is for virtual machines, so ipvtap-interface is supposed +# to be used only for traffic monitoring and doesn't have ip-address. +# +# To simulate a virtual machine on ipvtap, we create TAP-interfaces +# in TST environments and assing IP-addresses to them. +# TAP and IPVTAP are connected with simple python script. +#
+ns_run() {
- ns=$1
- shift
- if [[ "$ns" == "default" ]]; then
"$@" >/dev/null- else
ip netns exec "$ns" "$@" >/dev/null- fi
+}
+configure_ns() {
- local ns=$1
- local n=$2
- local ip=$3
- local ip6=$4
- local mac=$5
- ns_run "$ns" ip link set lo up
- if ! ip link add netns "$ns" name "ipvtap0.$n" link $VETH_HOST \
type ipvtap mode l2macnat bridge; thenexit_error "FAIL: Failed to configure ipvtap link."- fi
- ns_run "$ns" ip link set "ipvtap0.$n" up
- ns_run "$ns" ip tuntap add mode tap "tap0.$n"
- ns_run "$ns" ip link set dev "tap0.$n" address "$mac"
- # disable dad
- ns_run "$ns" sysctl -w "net/ipv6/conf/tap0.$n/accept_dad"=0
- ns_run "$ns" ip link set "tap0.$n" up
- ns_run "$ns" ip a a "$ip/24" dev "tap0.$n"
- ns_run "$ns" ip a a "$ip6/64" dev "tap0.$n"
+}
+start_macnat_bridge() {
- local ns=$1
- local n=$2
- ip netns exec "$ns" python3 ipvtap_macnat_bridge.py \
"tap0.$n" "ipvtap0.$n" &+}
+configure_veth() {
- local ns=$1
- local veth=$2
- local ip=$3
- local ip6=$4
- local mac=$5
- ns_run "$ns" ip link set lo up
- ns_run "$ns" ethtool -K "$veth" tx off rx off
- ns_run "$ns" ip link set dev "$veth" address "$mac"
- ns_run "$ns" ip link set "$veth" up
- ns_run "$ns" ip a a "$ip/24" dev "$veth"
- ns_run "$ns" ip a a "$ip6/64" dev "$veth"
+}
+setup_env() {
- ip netns add $NS_TST0
- ip netns add $NS_TST1
- ip netns add $NS_PHY
- # setup simulated other-host (phy) and host itself
- ip link add $VETH_HOST type veth peer name $VETH_PHY \
netns $NS_PHY >/dev/null- # host config
- configure_veth default $VETH_HOST $IP_HOST $IP6_HOST $MAC_HOST
- configure_veth $NS_PHY $VETH_PHY $IP_PHY $IP6_PHY $MAC_PHY
- # TST namespaces config
- configure_ns $NS_TST0 0 $IP_TST0 $IP6_TST0 $MAC_TST0
- configure_ns $NS_TST1 1 $IP_TST1 $IP6_TST1 $MAC_TST1
+}
+ping_all() {
- # This will learn MAC/IP addresses on ipvtap
- local ns=$1
- ns_run "$ns" ping -c 1 $IP_TST0
- ns_run "$ns" ping -c 1 $IP6_TST0
- ns_run "$ns" ping -c 1 $IP_TST1
- ns_run "$ns" ping -c 1 $IP6_TST1
- ns_run "$ns" ping -c 1 $IP_HOST
- ns_run "$ns" ping -c 1 $IP6_HOST
- ns_run "$ns" ping -c 1 $IP_PHY
- ns_run "$ns" ping -c 1 $IP6_PHY
+}
+check_mac_eq() {
- # Ensure IP corresponds to MAC.
- local ns=$1
- local ip=$2
- local mac=$3
- local dev=$4
- if [[ "$ns" == "default" ]]; then
out=$(ip neigh show "$ip" dev "$dev" \| grep "$ip" \| grep "$mac")- else
out=$(ip netns exec "$ns" \ip neigh show "$ip" dev "$dev" \| grep "$ip" \| grep "$mac")- fi
- if [[ $out'X' == "X" ]]; then
exit_error "FAIL: '$ip' is not '$mac'"- fi
+}
+cleanup_env() {
- ip link del $VETH_HOST
- ip netns del $NS_TST0
- ip netns del $NS_TST1
- ip netns del $NS_PHY
+}
+exit_error() {
- echo "$1"
- exit 1
It would be better to try to run all the test-cases and return a single fail/success code. lib.sh can help with that. too.
/P