summaryrefslogtreecommitdiff
path: root/net/ipv4/tcp_input.c
AgeCommit message (Collapse)Author
10 daysMerge tag 'bpf-next-7.4' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next Pull bpf updates from Alexei Starovoitov: "Major changes: - Introduce scalar evolution (SCEV) analysis in the verifier. It infers how registers and stack slots change in a loop and lets the verifier check bounded loops with induction variables as ranges instead of walking every iteration. The number of processed insns drops ten fold in programs with loops (Eduard Zingerman) - Add 'callx' instruction: indirect call of a static BPF subprogram. The address is taken with ld_imm64 or loaded from read-only data. Supported by x86-64, arm64 and riscv64 JITs (Alexei Starovoitov, Pu Lehui) - Add unwind_goto and unwind_exit instructions, so that Rust panic or C++ exception can run destructors of every frame it passes through. The normal path is free of unwind code. Supported by x86-64 and arm64 JITs (Alexei Starovoitov) - Support programs compiled by rust-bpf: treat load and store through a number as arena access with BPF_F_ARENA_SCALAR, accept rust names in BTF (Alexei Starovoitov) - Raise BPF program stack size from 512 bytes to 2 KiB on x86-64 and arm64 (Kumar Kartikeya Dwivedi) - Support struct, union and __int128 up to 16 bytes passed and returned by value in BPF subprograms and kfuncs, and fix x86-64 and arm64 trampolines for such arguments (Yonghong Song) - Introduce a common way to attach struct_ops to a cgroup via bpf_link. bpf_tcp_ops is the first user and mirrors TCP sock_ops callbacks (Martin KaFai Lau, Amery Hung) - Describe inlined functions in BTF. New kinds tell where the inline sites are and how to fetch the arguments there. CONFIG_DEBUG_INFO_BTF_INLINE keeps it apart from the main BTF in .BTF.inline section or in btf_vmlinux_inline.ko (Alan Maguire) - Fix many memory safety, lifetime and locking bugs in BPF core, verifier, iterators, local storage, dynptr, devmap, cpumap and seg6local (Josef Bacik, Alexei Starovoitov) - Diff stat is dominated by selftests and by removal of lib/test_bpf.c. Its 16k lines of instruction tests were converted to BPF selftests that BPF CI runs on every architecture it covers (Daniel Borkmann) Other features and fixes: - Add KASAN checks to memory accesses of JITed programs on x86-64 (Alexis Lothoré) - Complete unification of helper, kfunc and subprog argument checks in the verifier (Amery Hung) - Add bpf_copy_from_user_mm[_str]() kfuncs (Anastasios Papagiannis) - Various features and fixes (Daniel Borkmann): - Add .bpf keyring for program signature verification, modelled after dm-verity keyring, and support ML-DSA in signing tools - Emit shorter and faster code in x86-64 JIT for patterns that LLVM generates - Fix various issues in gotox handling - Let BPF LSM set xattrs at inode creation with bpf_inode_init_xattr() (David Windsor, Daniel Borkmann) - Use sleepable page allocation in sleepable arena paths. Fix races between arena free, allocation and user page fault (Emil Tsalapatis) - Switch BPF crypto from lskcipher to AES-CBC and AES-ECB libraries (Eric Biggers) - Add bpf_proactive_reclaim() kfunc (Hui Zhu) - Render decl_tags in libbpf btf_dump and add tests for bpftool C dump (Ihor Solodrai) - Speed up tracing_multi attach on x86 (Jiri Olsa) - Various features and fixes (Kumar Kartikeya Dwivedi): - Add BPF_PROG_STREAM_OPEN command to read BPF streams through a file descriptor with poll support - Let kernel structs publish arena pointers with __arena type tag - Fix __uninit kfunc output buffers and fastcall rewrite with indirect stack accesses - Refuse CO-RE relocations for signed programs - Add enqueue_rcvq and dequeue_rcvq hooks to bpf_tcp_ops to adjust sk_rcvlowat and avoid unnecessary wakeups (Kuniyuki Iwashima) - Add bpf_ksock_sendto() kfunc and allow ksock connect and send from bpf_wq (Mahe Tardy) - Fix racy plt target update in arm64 bpf_arch_text_poke() (Matthew Wood) - Restructure BPF selftests Makefile as a layered build (Mykola Lysenko) - Speed up hash map lookups for u32 and u64 keys (Mykyta Yatsenko) - Add signed div/mod, movsx, bswap and gotol to MIPS JITs, signed div/mod to parisc JITs (Nicholas Dudar, Johan Almbladh) - Fix stack overflow in build ID parser on 32-bit (Nickolai Zeldovich) - Add stack arguments, signed arena loads and gotox to riscv64 JIT. Pu Lehui is now co-maintainer of riscv BPF JITs (Pu Lehui, Chen Pei, Feng Jiang) - Add bpf_call_rcu() and bpf_call_rcu_tasks_trace() kfuncs. Support fetching and/or/xor atomics in arena on x86-64 (Puranjay Mohan) - Fix flaky selftests, selftests with clang 23 and bpf-gcc (Qiliang Yuan, KaFai Wan, Vineet Gupta) - Fix builds broken by fatal resolve_btfids warnings, BTF generation on ARC, and define arch_cmpxchg_local() on arc, hexagon and openrisc (Sasha Levin) - Reduce memory use of hash maps by up to 50% per element (T.J. Mercier) - Mark pointer fields of sched_ext ops arguments as trusted (Tejun Heo) - Remove legacy bpf_asm, bpf_dbg and bpf_jit_disasm tools (Xia Yan) - Fix index overflow in queue and stack maps, arena range tree after allocation failure, tail call loop after freplace detach, lost signal in bpf_send_signal() (Yuan Chen) - Many more fixes and cleanups" * tag 'bpf-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (660 commits) selftests/bpf: Time tc_edt from its first packet with data selftests/bpf: Test unwind_exit of an exception callback selftests/bpf: Tests for 32-bit scalar evolution bounds computation bpf: Reject unwind_goto and unwind_exit in offloaded progs bpf: Support 32-bit linear scalar evolution bpf: Make unwind_exit of an exception callback exit in JITs selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach selftests/bpf: Test ksock sendto() bpf: Add bpf_ksock_sendto() kfunc selftests/bpf: Test unwinding from R0: R2 subprog selftests/bpf: Add a C++ prog with exceptions selftests/bpf: Add tests for unwind_goto and unwind_exit bpf, arm64: Support unwind_goto and unwind_exit bpf, x86: Support unwind_goto and unwind_exit bpf: Add unwind_goto and unwind_exit insns tools/bpf: Remove legacy BPF tools bpf: Annotate data races on bpf_lru_node type selftests/bpf: Add arena allocation race tests bpf: Fix arena race between page free and alloc leading to incoherency bpf: Revalidate faulted arena pages before installing user mappings ...
2026-10-10bpf: tcp: Introduce bpf_tcp_ops.{enqueue,dequeue}_rcvq().Kuniyuki Iwashima
Waking up a thread per packet is expensive when an application processes variable-length frames (e.g., RPC) that span multiple packets. SO_RCVLOWAT can defer wakeups, but because the frame size is encoded in a fixed-size descriptor at the start of each frame, the application has to: 1. wake up and recv() the descriptor, 2. raise SO_RCVLOWAT to the payload size via setsockopt(), 3. wake up and recv() the payload, and 4. reset SO_RCVLOWAT back to the descriptor size via setsockopt() for the next frame. This requires an extra wakeup and two setsockopt() syscalls for every single RPC frame. With SOCKMAP, we can parse skb and suppress wakeups in kernel, but SOCKMAP adds overhead and also kills zerocopy. Let's add lighter-weight opt-in callbacks to bpf_tcp_ops to replace that. .enqueue_rcvq(): invoked when TCP stack enqueues skb to sk->sk_receive_queue .dequeue_rcvq(): invoked in tcp_cleanup_rbuf() after data is dequeued from sk->sk_receive_queue Those callbacks can be enabled on a per-socket basis by bpf_tcp_ops_set_flags(): bpf_tcp_ops_set_flags((struct tcp_sock *)sk, BPF_TCP_OPS_FLAG_RCVQ, 0); Later, we will add a new kfunc to adjust sk->sk_rcvlowat from these callbacks. This will allow the bpf_tcp_ops prog to parse each skb and dynamically adjust sk->sk_rcvlowat to suppress unnecessary EPOLLIN wakeups until sufficient data is available in the receive queue. The placement of bpf_tcp_ops_call() in tcp_ofo_queue() and tcp_fastopen_add_skb() is chosen to provide the same snapshot as tcp_queue_rcv(). For example, if bpf_tcp_ops_call() were called before updating TCP_SKB_CB(skb)->seq in tcp_fastopen_add_skb(), BPF prog would need an extra branch for the unlikely TFO case to strip SYN. In addition, the TCP stack can queue overlapping skbs into recvq. Once rcv_nxt is updated with a new skb, BPF prog can no longer infer the previous rcv_nxt from skb->len. Lastly, dequeue_rcvq() is placed in tcp_cleanup_rbuf() rather than __tcp_cleanup_rbuf() so that it is not called for sockets in SOCKMAP, where calling sk->sk_data_ready() from the new kfunc would otherwise trigger infinite recursion. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Amery Hung <ameryhung@gmail.com> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20261008031604.256498-7-kuniyu@google.com
2026-10-10bpf: tcp: Check BPF_SOCK_OPS_TEST_FLAG() after ↵Kuniyuki Iwashima
cgroup_bpf_enabled(CGROUP_SOCK_OPS). BPF_CGROUP_RUN_PROG_XXX() macros guard __cgroup_bpf_run_filter_XXX() with cgroup_bpf_enabled(). However, even when no SOCK_OPS prog is attached, callers still initialise struct bpf_sock_ops_kern (memset(), etc.) or evaluate BPF_SOCK_OPS_TEST_FLAG(), which loads tp->bpf_sock_ops_cb_flags from a cold cacheline near the end of struct tcp_sock. Similar to bpf_tcp_ops, let's check cgroup_bpf_enabled() before BPF_SOCK_OPS_TEST_FLAG() and struct bpf_sock_ops_kern setup, and rename BPF_CGROUP_RUN_PROG_SOCK_OPS{,_SK}() with __ prefix. Since all direct callers of tcp_call_bpf() pass 0 and NULL for nargs and args, they can be folded into the new tcp_call_bpf() macro. All callers of tcp_call_bpf_{2,3}arg() check BPF_SOCK_OPS_TEST_FLAG() and do not need the return value. These are replaced with the new tcp_call_bpf_flag() macro. Now, bpf_skops_hdr_opt_len() and bpf_tcp_ops_hdr_opt_len() are just NOPs without bpf prog attached. $ llvm-objdump -S -D --disassemble=tcp_established_options vmlinux ... ; asm goto(ARCH_STATIC_BRANCH_ASM("%c0 + %c1", "%l[l_yes]") ; size = MAX_TCP_OPTION_SPACE - remaining; ffffffff825127ea: b9 28 00 00 00 movl $0x28, %ecx ffffffff825127ef: 29 c1 subl %eax, %ecx ; return size; ffffffff825127f1: 89 c8 movl %ecx, %eax ... ffffffff825127fb: 2e e9 6f 02 43 00 jmp 0xffffffff82942a70 <__x86_return_thunk> Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Amery Hung <ameryhung@gmail.com> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20261008031604.256498-6-kuniyu@google.com
2026-10-10bpf: tcp: Guard fast-path bpf_tcp_ops_call() under per-socket flag.Kuniyuki Iwashima
bpf_tcp_ops.{parse_hdr,hdr_opt_len} are called for every incoming / outgoing skb. bpf_tcp_ops.rtt is called once per RTT, which is every incoming skb in ping-pong workloads like tcp_rr. Even attaching NULL callbacks in the fast path hurts performance. Let's guard them (and write_hdr_opt) with the new per-socket flags. __bpf_tcp_ops_call() and bpf_tcp_ops_call_flag() are added to check cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS) first and avoid accessing tp->bpf_tcp_ops_flags when no bpf_tcp_ops is attached. Note that bpf_tcp_ops_hdr_opt_len() has 3 callers and previously checked the static key both in tcp_established_options() and inside bpf_tcp_ops_call(). Now the static key is checked once at the beginning of bpf_tcp_ops_hdr_opt_len(), and the redundant check in tcp_established_options() is removed. tcp_bpf_hdr_opt_len() must use __always_inline, not just inline, otherwise Clang inlines bpf_tcp_ops_hdr_opt_len() to tcp_bpf_hdr_opt_len() instead. $ llvm-objdump -S -D --disassemble=tcp_established_options vmlinux ... ; if (unlikely(BPF_SOCK_OPS_TEST_FLAG(tp, ffffffff8251270e: 41 f6 87 20 0c 00 00 40 testb $0x40, 0xc20(%r15) ffffffff82512716: 75 47 jne 0xffffffff8251275f <tcp_established_options+0x1ff> ; asm goto(ARCH_STATIC_BRANCH_ASM("%c0 + %c1", "%l[l_yes]") ffffffff82512718: 0f 1f 44 00 00 nopl (%rax,%rax) ; return size; ffffffff8251271d: 44 89 e0 movl %r12d, %eax ffffffff82512720: 5b popq %rbx ffffffff82512721: 41 5c popq %r12 ffffffff82512723: 41 5e popq %r14 ffffffff82512725: 41 5f popq %r15 ffffffff82512727: 5d popq %rbp ffffffff82512728: 2e e9 42 03 43 00 jmp 0xffffffff82942a70 <__x86_return_thunk> bpf_skops_write_hdr_opt() is still not free, but it can be optimised later if needed. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20261008031604.256498-5-kuniyu@google.com
2026-10-05tcp: add tp->tcp_nospaceEric Dumazet
tcp_check_space() runs for every incoming ACK and for every packet we send, and reads SOCK_NOSPACE from sk->sk_socket->flags. struct socket lives in its own cache line, which the TCP fast paths do not otherwise touch, so testing sk->sk_socket->flags pulls in an extra cache line that is cold when the working set is large. Add tp->tcp_nospace, a mirror of SOCK_NOSPACE placed right after tp->chrono_type in the tcp_sock_write_tx group, in a cache line both the transmit and the ACK paths already touch (bytes_sent, data_segs_out, delivered, bytes_acked, chrono_type). It fits in an existing 3-byte hole before chrono_start, so no other field moves and sizeof(struct tcp_sock) is unchanged. The two flags are now only changed from sk_set_nospace() and sk_clear_nospace(), which maintain this invariant: SOCK_NOSPACE set => tp->tcp_nospace set sk_set_nospace() sets SOCK_NOSPACE before tp->tcp_nospace (using smp_mb__after_atomic() and smp_store_mb()), while sk_clear_nospace() clears tp->tcp_nospace before SOCK_NOSPACE (using smp_mb__before_atomic()). If a lockless sk_set_nospace() from tcp_poll() races with sk_clear_nospace() and SOCK_NOSPACE ends up set, set_bit(SOCK_NOSPACE) happened after clear_bit(SOCK_NOSPACE), so tp->tcp_nospace = 1 happens after tp->tcp_nospace = 0 as well. tcp_check_space() can thus test tp->tcp_nospace alone and leave the authoritative SOCK_NOSPACE test to __tcp_check_space(). The invariant is one directional on purpose: a stale tp->tcp_nospace only costs an extra call to __tcp_check_space(), which is what we do unconditionally today, while a stale SOCK_NOSPACE would cost a missed EPOLLOUT. Note the smp_mb() is kept. tcp_poll() sets the flag without the socket lock, and the store-buffer pattern it forms with tcp_check_space() needs a full barrier on both sides. MPTCP subflows share the struct socket of their parent, hence its SOCK_NOSPACE bit, which can not be mirrored in the subflow tcp_sock. Pin their tp->tcp_nospace in subflow_ulp_init(), so that they always reach __tcp_check_space() and keep the current behavior. Microbenchmark on an AMD EPYC 7B13, 64 threads, each thread calling tcp_check_space() in a loop over a private set of sockets. Numbers are cycles per call above a baseline loop that performs the work the callers already did (the cache lines tcp_write_xmit() and tcp_clean_rtx_queue() touched) but not tcp_check_space() itself, so they are the marginal cost of the function. Median of 11 runs. The set size controls whether struct socket is still cached: sockets/thread before after 1 +0.6 +0.7 256 (64 KB) +8.3 +3.9 4096 (1 MB) +22.4 +1.1 262144 (64 MB) +48.4 -0.8 Signed-off-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20260929071743.23624-10-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-02Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 7.3-rc5Alexei Starovoitov
Cross-merge BPF and other fixes after downstream PR. Conflicts: arch/arm64/net/bpf_jit_comp.c arch/x86/net/bpf_jit_comp.c Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-10-01Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.3-rc6). Conflicts: net/mac80211/tx.c net/mac80211/ieee80211_i.h 8effab902fa34 ("wifi: mac80211: prevent AP VLAN tx from other interfaces") 78b843974fb83 ("wifi: mac80211: report multicast transmission from lookup_ra_sta()") https://lore.kernel.org/arJmcuhpJ69wAvYK@sirena.co.uk drivers/net/ethernet/realtek/r8169_main.c 3cdeaef1754ab ("r8169: disable EEE on RTL8168h/8111h") 8a3c76523e449 ("r8169: add support for phylink") https://lore.kernel.org/ar5vAxEqS8tO8aVT@sirena.org.uk Adjacent changes: rust/kernel/net/netlink.rs 5e5916923759 ("rust: net: netlink: Migrate to zerocopy's IntoBytes") 0923198be4ae ("rust: net: netlink: validate attribute length before casting to `c_int`") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-30tcp: preserve timestamps across receive queue collapseJason Xing
When tcp_collapse() rebuilds skbs under memory pressure, the copy process doesn't include the right tstamp and hwtstamp from the old skb. And memcpy(nskb->cb, skb->cb, ...) copies has_rxtstamp, but nskb->tstamp and hwtstamps are left at zero, so tcp_recv_timestamp() ends up emitting no cmsg at all. In net timestamping case, if such an skb happens to be the last one consumed in a recvmsg() call, the application receives no RX timestamp for that call. Fix this by copying both tstamp and hwtstamp of the last skb to the new skb, matching tcp_try_coalesce()/tcp_add_backlog(). Note that the has_rxtstamp flag can still be inherited through the cb memcpy from an skb that contributes no bytes (fully covered skb left in the ofo tree by the tcp_ooo_try_coalesce() -> coalesce_done path), so set TCP_SKB_CB(nskb)->has_rxtstamp to false which makes the new block the only place setting it. Signed-off-by: Jason Xing <kerneljasonxing@gmail.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20260924152529.5689-1-kerneljasonxing@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-30tcp: refresh TS.Recent for accepted old ACKsJeff Jo
A TCP packet can carry new data while acknowledging traffic in the opposite direction. With overlapping traffic in both directions, a delayed packet's acknowledgment can be older than one Linux has already accepted, even when that packet fills a gap in the received data. Linux accepts the data, but tcp_ack() takes the old_ack path and skips updating TS.Recent, the timestamp saved for outgoing acknowledgments. The reply therefore echoes an older timestamp. If the sender uses this echo to measure round-trip time after a long idle period, its estimate includes the idle time and can reduce its sending rate. Update TS.Recent in old_ack using tcp_replace_ts_recent(), before SACK processing can trigger a transmission. This reuses the existing timestamp and sequence checks, including PAWS protection against old duplicate packets. ACK validation already rejects old ACKs in SYN_RECV before this path, so no additional state check is needed. Echoing the timestamp of the packet that fills the receive gap follows RFC 7323 section 4.3. In a socket reproduction with 300 seconds idle, controlled reordering and retransmission to exercise timestamp-based RTT sampling, the sender's smoothed round-trip time was 37.5 seconds without the fix and 15.5 ms with it. Fixes: 12fb3dd9dc3c ("tcp: call tcp_replace_ts_recent() from tcp_ack()") Assisted-by: LLM sparse Signed-off-by: Jeff Jo <jeffjo@openai.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2026-09-24Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 7.3-rc4Alexei Starovoitov
Cross-merge BPF and other fixes after downstream PR. Conflicts: kernel/bpf/helpers.c tools/testing/selftests/bpf/prog_tests/cb_refs.c tools/testing/selftests/bpf/prog_tests/verifier.c Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-22tcp: remove dead code in tcp_rcv_state_process()Eric Dumazet
Since commit 3d501dd326fb ("tcp: do not accept ACK of bytes we never sent"), tcp_ack() bounds the acceptable old ACK window by min(tp->max_window, tp->bytes_acked). When sk->sk_state == TCP_SYN_RECV, tp->bytes_acked is always 0, so any segment with before(ack, prior_snd_una) immediately returns -SKB_DROP_REASON_TCP_TOO_OLD_ACK and never reaches the old_ack label (which returns 0). Therefore, tcp_ack() can only return 0 in closing states (where old ACKs are accepted), and can never return 0 in TCP_SYN_RECV. Simplify the tcp_ack() return value check in tcp_rcv_state_process() to only check for negative return values and remove the unreachable !reason branch. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn> Link: https://patch.msgid.link/20260922010627.2291980-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-19bpf: tcp: Support parse/len/write header option hooks in bpf_tcp_opsAmery Hung
Add the TCP header option callbacks to the bpf_tcp_ops struct_ops type: parse_hdr - parse the options of an incoming skb on an established connection hdr_opt_len - reserve space in the TCP header for bpf options write_hdr_opt - write the reserved bpf options These mirror the BPF_SOCK_OPS_PARSE_HDR_OPT_CB, _HDR_OPT_LEN_CB and _WRITE_HDR_OPT_CB legacy sockops callbacks, but are exposed as struct_ops members so a program can implement them with normal function signatures and per-member helper sets. The reserved header window is shared between the legacy sockops and bpf_tcp_ops paths. tcp_{syn,synack,established}_options() first run the legacy BPF_SOCK_OPS_HDR_OPT_LEN_CB and then call hdr_opt_len, so both sources accumulate into opts->bpf_opt_len; at write time the legacy options are emitted first and bpf_tcp_ops writes after them. API design bpf_tcp_ops overloads the sock_ops header-option helpers rather than introducing a new API: bpf_reserve_hdr_opt(), bpf_store_hdr_opt() and bpf_load_hdr_opt() are exposed per-member (reserve for hdr_opt_len, store/load for write_hdr_opt, load for parse_hdr) and share the existing kernel option-walking core via _bpf_sock_ops{store,load}hdr_opt(), with the bpf_tcp_ops wrappers synthesizing a temporary bpf_sock_ops_kern from the program ctx. This keeps a port from the legacy BPF_SOCK_OPS*_HDR_OPT_CB callbacks mechanical (same helper calls) and adds no new UAPI helper/kfunc surface. An alternative considered was to drop the option helpers entirely: have hdr_opt_len reserve space purely through its return value, and introduce a dedicated TCP-header-option dynptr used for both reading and writing. That is a cleaner, more self-contained interface, but it is a larger change and does not reuse the legacy helpers, making a port from sockops less mechanical. It can be pursued as a follow-up; the helper-based interface here keeps this series focused on moving the hooks to struct_ops. The hdr_opt_len fast path in tcp_established_options() is gated by cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS). Note this is a global, per-attach-type static branch: it is enabled whenever any bpf_tcp_ops is attached, even one that does not implement hdr_opt_len or that is attached to a different cgroup. In those cases the block still runs but bpf_tcp_ops_hdr_opt_len() no-ops via the per-member check in the dispatch macro. A per-member/per-cgroup gate could be added later if the extra fast-path work proves measurable. Signed-off-by: Amery Hung <ameryhung@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://patch.msgid.link/20260917200542.3689605-13-ameryhung@gmail.com
2026-09-19bpf: tcp: Support selected sock_ops callbacks as struct_opsAmery Hung
In LSFMMBPF 2025, I have talked about moving the BPF_PROG_TYPE_SOCK_OPS to a struct_ops interface [1]. The BPF_SOCK_OPS_*_CB enum interface has grown over time as new TCP callback points were added. A BPF_PROG_TYPE_SOCK_OPS program now commonly needs a large switch on sock_ops->op, and the shared bpf_sock_ops_kern context has become harder to extend because different callbacks have different locking, argument, skb, and helper requirements. The existing 'union { u32 args[4]; u32 replylong[4]; }' is also not reliable in passing args to bpf prog when there are multiple progs attached to a cgroup. The above has already been solved in struct_ops. Add a TCP-specific struct_ops type, bpf_tcp_ops, and support attaching it to cgroups. This allows each callback have its own func signature and allows the verifier to select kfuncs/helpers based on the specific struct_ops member being implemented. This patch wires up the following existing sock_ops callbacks: - BPF_SOCK_OPS_TIMEOUT_INIT - BPF_SOCK_OPS_RWND_INIT - BPF_SOCK_OPS_RTT_CB - BPF_SOCK_OPS_STATE_CB - BPF_SOCK_OPS_RETRANS_CB - BPF_SOCK_OPS_TCP_CONNECT_CB - BPF_SOCK_OPS_TCP_LISTEN_CB - BPF_SOCK_OPS_RTO_CB - BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB - BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB BASE_RTT is ignored as it is not particularly useful. NEEDS_ECN should be done in bpf-tcp-cc instead. The tstamp ones should be a separate struct_ops (e.g. "bpf_sock_ops") that can work in both TCP and UDP. timeout_init and rwnd_init could have a request_sock pointer. This patch tries a different API and directly passes the request_sock pointer as an arg. Two other approaches were considered before settling on having bpf_get_retval() read the dispatcher's run_ctx via saved_run_ctx. The first was to inherit the retval in the trampoline itself: add a helper in the four __bpf_prog_enter*() paths that, for struct_ops programs, copies the chained value from the caller's run_ctx (now saved_run_ctx) into the program's own run_ctx. It works but puts a per-enter program-type check on the generic trampoline fast path, taxing all fentry/fexit/lsm callers for a cgroup-struct_ops-only feature. The second was to do that same inherit only for the int-returning members via a gen_prologue that emits a hidden kfunc at the start of timeout_init/rwnd_init; this keeps the cost off the generic path and scoped to bpf_tcp_ops, but needs a kfunc + BTF_ID + prologue-emission machinery. The chosen approach avoids both: it touches neither the trampoline nor the program, since saved_run_ctx already points at the dispatcher's run_ctx that carries the value. [1], page 13: https://drive.google.com/file/d/1wjKZth6T0llLJ_ONPAL_6Q_jbxbAjByp/view?usp=sharing Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Signed-off-by: Amery Hung <ameryhung@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://patch.msgid.link/20260917200542.3689605-12-ameryhung@gmail.com
2026-09-17tcp: exclude old ACKs from tcp fast pathInbal Schussheim
Exclude old ACKs before SND.UNA from the tcp fast path as well as ACKs after SND.NXT. Such ACKs will fall through to the slow path, where tcp_ack() performs the appropriate validation and challenge ACK handling according to RFC5961 and Commit 3d501dd326fb1c7 ("tcp: do not accept ACK of bytes we never sent"). This prevents old ACKs from being accepted or modifying connection state as part of the fast path before appropriate ACK validation is applied. In particular, this prevents payload carried by a segment with an excessively old ACK from advancing RCV.NXT before the ACK is rejected. Fixes: 31770e34e43d ("tcp: Revert "tcp: remove header prediction"") Reported-by: Amit Klein <amit.klein@mail.huji.ac.il> Reported-by: Tamir Shahar <tamir.shahar1@mail.huji.ac.il> Reported-by: Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il> Suggested-by: Eric Dumazet <edumazet@google.com> Cc: stable@vger.kernel.org Signed-off-by: Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260914090408.1435080-2-inbal.lipshtat@mail.huji.ac.il Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-10tcp: fix icsk_ack.ato bitfield overflowJiayuan Chen
On cross-region connections we observed delayed ACKs suddenly turning into immediate ACKs plus a TCP_MAX_QUICKACKS burst, as if the connection had just received its first data segment. Commit 95b9a87c6a6b ("tcp: record last received ipv6 flowlabel") squeezed icsk_ack.ato into 8 bits, sized for TCP_DELACK_MAX. But both writers still bound ato by icsk_rto, which can be well above 255 jiffies, so the bitfield assignment silently wraps mod 256: repeated delack timer misses double ato up to icsk_rto, storing 320 as 64 and 256 as 0, and ato == 0 is the "first data packet" sentinel in tcp_event_data_recv(). Clamp both writers to TCP_DELACK_MAX, which the static_assert already guarantees to fit and tcp_send_delayed_ack() effectively caps ato at anyway. Fixes: 95b9a87c6a6b ("tcp: record last received ipv6 flowlabel") Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Reviewed-by: Neal Cardwell <ncardwell@google.com> Link: https://patch.msgid.link/20260807014437.36687-1-jiayuan.chen@linux.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-03tcp: do not change rcv_ssthresh in tcp_measure_rcv_mss()Nathan Gao
Commit f5da7c45188e ("tcp: adjust rcvq_space after updating scaling ratio") replaced the direct window_clamp update in tcp_measure_rcv_mss() with a call to tcp_set_window_clamp(), a helper that implements the TCP_WINDOW_CLAMP setsockopt. As a side effect, the helper also shrinks rcv_ssthresh via __tcp_adjust_rcv_ssthresh(). As a result, each scaling_ratio decrease detected by tcp_measure_rcv_mss() also cuts rcv_ssthresh. Elsewhere in TCP, rcv_ssthresh is usually cut under memory pressure and grows via tcp_grow_window(). Flows whose segment sizes vary keep scaling_ratio oscillating, which leads to an unstable rcv_ssthresh: a dip of rcv_ssthresh only recovers via tcp_grow_window(), keeping the advertised window at a relatively low level even after the ratio itself has recovered, and can even stall the sender. Observed on a customer's proxy gateway after upgrading from kernel 6.1 to 6.12: in the worst case, rcv_ssthresh was cut in half by a scaling_ratio dip. P99 latency jumped from <10ms on 6.1 to ~100ms on 6.12, and almost returned to the 6.1 level with this patch applied. Restore the plain WRITE_ONCE() update of window_clamp, as introduced in commit a2cbb1603943 ("tcp: Update window clamping condition"), and keep the rcvq_space.space adjustment. Now rcv_ssthresh is decoupled from scaling_ratio changes in tcp_measure_rcv_mss(). Fixes: f5da7c45188e ("tcp: adjust rcvq_space after updating scaling ratio") Signed-off-by: Nathan Gao <zcgao@amazon.com> Link: https://patch.msgid.link/20260725030806.28135-1-zcgao@amazon.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-23tcp: challenge ACK for non-exact RST in SYN-RECEIVEDYuxiang Yang
The SYN-RECEIVED request-socket path in tcp_check_req() accepts an in-window RST without requiring SEG.SEQ to exactly match RCV.NXT. A non-exact RST therefore removes the request instead of eliciting a challenge ACK. RFC 9293 section 3.10.7.4 applies the RFC 5961 reset check in SYN-RECEIVED: an exact RST resets the connection, while a non-exact in-window RST must trigger a challenge ACK and be dropped. Apply that check before the ACK-field validation, following the RFC sequence-number, RST, then ACK processing order. Factor the per-netns challenge ACK quota out of tcp_send_challenge_ack() so request sockets can share it. Use the request socket's send_ack() callback and its own out-of-window ACK timestamp to send and rate-limit the response. Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn> Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn> Reported-by: Ao Wang <wangao@seu.edu.cn> Reported-by: Xuewei Feng <fengxw06@126.com> Reported-by: Qi Li <qli01@tsinghua.edu.cn> Reported-by: Ke Xu <xuke@tsinghua.edu.cn> Fixes: 282f23c6ee34 ("tcp: implement RFC 5961 3.2") Cc: stable@vger.kernel.org Signed-off-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260717081443.809393-2-yangyx22@mails.tsinghua.edu.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-15tcp: rehash onto different local ECMP path on retransmit timeoutNeil Spring
Currently sk_rethink_txhash() re-rolls the socket's txhash on RTO, PLB, and spurious-retransmission events, but the cached route is reused and the new hash is not propagated into the ECMP path selection logic. Two changes are needed to make rehash select a different local ECMP path: 1. Add __sk_dst_reset() alongside sk_rethink_txhash() in tcp_write_timeout(), tcp_rcv_spurious_retrans(), and tcp_plb_check_rehash() so the cached dst is invalidated and the next transmit triggers a fresh route lookup. 2. Set fl6->mp_hash from sk_txhash (or tcp_rsk(req)->txhash for SYN/ACK retransmits and syncookies) in tcp_v6_connect(), inet6_sk_rebuild_header(), inet6_csk_route_req(), inet6_csk_route_socket(), tcp_v6_send_response(), and cookie_v6_check() so fib6_select_path() picks a path based on the new hash. The mp_hash override only applies to fib_multipath_hash_policy 0 (the default L3 policy). Its hash includes the flow label, but that is 0 by default -- np->flow_label is unset, and auto_flowlabels only computes the on-wire label later, per packet -- so flows to the same peer share one local path. Keying the hash on sk_txhash makes the local path per-connection and lets a rehash re-select it. Policies 1-3 are left unchanged. The mp_hash assignment is factored into a small helper, ip6_ecmp_set_mp_hash(), shared by inet6_csk_route_req(), inet6_csk_route_socket(), tcp_v6_connect(), inet6_sk_rebuild_header(), tcp_v6_send_response(), and cookie_v6_check(). It applies (txhash >> 1) ?: 1 for policy 0 (the >> 1 keeps mp_hash in the 31-bit range; ?: 1 keeps it non-zero, since 0 would fall back to rt6_multipath_hash()). inet6_csk_route_socket() calls it only for sk_protocol == IPPROTO_TCP so that non-TCP callers (e.g., L2TP via inet6_csk_xmit) fall through to rt6_multipath_hash() and retain their existing flow-key-based ECMP behavior. tcp_v6_send_response() also sets mp_hash from the response txhash so that a control packet (a RST from the full socket, or an ACK from a time-wait socket) selects the same local ECMP nexthop as the connection's txhash rather than falling back to the flow hash. The time-wait socket's tw_txhash is copied from sk_txhash when the connection enters TIME_WAIT, so it reflects any rehash that occurred. Setting mp_hash explicitly is necessary because the default ECMP hash derives from fl6->flowlabel via np->flow_label, which is not updated from sk_txhash (REPFLOW is off by default). ip6_make_flowlabel() cannot help either, as it runs after the route lookup. As a consequence, for policy 0 the local ECMP path of an IPv6 TCP flow follows sk_txhash even when fl6->flowlabel is non-zero, e.g. a reflected (REPFLOW) or explicitly set (IPV6_FLOWLABEL_MGR) flow label. This is intentional: only local path selection changes, so rehash can recover from a failed path; the on-wire flow label is unchanged. sk_set_txhash() is moved before ip6_dst_lookup_flow() in tcp_v6_connect() so the initial ECMP path is selected by the same txhash that subsequent route rebuilds will use. This avoids unintended path changes when the cached dst is naturally invalidated (e.g., by PMTU discovery or route changes). The rehash sites (tcp_write_timeout(), tcp_plb_check_rehash(), and tcp_rcv_spurious_retrans()) call __sk_rethink_txhash_reset_dst(), which re-rolls the txhash and, when it changed, drops the cached dst so the next transmit re-runs route selection. The dst reset is guarded by sk->sk_family == AF_INET6 since IPv4 ECMP does not currently use sk_txhash for path selection. For IPv4-mapped IPv6 sockets this produces a redundant dst reset on a cold path (RTO/PLB); the subsequent IPv4 route lookup returns the same result. The helper is deliberately separate from sk_rethink_txhash() itself: dst_negative_advice() calls sk_rethink_txhash() before its own dst op, so resetting the dst inside sk_rethink_txhash() would skip that op (e.g. rt6_remove_exception_rt()). For syncookies, cookie_init_sequence() computes the cookie value before route_req() and sets txhash so the SYN-ACK selects the same ECMP path that cookie_v6_check() will use when the full socket is created. cookie_tcp_reqsk_init() derives txhash from the cookie so the full socket's ECMP path matches the SYN-ACK. Both the SYN-ACK assignment in tcp_conn_request() and the full-socket assignment in cookie_tcp_reqsk_init() set txhash from the cookie for IPv4 and IPv6 alike. On IPv6 this drives ECMP path selection; on IPv4, which does not use sk_txhash for ECMP, it only affects TX-queue selection. That selection scales the hash by its high bits (reciprocal_scale()), which are uniform in the keyed secure_tcp_syn_cookie() output -- the MSS index only perturbs the low bits -- so the queue distribution matches net_tx_rndhash(). cookie_init_sequence() is split from the former version that also called tcp_synq_overflow() and incremented SYNCOOKIESSENT; those side effects are now in cookie_record_sent(), called after route_req() succeeds so they are not bumped when route_req() fails. cookie_record_sent() is guarded by CONFIG_SYN_COOKIES to match the guard on tcp_synq_overflow(). route_req() receives 0 as tw_isn for the syncookie path so that tcp_v6_init_req() still saves ireq->pktopts for REPFLOW flowlabel reflection and IPv6 cmsg options. The ecn_ok clear for syncookies without timestamps stays after tcp_ecn_create_request() so it takes precedence. Signed-off-by: Neil Spring <ntspring@meta.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260615042158.1600746-2-ntspring@meta.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-13tcp: refine tcp_sequence() for the FIN exceptionEric Dumazet
Commit 0e24d17bd966 ("tcp: implement RFC 7323 window retraction receiver requirements") removed the special FIN case that was added in commit 1e3bb184e941 ("tcp: re-enable acceptance of FIN packets when RWIN is 0"). If a peer sends a segment containing data and a FIN flag before it learns about our window retraction and has a buggy TCP stack, it might place the FIN one byte beyond what it thinks is the right edge of the window (i.e., max_window_edge + 1). The data portion (end_seq - th->fin) will end exactly at max_window_edge. In this case, we will drop the packet if our receive queue is not empty, even though the data was sent within the window we previously allowed. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Neal Cardwell <ncardwell@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Simon Baatz <gmbnomis@gmail.com> Link: https://patch.msgid.link/20260608151452.706822-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-21Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.1-rc5). No conflicts, adjacent changes: drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c cc199cd1b912 ("net/mlx5e: Reduce branches in napi poll") c326f9c68921 ("net/mlx5e: xsk: Fix unlocked writing to ICOSQ") drivers/net/ethernet/mellanox/mlx5/core/eswitch.c c6df9a65cbb0 ("net/mlx5: Skip disabled vports when setting max TX speed") 1fba57c91416 ("net/mlx5: Add VHCA_ID page management mode support") net/mac80211/mlme.c a6e6ccd5bd07 ("wifi: mac80211: consume only present negotiated TTLM maps") 49e62ec6eb06 ("wifi: mac80211: move frame RX handling to type files") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-20tcp: fix stale per-CPU tcp_tw_isn leak enabling ISN predictionEric Dumazet
Blamed commit moved the TIME_WAIT-derived ISN from the skb control block to a per-CPU variable, assuming the value would always be consumed by tcp_conn_request() for the same packet that wrote it. That assumption is violated by multiple drop paths between the producer (__this_cpu_write(tcp_tw_isn, isn) in tcp_v{4,6}_rcv()) and the consumer (tcp_conn_request()): - min_ttl / min_hopcount check - xfrm policy check - tcp_inbound_hash() MD5/AO mismatch - tcp_filter() eBPF/SO_ATTACH_FILTER drop - th->syn && th->fin discard in tcp_rcv_state_process() TCP_LISTEN - psp_sk_rx_policy_check() in tcp_v{4,6}_do_rcv() - tcp_checksum_complete() in tcp_v{4,6}_do_rcv() - tcp_v{4,6}_cookie_check() returning NULL When a packet is dropped on any of these paths, tcp_tw_isn is left set. The next SYN processed on the same CPU then consumes the non zero value in tcp_conn_request(), receiving a potentially predictable ISN. This patch moves back tcp_tw_isn to skb->cb[], getting rid of the per-cpu variable. Note that tcp_v{4,6}_fill_cb() do not set it. Very litle impact on overall code size/complexity: $ scripts/bloat-o-meter -t vmlinux.old vmlinux.new add/remove: 0/0 grow/shrink: 2/1 up/down: 8/-15 (-7) Function old new delta tcp_v6_rcv 3038 3042 +4 tcp_v4_rcv 3035 3039 +4 tcp_conn_request 2938 2923 -15 Total: Before=24436060, After=24436053, chg -0.00% Fixes: 41eecbd712b7 ("tcp: replace TCP_SKB_CB(skb)->tcp_tw_isn with a per-cpu field") Reported-by: Chris Mason <clm@meta.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260519084611.2485277-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-29tcp: add tcp_mstamp_refresh_inline()Eric Dumazet
We want to inline tcp_mstamp_refresh() in fast path only: - tcp_rcv_established() - tcp_write_xmit() Add tcp_mstamp_refresh_inline() for this purpose. Add noinline qualifier on tcp_mstamp_refresh() for the other paths, to reduce bloat. $ scripts/bloat-o-meter -t vmlinux.old vmlinux.new add/remove: 0/0 grow/shrink: 1/4 up/down: 26/-123 (-97) Function old new delta tcp_rcv_established 2238 2264 +26 tcp_connect 4027 4003 -24 tcp_tsq_write 152 120 -32 tcp_send_active_reset 476 444 -32 tcp_send_window_probe 235 200 -35 Total: Before=25316710, After=25316613, chg -0.00% Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Neal Cardwell <ncardwell@google.com> Link: https://patch.msgid.link/20260429010809.784315-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-23tcp: send a challenge ACK on SEG.ACK > SND.NXTJiayuan Chen
RFC 5961 Section 5.2 validates an incoming segment's ACK value against the range [SND.UNA - MAX.SND.WND, SND.NXT] and states: "All incoming segments whose ACK value doesn't satisfy the above condition MUST be discarded and an ACK sent back." Commit 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation") opted Linux into this mitigation and implements the challenge ACK on the lower side (SEG.ACK < SND.UNA - MAX.SND.WND), but the symmetric upper side (SEG.ACK > SND.NXT) still takes the pre-RFC-5961 path and silently returns SKB_DROP_REASON_TCP_ACK_UNSENT_DATA, even though RFC 793 Section 3.9 (now RFC 9293 Section 3.10.7.4) has always required: "If the ACK acknowledges something not yet sent (SEG.ACK > SND.NXT) then send an ACK, drop the segment, and return." Complete the mitigation by sending a challenge ACK on that branch, reusing the existing tcp_send_challenge_ack() path which already enforces the per-socket RFC 5961 Section 7 rate limit via __tcp_oow_rate_limited(). FLAG_NO_CHALLENGE_ACK is honoured for symmetry with the lower-edge case. Update the existing tcp_ts_recent_invalid_ack.pkt selftest, which drives this exact path, to consume the new challenge ACK. Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation") Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260422123605.320000-2-jiayuan.chen@linux.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-18tcp: annotate data-races around tp->srtt_usEric Dumazet
tcp_get_timestamping_opt_stats() intentionally runs lockless, we must add READ_ONCE() and WRITE_ONCE() annotations to keep KCSAN happy. Fixes: e8bd8fca6773 ("tcp: add SRTT to SCM_TIMESTAMPING_OPT_STATS") Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260416200319.3608680-12-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-18tcp: annotate data-races around tp->reord_seenEric Dumazet
tcp_get_timestamping_opt_stats() intentionally runs lockless, we must add READ_ONCE() and WRITE_ONCE() annotations to keep KCSAN happy. Fixes: 7ec65372ca53 ("tcp: add stat of data packet reordering events") Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260416200319.3608680-11-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-18tcp: annotate data-races around tp->dsack_dupsEric Dumazet
tcp_get_timestamping_opt_stats() intentionally runs lockless, we must add READ_ONCE() and WRITE_ONCE() annotations to keep KCSAN happy. Fixes: 7e10b6554ff2 ("tcp: add dsack blocks received stats") Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260416200319.3608680-10-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-18tcp: add data-race annotations for TCP_NLA_SNDQ_SIZEEric Dumazet
tcp_get_timestamping_opt_stats() intentionally runs lockless, we must add READ_ONCE() and WRITE_ONCE() annotations to keep KCSAN happy. Fixes: 87ecc95d81d9 ("tcp: add send queue size stat in SCM_TIMESTAMPING_OPT_STATS") Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260416200319.3608680-7-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-18tcp: annotate data-races around tp->delivered and tp->delivered_ceEric Dumazet
tcp_get_timestamping_opt_stats() intentionally runs lockless, we must add READ_ONCE() and WRITE_ONCE() annotations to keep KCSAN happy. Fixes: feb5f2ec6464 ("tcp: export packets delivery info") Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260416200319.3608680-6-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-18tcp: annotate data-races around tp->snd_ssthreshEric Dumazet
tcp_get_timestamping_opt_stats() intentionally runs lockless, we must add READ_ONCE() and WRITE_ONCE() annotations to keep KCSAN happy. Fixes: 7156d194a077 ("tcp: add snd_ssthresh stat in SCM_TIMESTAMPING_OPT_STATS") Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260416200319.3608680-5-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-18tcp: add data-races annotations around tp->reordering, tp->snd_cwndEric Dumazet
tcp_get_timestamping_opt_stats() intentionally runs lockless, we must add READ_ONCE(), WRITE_ONCE() data_race() annotations to keep KCSAN happy. Fixes: bb7c19f96012 ("tcp: add related fields into SCM_TIMESTAMPING_OPT_STATS") Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260416200319.3608680-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-12tcp: add indirect call wrapper in tcp_conn_request()Eric Dumazet
Small improvement in SYN processing, to directly call tcp_v6_init_seq_and_ts_off() or tcp_v4_init_seq_and_ts_off(). Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260410174950.745670-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-29net: remove EXPORT_IPV6_MOD() and EXPORT_IPV6_MOD_GPL() macrosFernando Fernandez Mancera
As IPv6 is built-in only, the macro is always evaluating to an empty one. Remove it completely from the code. Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Link: https://patch.msgid.link/20260325120928.15848-3-fmancera@suse.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-14tcp: increase LINUX_MIB_BEYOND_WINDOW for SKB_DROP_REASON_TCP_OVERWINDOWSimon Baatz
Since commit 9ca48d616ed7 ("tcp: do not accept packets beyond window"), the path leading to SKB_DROP_REASON_TCP_OVERWINDOW in tcp_data_queue() is probably dead. However, it can be reached now when tcp_max_receive_window() is larger than tcp_receive_window(). In that case, increment LINUX_MIB_BEYOND_WINDOW as done in tcp_sequence(). Signed-off-by: Simon Baatz <gmbnomis@gmail.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260309-tcp_rfc7323_retract_wnd_rfc-v3-3-4c7f96b1ec69@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-14tcp: implement RFC 7323 window retraction receiver requirementsSimon Baatz
By default, the Linux TCP implementation does not shrink the advertised window (RFC 7323 calls this "window retraction") with the following exceptions: - When an incoming segment cannot be added due to the receive buffer running out of memory. Since commit 8c670bdfa58e ("tcp: correct handling of extreme memory squeeze") a zero window will be advertised in this case. It turns out that reaching the required memory pressure is easy when window scaling is in use. In the simplest case, sending a sufficient number of segments smaller than the scale factor to a receiver that does not read data is enough. - Commit b650d953cd39 ("tcp: enforce receive buffer memory limits by allowing the tcp window to shrink") addressed the "eating memory" problem by introducing a sysctl knob that allows shrinking the window before running out of memory. However, RFC 7323 does not only state that shrinking the window is necessary in some cases, it also formulates requirements for TCP implementations when doing so (Section 2.4). This commit addresses the receiver-side requirements: After retracting the window, the peer may have a snd_nxt that lies within a previously advertised window but is now beyond the retracted window. This means that all incoming segments (including pure ACKs) will be rejected until the application happens to read enough data to let the peer's snd_nxt be in window again (which may be never). To comply with RFC 7323, the receiver MUST honor any segment that would have been in window for any ACK sent by the receiver and, when window scaling is in effect, SHOULD track the maximum window sequence number it has advertised. This patch tracks that maximum window sequence number rcv_mwnd_seq throughout the connection and uses it in tcp_sequence() when deciding whether a segment is acceptable. rcv_mwnd_seq is updated together with rcv_wup and rcv_wnd in tcp_select_window(). If we count tcp_sequence() as fast path, it is read in the fast path. Therefore, rcv_mwnd_seq is put into rcv_wnd's cacheline group. The logic for handling received data in tcp_data_queue() is already sufficient and does not need to be updated. Signed-off-by: Simon Baatz <gmbnomis@gmail.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260309-tcp_rfc7323_retract_wnd_rfc-v3-1-4c7f96b1ec69@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-05Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.0-rc3). No conflicts. Adjacent changes: net/netfilter/nft_set_rbtree.c fb7fb4016300 ("netfilter: nf_tables: clone set on flush only") 3aea466a4399 ("netfilter: nft_set_rbtree: don't disable bh when acquiring tree lock") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-04tcp: move tcp_do_parse_auth_options() to net/ipv4/tcp.cEric Dumazet
tcp_do_parse_auth_options() fast path user is tcp_inbound_hash(). Move tcp_do_parse_auth_options() right before tcp_inbound_hash() so that it can be (auto)inlined by the compiler. As a bonus, stack canary is removed from tcp_inbound_hash(). Also use EXPORT_IPV6_MOD(tcp_do_parse_auth_options). $ scripts/bloat-o-meter -t vmlinux.0 vmlinux add/remove: 0/0 grow/shrink: 1/0 up/down: 131/0 (131) Function old new delta tcp_inbound_hash 565 696 +131 Total: Before=25223788, After=25223919, chg +0.00% Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260303191243.557245-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-04tcp: secure_seq: add back ports to TS offsetEric Dumazet
This reverts 28ee1b746f49 ("secure_seq: downgrade to per-host timestamp offsets") tcp_tw_recycle went away in 2017. Zhouyan Deng reported off-path TCP source port leakage via SYN cookie side-channel that can be fixed in multiple ways. One of them is to bring back TCP ports in TS offset randomization. As a bonus, we perform a single siphash() computation to provide both an ISN and a TS offset. Fixes: 28ee1b746f49 ("secure_seq: downgrade to per-host timestamp offsets") Reported-by: Zhouyan Deng <dengzhouyan_nwpu@163.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Acked-by: Florian Westphal <fw@strlen.de> Link: https://patch.msgid.link/20260302205527.1982836-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-28tcp: give up on stronger sk_rcvbuf checks (for now)Jakub Kicinski
We hit another corner case which leads to TcpExtTCPRcvQDrop Connections which send RPCs in the 20-80kB range over loopback experience spurious drops. The exact conditions for most of the drops I investigated are that: - socket exchanged >1MB of data so its not completely fresh - rcvbuf is around 128kB (default, hasn't grown) - there is ~60kB of data in rcvq - skb > 64kB arrives The sum of skb->len (!) of both of the skbs (the one already in rcvq and the arriving one) is larger than rwnd. My suspicion is that this happens because __tcp_select_window() rounds the rwnd up to (1 << wscale) if less than half of the rwnd has been consumed. Eric suggests that given the number of Fixes we already have pointing to 1d2fbaad7cd8 it's probably time to give up on it, until a bigger revamp of rmem management. Also while we could risk tweaking the rwnd math, there are other drops on workloads I investigated, after the commit in question, not explained by this phenomenon. Suggested-by: Eric Dumazet <edumazet@google.com> Link: https://lore.kernel.org/20260225122355.585fd57b@kernel.org Fixes: 1d2fbaad7cd8 ("tcp: stronger sk_rcvbuf checks") Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260227003359.2391017-1-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-26net: annotate data-races around sk->sk_{data_ready,write_space}Eric Dumazet
skmsg (and probably other layers) are changing these pointers while other cpus might read them concurrently. Add corresponding READ_ONCE()/WRITE_ONCE() annotations for UDP, TCP and AF_UNIX. Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") Reported-by: syzbot+87f770387a9e5dc6b79b@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/699ee9fc.050a0220.1cd54b.0009.GAE@google.com/ Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: John Fastabend <john.fastabend@gmail.com> Cc: Jakub Sitnicki <jakub@cloudflare.com> Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260225131547.1085509-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-26Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.0-rc2). Conflicts: tools/testing/selftests/drivers/net/hw/rss_ctx.py 19c3a2a81d2b ("selftests: drv-net: rss: Generate unique ports for RSS context tests") ce5a0f4612db ("selftests: drv-net: rss_ctx: test RSS contexts persist after ifdown/up") include/net/inet_connection_sock.h 858d2a4f67ff6 ("tcp: fix potential race in tcp_v6_syn_recv_sock()") fcd3d039fab69 ("tcp: make tcp_v{4,6}_send_check() static") https://lore.kernel.org/aZ8PSFLzBrEU3I89@sirena.org.uk drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c 69050f8d6d075 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types") bf4afc53b77ae ("Convert 'alloc_obj' family to use the new default GFP_KERNEL argument") 8a96b9144f18a ("net/mlx5e: Alloc xsk channel param out of mlx5e_open_xsk()") Adjacent changes: net/netfilter/ipvs/ip_vs_ctl.c c59bd9e62e06 ("ipvs: use more counters to avoid service lookups") bf4afc53b77a ("Convert 'alloc_obj' family to use the new default GFP_KERNEL argument") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-26Merge tag 'net-7.0-rc2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Including fixes from IPsec, Bluetooth and netfilter Current release - regressions: - wifi: fix dev_alloc_name() return value check - rds: fix recursive lock in rds_tcp_conn_slots_available Current release - new code bugs: - vsock: lock down child_ns_mode as write-once Previous releases - regressions: - core: - do not pass flow_id to set_rps_cpu() - consume xmit errors of GSO frames - netconsole: avoid OOB reads, msg is not nul-terminated - netfilter: h323: fix OOB read in decode_choice() - tcp: re-enable acceptance of FIN packets when RWIN is 0 - udplite: fix null-ptr-deref in __udp_enqueue_schedule_skb(). - wifi: brcmfmac: fix potential kernel oops when probe fails - phy: register phy led_triggers during probe to avoid AB-BA deadlock - eth: - bnxt_en: fix deleting of Ntuple filters - wan: farsync: fix use-after-free bugs caused by unfinished tasklets - xscale: check for PTP support properly Previous releases - always broken: - tcp: fix potential race in tcp_v6_syn_recv_sock() - kcm: fix zero-frag skb in frag_list on partial sendmsg error - xfrm: - fix race condition in espintcp_close() - always flush state and policy upon NETDEV_UNREGISTER event - bluetooth: - purge error queues in socket destructors - fix response to L2CAP_ECRED_CONN_REQ - eth: - mlx5: - fix circular locking dependency in dump - fix "scheduling while atomic" in IPsec MAC address query - gve: fix incorrect buffer cleanup for QPL - team: avoid NETDEV_CHANGEMTU event when unregistering slave - usb: validate USB endpoints" * tag 'net-7.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (72 commits) netfilter: nf_conntrack_h323: fix OOB read in decode_choice() dpaa2-switch: validate num_ifs to prevent out-of-bounds write net: consume xmit errors of GSO frames vsock: document write-once behavior of the child_ns_mode sysctl vsock: lock down child_ns_mode as write-once selftests/vsock: change tests to respect write-once child ns mode net/mlx5e: Fix "scheduling while atomic" in IPsec MAC address query net/mlx5: Fix missing devlink lock in SRIOV enable error path net/mlx5: E-switch, Clear legacy flag when moving to switchdev net/mlx5: LAG, disable MPESW in lag_disable_change() net/mlx5: DR, Fix circular locking dependency in dump selftests: team: Add a reference count leak test team: avoid NETDEV_CHANGEMTU event when unregistering slave net: mana: Fix double destroy_workqueue on service rescan PCI path MAINTAINERS: Update maintainer entry for QUALCOMM ETHQOS ETHERNET DRIVER dpll: zl3073x: Remove redundant cleanup in devm_dpll_init() selftests/net: packetdrill: Verify acceptance of FIN packets when RWIN is 0 tcp: re-enable acceptance of FIN packets when RWIN is 0 vsock: Use container_of() to get net namespace in sysctl handlers net: usb: kaweth: validate USB endpoints ...
2026-02-25tcp: re-enable acceptance of FIN packets when RWIN is 0Simon Baatz
Commit 2bd99aef1b19 ("tcp: accept bare FIN packets under memory pressure") allowed accepting FIN packets in tcp_data_queue() even when the receive window was closed, to prevent ACK/FIN loops with broken clients. Such a FIN packet is in sequence, but because the FIN consumes a sequence number, it extends beyond the window. Before commit 9ca48d616ed7 ("tcp: do not accept packets beyond window"), tcp_sequence() only required the seq to be within the window. After that change, the entire packet (including the FIN) must fit within the window. As a result, such FIN packets are now dropped and the handling path is no longer reached. Be more lenient by not counting the sequence number consumed by the FIN when calling tcp_sequence(), restoring the previous behavior for cases where only the FIN extends beyond the window. Fixes: 9ca48d616ed7 ("tcp: do not accept packets beyond window") Signed-off-by: Simon Baatz <gmbnomis@gmail.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260224-fix_zero_wnd_fin-v2-1-a16677ea7cea@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-24tcp: reduce calls to tcp_schedule_loss_probe()Eric Dumazet
For RPC workloads, we alternate tcp_schedule_loss_probe() calls from output path and from input path, with tp->packets_out value oscillating between !zero and zero, leading to poor branch prediction. Move tp->packets_out check from tcp_schedule_loss_probe() to tcp_set_xmit_timer(). We avoid one call to tcp_schedule_loss_probe() from tcp_ack() path for typical RPC workloads, while improving branch prediction. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Neal Cardwell <ncardwell@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260223113501.4070245-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-21treewide: Replace kmalloc with kmalloc_obj for non-scalar typesKees Cook
This is the result of running the Coccinelle script from scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to avoid scalar types (which need careful case-by-case checking), and instead replace kmalloc-family calls that allocate struct or union object instances: Single allocations: kmalloc(sizeof(TYPE), ...) are replaced with: kmalloc_obj(TYPE, ...) Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...) are replaced with: kmalloc_objs(TYPE, COUNT, ...) Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...) are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...) (where TYPE may also be *VAR) The resulting allocations no longer return "void *", instead returning "TYPE *". Signed-off-by: Kees Cook <kees@kernel.org>
2026-02-04tcp: split tcp_check_space() in two partsEric Dumazet
tcp_check_space() is fat and not inlined. Move its slow path in (out of line) __tcp_check_space() and make tcp_check_space() an inline function for better TCP performance. $ scripts/bloat-o-meter -t vmlinux.old vmlinux.new add/remove: 2/2 grow/shrink: 4/0 up/down: 708/-582 (126) Function old new delta __tcp_check_space - 521 +521 tcp_rcv_established 1860 1916 +56 tcp_rcv_state_process 3342 3384 +42 tcp_event_new_data_sent 248 286 +38 tcp_data_snd_check 71 106 +35 __pfx___tcp_check_space - 16 +16 __pfx_tcp_check_space 16 - -16 tcp_check_space 566 - -566 Total: Before=24896373, After=24896499, chg +0.00% Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260203050932.3522221-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-04tcp: move tcp_rbtree_insert() to tcp_output.cEric Dumazet
tcp_rbtree_insert() is primarily used from tcp_output.c In tcp_input.c, only (slow path) tcp_collapse() uses it. Move it to tcp_output.c to allow its (auto)inlining to improve TCP tx fast path. $ scripts/bloat-o-meter -t vmlinux.old vmlinux.new add/remove: 0/0 grow/shrink: 4/1 up/down: 445/-115 (330) Function old new delta tcp_connect 4277 4478 +201 tcp_event_new_data_sent 162 248 +86 tcp_send_synack 780 862 +82 tcp_fragment 1185 1261 +76 tcp_collapse 1524 1409 -115 Total: Before=24896043, After=24896373, chg +0.00% Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260203045110.3499713-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-03tcp: accecn: detect loss ACK w/ AccECN option and add TCP_ACCECN_OPTION_PERSISTChia-Yu Chang
Detect spurious retransmission of a previously sent ACK carrying the AccECN option after the second retransmission. Since this might be caused by the middlebox dropping ACK with options it does not recognize, disable the sending of the AccECN option in all subsequent ACKs. This patch follows Section 3.2.3.2.2 of AccECN spec (RFC9768), and a new field (accecn_opt_sent_w_dsack) is added to indicate that an AccECN option was sent with duplicate SACK info. Also, a new AccECN option sending mode is added to tcp_ecn_option sysctl: (TCP_ECN_OPTION_PERSIST), which ignores the AccECN fallback policy and persistently sends AccECN option once it fits into TCP option space. Signed-off-by: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com> Acked-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260131222515.8485-13-chia-yu.chang@nokia-bell-labs.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-02-03tcp: accecn: unset ECT if receive or send ACE=0 in AccECN negotiaionChia-Yu Chang
Based on specification: https://tools.ietf.org/id/draft-ietf-tcpm-accurate-ecn-28.txt Based on Section 3.1.5 of AccECN spec (RFC9768), a TCP Server in AccECN mode MUST NOT set ECT on any packet for the rest of the connection, if it has received or sent at least one valid SYN or Acceptable SYN/ACK with (AE,CWR,ECE) = (0,0,0) during the handshake. In addition, a host in AccECN mode that is feeding back the IP-ECN field on a SYN or SYN/ACK MUST feed back the IP-ECN field on the latest valid SYN or acceptable SYN/ACK to arrive. Signed-off-by: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260131222515.8485-11-chia-yu.chang@nokia-bell-labs.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-02-03tcp: disable RFC3168 fallback identifier for CC modulesChia-Yu Chang
When AccECN is not successfully negociated for a TCP flow, it defaults fallback to classic ECN (RFC3168). However, L4S service will fallback to non-ECN. This patch enables congestion control module to control whether it should not fallback to classic ECN after unsuccessful AccECN negotiation. A new CA module flag (TCP_CONG_NO_FALLBACK_RFC3168) identifies this behavior expected by the CA. Signed-off-by: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com> Acked-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260131222515.8485-6-chia-yu.chang@nokia-bell-labs.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-02-03tcp: ECT_1_NEGOTIATION and NEEDS_ACCECN identifiersChia-Yu Chang
Two flags for congestion control (CC) module are added in this patch related to AccECN negotiation. First, a new flag (TCP_CONG_NEEDS_ACCECN) defines that the CC expects to negotiate AccECN functionality using the ECE, CWR and AE flags in the TCP header. Second, during ECN negotiation, ECT(0) in the IP header is used. This patch enables CC to control whether ECT(0) or ECT(1) should be used on a per-segment basis. A new flag (TCP_CONG_ECT_1_NEGOTIATION) defines the expected ECT value in the IP header by the CA when not-yet initialized for the connection. The detailed AccECN negotiaotn can be found in IETF RFC9768. Co-developed-by: Olivier Tilmans <olivier.tilmans@nokia.com> Signed-off-by: Olivier Tilmans <olivier.tilmans@nokia.com> Signed-off-by: Ilpo Järvinen <ij@kernel.org> Signed-off-by: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com> Acked-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260131222515.8485-5-chia-yu.chang@nokia-bell-labs.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>