[Devel] [PATCH vz10 v2 6/6] selftests: net: let the bridged PMTU tests take the ICMP they ask for

Konstantin Khorenko khorenko at virtuozzo.com
Tue Sep 22 17:27:15 MSK 2026


  I am not taking this patch. Instead I will cherry-pick the upstream commit
  it is a piece of:

    b58d74963320 ("tunnels: Drop stale dst when building an ICMP error for
    PMTUD")

  Why the test fails here at all

    Upstream commit 8930424777e4 ("tunnels: Accept PACKET_HOST in
    skb_tunnel_check_pmtu()") made bridged vxlan/geneve build a "Frag needed"
    ICMP for locally generated packets too, not only for forwarded ones.
    Our tree has it via the RHEL 6.12.0-211.16.1 import (see the blame of
    net/ipv4/ip_tunnel_core.c:425). That is the ICMP ns_a's own ping now
    receives, and that is what makes ping stop on the -w deadline.

  Why the test change alone is not enough

    8930424777e4 also introduced a bug. The ICMP error is built around the
    original packet, which for a routed or locally generated overlay packet
    still carries a valid dst. The error is then re-injected into the Rx
    path with that stale dst, so the IP layer skips the route lookup and the
    ICMP is either dropped or sent back out of the tunnel instead of being
    delivered to the overlay source.

    b58d74963320 fixes that: iptunnel_pmtud_build_icmp() and
    iptunnel_pmtud_build_icmpv6() drop the dst, so the ICMP gets a proper
    route lookup. It is marked Cc: stable and has Fixes: 8930424777e4.

  What this patch is

    The pmtu.sh hunk here is byte for byte the selftest part of that same
    upstream commit. Taking the test half as a vz patch and leaving the
    kernel half out would make the test pass while the kernel keeps
    misrouting PMTUD errors on bridged tunnels.

  So: one ms/ cherry-pick of b58d74963320, kernel fix and test change
  together, instead of a vz-only change to the test.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 9/22/26 14:02, Eva Kurchatova wrote:
> The bridged tunnel PMTU tests send a packet that is too big to make the
> tunnel answer with "Frag needed", which is how the route exception they
> check gets created. The ping that does it from the namespace holding
> the bridge is given a deadline, and ping(8) says of it:
> 
>   In this case ping does not stop after count packet are sent, it waits
>   either for deadline expire or until count probes are answered or for
>   some error notification from network.
> 
> so it stops at that very ICMP and reports the loss:
> 
>   # ping -M want -i 0.1 -w 1 -s 4500 192.168.2.2
>   From 192.168.2.2 icmp_seq=2 Frag needed and DF set (mtu = 3950)
>   2 packets transmitted, 0 received, +1 errors, 100% packet loss
> 
>   TEST: IPv4, bridged vxlan4: PMTU exceptions                    [FAIL]
> 
> The exception is created all the same, and with the right value, the
> test never gets to look at it. Ask for a count of pings instead, as
> the line above this one already does for the other namespace, so the
> error is counted and the run goes on.
> 
> All 16 bridged cases pass with this, vxlan and geneve, over IPv4 and
> IPv6.
> 
> https://virtuozzo.atlassian.net/browse/VSTOR-139651
> Feature: fix selftests
> Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>
> ---
>  tools/testing/selftests/net/pmtu.sh | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
> index 6c651c880fe8..d607429840cf 100755
> --- a/tools/testing/selftests/net/pmtu.sh
> +++ b/tools/testing/selftests/net/pmtu.sh
> @@ -1409,7 +1409,12 @@ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() {
>  	mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
>  
>  	run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 10 -s $((${ll_mtu} + 500)) ${dst} || return 1
> -	run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1  -s $((${ll_mtu} + 500)) ${dst} || return 1
> +	# This ping is meant to draw the ICMP that creates the exception,
> +	# and ping stops on "some error notification from network" where a
> +	# deadline is given, see ping(8), so it would always report the
> +	# loss and fail here.  Send a count of them instead, as the ping
> +	# above does.
> +	run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -c 10 -s $((${ll_mtu} + 500)) ${dst} || return 1
>  
>  	# Check that exceptions were created
>  	pmtu="$(route_get_dst_pmtu_from_exception "${ns_c}" ${dst})"



More information about the Devel mailing list