Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets
@ 2026-09-29 15:38 Eric Dumazet
  2026-09-30 12:37 ` David Ahern
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Eric Dumazet @ 2026-09-29 15:38 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Neal Cardwell, Kuniyuki Iwashima, David Ahern,
	Ido Schimmel, edumazet, netdev, Eric Dumazet

ip_select_ident_segs() uses the per-socket private generator
for connected sockets, even for packets with IP_DF set.

This was historically done to work around buggy Windows95/2000
VJ header compression implementations, dropping every other
packet in a TCP stream when the IP ID field did not change.

RFC 6864 section 4.2 states that "Originating sources MAY set the
IPv4 ID field of atomic datagrams to any value".

Packets with IP_DF set and skb->ignore_df cleared can not be
fragmented, neither locally (ip_fragment() refuses to do so)
nor by routers on the path.

Set their IPID to zero, like we already do for unconnected sockets
and in ip_build_and_send_pkt(). FreeBSD also does the same by
default (net.inet.ip.rfc6864 = 1).

Connected sockets still use their private generator for packets
without IP_DF, or with skb->ignore_df set.

This avoids an atomic operation on a shared cache line for
connected UDP sockets using IP_PMTUDISC_DO/IP_PMTUDISC_PROBE,
and TCP no longer touches inet->inet_id in the fast path.

Minor side effects: IP IDs can no longer be used to distinguish
network duplicates from TCP retransmits, or to correlate packet
captures taken at different points. OS fingerprints will also change.

Signed-off-by: Eric Dumazet <edumazet@kernel.org>
---
 include/net/ip.h | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/include/net/ip.h b/include/net/ip.h
index 6f602df72ee621ee4ee45e70beef0a1b5145367f..ffa4ba0b571fc42ba9855e2f3bbcb1c6d12a1e1d 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -584,6 +584,13 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
 {
 	struct iphdr *iph = ip_hdr(skb);
 
+	/* RFC 6864: the IPv4 ID of atomic datagrams has no meaning.
+	 * DF packets without ignore_df can not be fragmented.
+	 */
+	if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
+		iph->id = 0;
+		return;
+	}
 	/* We had many attacks based on IPID, use the private
 	 * generator as much as we can.
 	 */
@@ -603,12 +610,8 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
 		iph->id = htons(val);
 		return;
 	}
-	if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
-		iph->id = 0;
-	} else {
-		/* Unfortunately we need the big hammer to get a suitable IPID */
-		__ip_select_ident(net, iph, segs);
-	}
+	/* Unfortunately we need the big hammer to get a suitable IPID */
+	__ip_select_ident(net, iph, segs);
 }
 
 static inline void ip_select_ident(struct net *net, struct sk_buff *skb,
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets
  2026-09-29 15:38 [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets Eric Dumazet
@ 2026-09-30 12:37 ` David Ahern
  2026-10-01  5:09 ` Kuniyuki Iwashima
  2026-10-01  9:29 ` netdev-bot+sashiko
  2 siblings, 0 replies; 5+ messages in thread
From: David Ahern @ 2026-09-30 12:37 UTC (permalink / raw)
  To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Neal Cardwell, Kuniyuki Iwashima, Ido Schimmel,
	edumazet, netdev

On 9/29/26 10:38 AM, Eric Dumazet wrote:
> ip_select_ident_segs() uses the per-socket private generator
> for connected sockets, even for packets with IP_DF set.
> 
> This was historically done to work around buggy Windows95/2000
> VJ header compression implementations, dropping every other
> packet in a TCP stream when the IP ID field did not change.
> 
> RFC 6864 section 4.2 states that "Originating sources MAY set the
> IPv4 ID field of atomic datagrams to any value".
> 
> Packets with IP_DF set and skb->ignore_df cleared can not be
> fragmented, neither locally (ip_fragment() refuses to do so)
> nor by routers on the path.
> 
> Set their IPID to zero, like we already do for unconnected sockets
> and in ip_build_and_send_pkt(). FreeBSD also does the same by
> default (net.inet.ip.rfc6864 = 1).
> 
> Connected sockets still use their private generator for packets
> without IP_DF, or with skb->ignore_df set.
> 
> This avoids an atomic operation on a shared cache line for
> connected UDP sockets using IP_PMTUDISC_DO/IP_PMTUDISC_PROBE,
> and TCP no longer touches inet->inet_id in the fast path.
> 
> Minor side effects: IP IDs can no longer be used to distinguish
> network duplicates from TCP retransmits, or to correlate packet
> captures taken at different points. OS fingerprints will also change.
> 
> Signed-off-by: Eric Dumazet <edumazet@kernel.org>
> ---
>  include/net/ip.h | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 

Reviewed-by: David Ahern <dsahern@kernel.org>



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets
  2026-09-29 15:38 [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets Eric Dumazet
  2026-09-30 12:37 ` David Ahern
@ 2026-10-01  5:09 ` Kuniyuki Iwashima
  2026-10-01  9:29 ` netdev-bot+sashiko
  2 siblings, 0 replies; 5+ messages in thread
From: Kuniyuki Iwashima @ 2026-10-01  5:09 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Neal Cardwell, David Ahern, Ido Schimmel, edumazet, netdev

On Tue, Sep 29, 2026 at 8:38 AM Eric Dumazet <edumazet@kernel.org> wrote:
>
> ip_select_ident_segs() uses the per-socket private generator
> for connected sockets, even for packets with IP_DF set.
>
> This was historically done to work around buggy Windows95/2000
> VJ header compression implementations, dropping every other
> packet in a TCP stream when the IP ID field did not change.
>
> RFC 6864 section 4.2 states that "Originating sources MAY set the
> IPv4 ID field of atomic datagrams to any value".
>
> Packets with IP_DF set and skb->ignore_df cleared can not be
> fragmented, neither locally (ip_fragment() refuses to do so)
> nor by routers on the path.
>
> Set their IPID to zero, like we already do for unconnected sockets
> and in ip_build_and_send_pkt(). FreeBSD also does the same by
> default (net.inet.ip.rfc6864 = 1).
>
> Connected sockets still use their private generator for packets
> without IP_DF, or with skb->ignore_df set.
>
> This avoids an atomic operation on a shared cache line for
> connected UDP sockets using IP_PMTUDISC_DO/IP_PMTUDISC_PROBE,
> and TCP no longer touches inet->inet_id in the fast path.
>
> Minor side effects: IP IDs can no longer be used to distinguish
> network duplicates from TCP retransmits, or to correlate packet
> captures taken at different points. OS fingerprints will also change.
>
> Signed-off-by: Eric Dumazet <edumazet@kernel.org>

Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets
  2026-09-29 15:38 [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets Eric Dumazet
  2026-09-30 12:37 ` David Ahern
  2026-10-01  5:09 ` Kuniyuki Iwashima
@ 2026-10-01  9:29 ` netdev-bot+sashiko
  2026-10-01 15:50   ` Eric Dumazet
  2 siblings, 1 reply; 5+ messages in thread
From: netdev-bot+sashiko @ 2026-10-01  9:29 UTC (permalink / raw)
  To: edumazet
  Cc: davem, kuba, pabeni, horms, ncardwell, kuniyu, dsahern, idosch,
	edumazet, netdev

Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider.

Critical: 0 · High: 0 · Medium: 1 · Low: 1

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [Medium] TCP TSO/GSO skbs now carry IPv4 IDs that restart at 0 on every
  skb.
- [Low] The kernel-doc for struct inet_sock (include/net/inet_sock.h)
  still says `@inet_id - ID counter for DF pkts`.

--

ipv4: use zero IPID for atomic datagrams on connected sockets

This patch moves the DF && !ignore_df check in ip_select_ident_segs()
ahead of the per-socket private generator. On connected sockets, atomic
datagrams now get an IP ID of zero, and inet_id is used only for non-DF
packets or packets with skb->ignore_df set. The stated goal is to avoid
an atomic operation on a shared cache line and to keep TCP from touching
inet->inet_id in the fast path.

> diff --git a/include/net/ip.h b/include/net/ip.h
> index 6f602df72ee62..ffa4ba0b571fc 100644
> --- a/include/net/ip.h
> +++ b/include/net/ip.h
> @@ -584,6 +584,13 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
>  {
>  	struct iphdr *iph = ip_hdr(skb);
>  
> +	/* RFC 6864: the IPv4 ID of atomic datagrams has no meaning.
> +	 * DF packets without ignore_df can not be fragmented.
> +	 */
> +	if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
> +		iph->id = 0;
> +		return;
> +	}

[Severity: Medium]
Does this also change the IDs of TCP TSO/GSO skbs, not only single
atomic datagrams?

__ip_queue_xmit() still passes the segment count:

	ip_select_ident_segs(net, skb, sk,
			     skb_shinfo(skb)->gso_segs ?: 1);

The new early return ignores segs. The template ID is now 0, and inet_id
is no longer advanced by segs.

TCP never sets SKB_GSO_TCP_FIXEDID, so inet_gso_segment() in
net/ipv4/af_inet.c takes the !fixedid path:

		} else {
			if (!fixedid)
				iph->id = htons(id++);

TSO hardware behaves the same way. From
Documentation/networking/segmentation-offloads.rst:

  "The default behavior is to increment the IP ID with every segment."

So each TSO skb goes out with IDs 0, 1, ..., n-1, and the next skb of
the flow starts again at 0. Before this patch, the IDs continued across
skbs.

On a Linux receiver, tcp_gro_receive()->gro_receive_network_flush()->
inet_gro_flush() checks ID continuity:

	if (count == 1 && !ipid_offset)
		NAPI_GRO_CB(p)->ip_fixedid |= 1 << inner;

	return ipid_offset ^ (count * !(NAPI_GRO_CB(p)->ip_fixedid & (1 << inner)));

At each sender skb boundary, the arriving segment has ID 0, the same as
the held head. So ipid_offset is 0 while count is not, and the flow gets
flushed.

Does this mean receiver GRO can no longer merge across sender TSO skbs?

It can get worse when a single-MSS skb (ID 0) is followed by a TSO skb
(IDs 0, 1, ...). On the second frame, count == 1 and ipid_offset == 0,
so the chain switches to fixed-ID mode. The next incrementing ID then
flushes it again.

How much this hurts probably depends on how the receiver's gro_max_size
compares with the sender's TSO skb size. BIG TCP receivers, small
cwnd-limited TSO bursts, and mixes of single-MSS and TSO skbs look the
most exposed. Connected UDP GSO already lost ID continuity before this
patch, because __ip_make_skb() uses ip_select_ident() with segs=1. The
new behaviour change is on the TCP path.

The commit message says DF packets on connected sockets get their IPID
set to zero, and the new comment says the ID "has no meaning". Neither
holds for multi-segment skbs. The "Minor side effects" paragraph also
does not mention the GRO impact.

Was this trade-off intended, and should the changelog mention it?

[Severity: Low]
This isn't a bug, but the kernel-doc for struct inet_sock in
include/net/inet_sock.h still says:

 * @inet_id - ID counter for DF pkts

After this change, inet_id is used only for non-DF packets and for DF
packets with skb->ignore_df set, which is the reverse of what the
comment says.

Could that comment be updated as well?

tcp_v4_connect() and tcp_v4_syn_recv_sock() still seed inet_id with
get_random_u16(). Non-DF TCP (for example IP_PMTUDISC_DONT) still needs
that, so only the comment is out of date.

[ ... ]

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260929153834.566551-1-edumazet%40kernel.org

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets
  2026-10-01  9:29 ` netdev-bot+sashiko
@ 2026-10-01 15:50   ` Eric Dumazet
  0 siblings, 0 replies; 5+ messages in thread
From: Eric Dumazet @ 2026-10-01 15:50 UTC (permalink / raw)
  To: netdev-bot+sashiko
  Cc: davem, kuba, pabeni, horms, ncardwell, kuniyu, dsahern, idosch,
	edumazet, netdev

On Thu, Oct 1, 2026 at 11:29 AM <netdev-bot+sashiko@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 2 potential
> issue(s) to consider.
>
> Critical: 0 · High: 0 · Medium: 1 · Low: 1
>
> If you believe none of the issues are legitimate, please reply to each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let patchwork
> know by including "pw-bot: cr" as a separate line at the end of your reply
> (one such reply per series is enough).
>
> - [Medium] TCP TSO/GSO skbs now carry IPv4 IDs that restart at 0 on every
>   skb.

GRO already terminates each sender TSO packet since 2019, commit 051ba67447de
("tcp: force a PSH flag on TSO packets"), every TSO skb carries PSH on
its last segment, and tcp_gro_receive() flushes on PSH. IP ID restarting
at 0 on every TSO skb therefore does not add GRO flushes.

The only extra flush is a 1-MSS skb (without PSH) followed by a TSO skb,
which happens under cwnd/congestion limited conditions, where we already
choose to delay delivery on purpose.

> - [Low] The kernel-doc for struct inet_sock (include/net/inet_sock.h)
>   still says `@inet_id - ID counter for DF pkts`.

Okay I will update the inet_id kernel-doc in v2.

pw-bot: cr

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-01 15:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29 15:38 [PATCH net-next] ipv4: use zero IPID for atomic datagrams on connected sockets Eric Dumazet
2026-09-30 12:37 ` David Ahern
2026-10-01  5:09 ` Kuniyuki Iwashima
2026-10-01  9:29 ` netdev-bot+sashiko
2026-10-01 15:50   ` Eric Dumazet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox