* [PATCH net v3] ipvs: fix MTU check for GSO packets in tunnel mode
@ 2026-04-02 14:46 Yingnan Zhang
2026-04-03 14:20 ` Julian Anastasov
2026-04-10 1:11 ` Pablo Neira Ayuso
0 siblings, 2 replies; 4+ messages in thread
From: Yingnan Zhang @ 2026-04-02 14:46 UTC (permalink / raw)
To: horms, ja
Cc: pablo, fw, phil, davem, edumazet, kuba, pabeni, netdev, lvs-devel,
netfilter-devel, coreteam, linux-kernel, Yingnan Zhang
Currently, IPVS skips MTU checks for GSO packets by excluding them with
the !skb_is_gso(skb) condition. This creates problems when IPVS tunnel
mode encapsulates GSO packets with IPIP headers.
The issue manifests in two ways:
1. MTU violation after encapsulation:
When a GSO packet passes through IPVS tunnel mode, the original MTU
check is bypassed. After adding the IPIP tunnel header, the packet
size may exceed the outgoing interface MTU, leading to unexpected
fragmentation at the IP layer.
2. Fragmentation with problematic IP IDs:
When net.ipv4.vs.pmtu_disc=1 and a GSO packet with multiple segments
is fragmented after encapsulation, each segment gets a sequentially
incremented IP ID (0, 1, 2, ...). This happens because:
a) The GSO packet bypasses MTU check and gets encapsulated
b) At __ip_finish_output, the oversized GSO packet is split into
separate SKBs (one per segment), with IP IDs incrementing
c) Each SKB is then fragmented again based on the actual MTU
This sequential IP ID allocation differs from the expected behavior
and can cause issues with fragment reassembly and packet tracking.
Fix this by properly validating GSO packets using
skb_gso_validate_network_len(). This function correctly validates
whether the GSO segments will fit within the MTU after segmentation. If
validation fails, send an ICMP Fragmentation Needed message to enable
proper PMTU discovery.
Fixes: 4cdd34084d53 ("netfilter: nf_conntrack_ipv6: improve fragmentation handling")
Signed-off-by: Yingnan Zhang <342144303@qq.com>
---
v3:
- Fixed compilation error (removed extra closing brace in IPv6 function)
- Fixed indentation to match kernel style
v2: https://lore.kernel.org/netdev/20260402030541.27855-1-342144303@qq.com/
v1: https://lore.kernel.org/netdev/20260401152228.31190-1-342144303@qq.com/
---
net/netfilter/ipvs/ip_vs_xmit.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 3601eb86d..a4ca7cad0 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -111,8 +111,8 @@ __mtu_check_toobig_v6(const struct sk_buff *skb, u32 mtu)
*/
if (IP6CB(skb)->frag_max_size > mtu)
return true; /* largest fragment violate MTU */
- }
- else if (skb->len > mtu && !skb_is_gso(skb)) {
+ } else if (skb->len > mtu &&
+ !(skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))) {
return true; /* Packet size violate MTU size */
}
return false;
@@ -232,8 +232,9 @@ static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af,
return true;
if (unlikely(ip_hdr(skb)->frag_off & htons(IP_DF) &&
- skb->len > mtu && !skb_is_gso(skb) &&
- !ip_vs_iph_icmp(ipvsh))) {
+ skb->len > mtu && !ip_vs_iph_icmp(ipvsh) &&
+ !(skb_is_gso(skb) &&
+ skb_gso_validate_network_len(skb, mtu)))) {
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(mtu));
IP_VS_DBG(1, "frag needed for %pI4\n",
--
2.51.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH net v3] ipvs: fix MTU check for GSO packets in tunnel mode
2026-04-02 14:46 [PATCH net v3] ipvs: fix MTU check for GSO packets in tunnel mode Yingnan Zhang
@ 2026-04-03 14:20 ` Julian Anastasov
2026-04-10 1:11 ` Pablo Neira Ayuso
1 sibling, 0 replies; 4+ messages in thread
From: Julian Anastasov @ 2026-04-03 14:20 UTC (permalink / raw)
To: Yingnan Zhang
Cc: horms, pablo, fw, phil, davem, edumazet, kuba, pabeni, netdev,
lvs-devel, netfilter-devel, coreteam, linux-kernel
Hello,
On Thu, 2 Apr 2026, Yingnan Zhang wrote:
> Currently, IPVS skips MTU checks for GSO packets by excluding them with
> the !skb_is_gso(skb) condition. This creates problems when IPVS tunnel
> mode encapsulates GSO packets with IPIP headers.
>
> The issue manifests in two ways:
>
> 1. MTU violation after encapsulation:
> When a GSO packet passes through IPVS tunnel mode, the original MTU
> check is bypassed. After adding the IPIP tunnel header, the packet
> size may exceed the outgoing interface MTU, leading to unexpected
> fragmentation at the IP layer.
>
> 2. Fragmentation with problematic IP IDs:
> When net.ipv4.vs.pmtu_disc=1 and a GSO packet with multiple segments
> is fragmented after encapsulation, each segment gets a sequentially
> incremented IP ID (0, 1, 2, ...). This happens because:
>
> a) The GSO packet bypasses MTU check and gets encapsulated
> b) At __ip_finish_output, the oversized GSO packet is split into
> separate SKBs (one per segment), with IP IDs incrementing
> c) Each SKB is then fragmented again based on the actual MTU
>
> This sequential IP ID allocation differs from the expected behavior
> and can cause issues with fragment reassembly and packet tracking.
>
> Fix this by properly validating GSO packets using
> skb_gso_validate_network_len(). This function correctly validates
> whether the GSO segments will fit within the MTU after segmentation. If
> validation fails, send an ICMP Fragmentation Needed message to enable
> proper PMTU discovery.
>
> Fixes: 4cdd34084d53 ("netfilter: nf_conntrack_ipv6: improve fragmentation handling")
> Signed-off-by: Yingnan Zhang <342144303@qq.com>
Looks good to me for the nf tree, thanks!
Acked-by: Julian Anastasov <ja@ssi.bg>
> ---
> v3:
> - Fixed compilation error (removed extra closing brace in IPv6 function)
> - Fixed indentation to match kernel style
>
> v2: https://lore.kernel.org/netdev/20260402030541.27855-1-342144303@qq.com/
> v1: https://lore.kernel.org/netdev/20260401152228.31190-1-342144303@qq.com/
> ---
> net/netfilter/ipvs/ip_vs_xmit.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
> index 3601eb86d..a4ca7cad0 100644
> --- a/net/netfilter/ipvs/ip_vs_xmit.c
> +++ b/net/netfilter/ipvs/ip_vs_xmit.c
> @@ -111,8 +111,8 @@ __mtu_check_toobig_v6(const struct sk_buff *skb, u32 mtu)
> */
> if (IP6CB(skb)->frag_max_size > mtu)
> return true; /* largest fragment violate MTU */
> - }
> - else if (skb->len > mtu && !skb_is_gso(skb)) {
> + } else if (skb->len > mtu &&
> + !(skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))) {
> return true; /* Packet size violate MTU size */
> }
> return false;
> @@ -232,8 +232,9 @@ static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af,
> return true;
>
> if (unlikely(ip_hdr(skb)->frag_off & htons(IP_DF) &&
> - skb->len > mtu && !skb_is_gso(skb) &&
> - !ip_vs_iph_icmp(ipvsh))) {
> + skb->len > mtu && !ip_vs_iph_icmp(ipvsh) &&
> + !(skb_is_gso(skb) &&
> + skb_gso_validate_network_len(skb, mtu)))) {
> icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
> htonl(mtu));
> IP_VS_DBG(1, "frag needed for %pI4\n",
> --
> 2.51.0
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH net v3] ipvs: fix MTU check for GSO packets in tunnel mode
2026-04-02 14:46 [PATCH net v3] ipvs: fix MTU check for GSO packets in tunnel mode Yingnan Zhang
2026-04-03 14:20 ` Julian Anastasov
@ 2026-04-10 1:11 ` Pablo Neira Ayuso
2026-04-10 6:51 ` Julian Anastasov
1 sibling, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2026-04-10 1:11 UTC (permalink / raw)
To: Yingnan Zhang
Cc: horms, ja, fw, phil, davem, edumazet, kuba, pabeni, netdev,
lvs-devel, netfilter-devel, coreteam, linux-kernel
On Thu, Apr 02, 2026 at 10:46:16PM +0800, Yingnan Zhang wrote:
> Currently, IPVS skips MTU checks for GSO packets by excluding them with
> the !skb_is_gso(skb) condition. This creates problems when IPVS tunnel
> mode encapsulates GSO packets with IPIP headers.
>
> The issue manifests in two ways:
>
> 1. MTU violation after encapsulation:
> When a GSO packet passes through IPVS tunnel mode, the original MTU
> check is bypassed. After adding the IPIP tunnel header, the packet
> size may exceed the outgoing interface MTU, leading to unexpected
> fragmentation at the IP layer.
>
> 2. Fragmentation with problematic IP IDs:
> When net.ipv4.vs.pmtu_disc=1 and a GSO packet with multiple segments
> is fragmented after encapsulation, each segment gets a sequentially
> incremented IP ID (0, 1, 2, ...). This happens because:
>
> a) The GSO packet bypasses MTU check and gets encapsulated
> b) At __ip_finish_output, the oversized GSO packet is split into
> separate SKBs (one per segment), with IP IDs incrementing
> c) Each SKB is then fragmented again based on the actual MTU
>
> This sequential IP ID allocation differs from the expected behavior
> and can cause issues with fragment reassembly and packet tracking.
>
> Fix this by properly validating GSO packets using
> skb_gso_validate_network_len(). This function correctly validates
> whether the GSO segments will fit within the MTU after segmentation. If
> validation fails, send an ICMP Fragmentation Needed message to enable
> proper PMTU discovery.
>
> Fixes: 4cdd34084d53 ("netfilter: nf_conntrack_ipv6: improve fragmentation handling")
> Signed-off-by: Yingnan Zhang <342144303@qq.com>
> ---
> v3:
> - Fixed compilation error (removed extra closing brace in IPv6 function)
> - Fixed indentation to match kernel style
>
> v2: https://lore.kernel.org/netdev/20260402030541.27855-1-342144303@qq.com/
> v1: https://lore.kernel.org/netdev/20260401152228.31190-1-342144303@qq.com/
> ---
> net/netfilter/ipvs/ip_vs_xmit.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
> index 3601eb86d..a4ca7cad0 100644
> --- a/net/netfilter/ipvs/ip_vs_xmit.c
> +++ b/net/netfilter/ipvs/ip_vs_xmit.c
> @@ -111,8 +111,8 @@ __mtu_check_toobig_v6(const struct sk_buff *skb, u32 mtu)
> */
> if (IP6CB(skb)->frag_max_size > mtu)
> return true; /* largest fragment violate MTU */
> - }
> - else if (skb->len > mtu && !skb_is_gso(skb)) {
> + } else if (skb->len > mtu &&
> + !(skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))) {
Maybe helper function helps make this more readable?
/* Based on ip_exceeds_mtu(). */
static bool ip_vs_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
{
if (skb->len <= mtu)
return false;
if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
return false;
return true;
}
> return true; /* Packet size violate MTU size */
> }
> return false;
> @@ -232,8 +232,9 @@ static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af,
> return true;
>
> if (unlikely(ip_hdr(skb)->frag_off & htons(IP_DF) &&
> - skb->len > mtu && !skb_is_gso(skb) &&
> - !ip_vs_iph_icmp(ipvsh))) {
> + skb->len > mtu && !ip_vs_iph_icmp(ipvsh) &&
> + !(skb_is_gso(skb) &&
> + skb_gso_validate_network_len(skb, mtu)))) {
> icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
> htonl(mtu));
> IP_VS_DBG(1, "frag needed for %pI4\n",
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH net v3] ipvs: fix MTU check for GSO packets in tunnel mode
2026-04-10 1:11 ` Pablo Neira Ayuso
@ 2026-04-10 6:51 ` Julian Anastasov
0 siblings, 0 replies; 4+ messages in thread
From: Julian Anastasov @ 2026-04-10 6:51 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Yingnan Zhang, horms, fw, phil, davem, edumazet, kuba, pabeni,
netdev, lvs-devel, netfilter-devel, coreteam, linux-kernel
Hello,
On Fri, 10 Apr 2026, Pablo Neira Ayuso wrote:
> On Thu, Apr 02, 2026 at 10:46:16PM +0800, Yingnan Zhang wrote:
> > + } else if (skb->len > mtu &&
> > + !(skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))) {
>
> Maybe helper function helps make this more readable?
>
> /* Based on ip_exceeds_mtu(). */
> static bool ip_vs_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
> {
> if (skb->len <= mtu)
> return false;
>
> if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
> return false;
>
> return true;
> }
Good idea! Yingnan Zhang, please send v4 by adding
this new function before __mtu_check_toobig_v6()...
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-04-10 6:52 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-02 14:46 [PATCH net v3] ipvs: fix MTU check for GSO packets in tunnel mode Yingnan Zhang
2026-04-03 14:20 ` Julian Anastasov
2026-04-10 1:11 ` Pablo Neira Ayuso
2026-04-10 6:51 ` Julian Anastasov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox