diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-06 11:39:20 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-06 11:39:20 -0700 |
| commit | 315f4bd234b3b8a3ed3a71fd4c53b110cf373720 (patch) | |
| tree | 43ce3f7794857c088e0173ed25fd4c247d97e143 /include | |
| parent | fcaeecb8b0cd44f77d03b28de0671258d4db18f8 (diff) | |
| parent | b0ce5fd9fabe7c79463cf4602217d4dfeff5b1fd (diff) | |
Merge tag 'net-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski:
"Including fixes from netfilter.
Looks like our attempt to keep the PRs smaller have only prevented
this one from getting even bigger. In the last 9 days there were
405 postings explicitly tagged with [PATCH net], vs 687 with [PATCH
net-next]. 37% of posted patches being fixes is pretty crazy, and
that's likely undercounting because LLM "researchers" more often post
fixes without knowing to tag the patches for specific trees. I don't
have historic data.
In any case, we keep adjusting the criteria. The next PR will be
smaller.
Current release - regressions:
- net: defer netdev KOBJ_ADD uevent until the device is published,
previously rtnl_lock would serialize the accesses vs publishing
- net: explicitly cancel work to avoid races with ref tracker exit
- qrtr: ns: raise lookup limit to 128
- eth: hns3: fix speed configuration residue after driver reload
Previous releases - regressions:
- tcp: do not change rcv_ssthresh in tcp_measure_rcv_mss(), regressed
flows with MSS and scaling_ratio variability
- Revert "net: thunderbolt: Enable end-to-end flow control also in
transmit", broke some platforms (no packets coming thru)
- eth: stmmac: resume PHY before hardware setup when opening the
interface
Previous releases - always broken:
- another pile of fixes for less common protocols (SCTP, TLS, SMC
etc.)
- close a couple of AF_PACKET bugs and ways it can build skbs
problematic for the rest of the stack
- bridge: mrp: fix uninitialised bytes on the wire
- net: devmem: prevent net-iov / page mixing, avoid crashes
- eth: atlantic: free RX pages of consumed but not refilled buffers"
* tag 'net-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (116 commits)
igc: fix netdev not re-attached after resume if interface is down
tls: don't abort the connection on signal-interrupted sends
net: avoid theoretical races with ref drain
net: Defer netdev KOBJ_ADD uevent until the device is published
MAINTAINERS: dpll: zl3073x: replace Prathosh Satish with Min Li
sctp: clear control chunk transport if it is being removed
net/atm: fix slab-out-of-bounds read in vcc_setsockopt()
s390/ism: Fix UAF of sba and ieq during ism_dev_exit()
packet: use consistent hard_header_len in TX_RING send path
packet: use consistent hard_header_len in non-ring send paths
net: remove CAP_SYS_RAWIO zero-padding in dev_validate_header
bnge: Fix resource leak in bnge_init_nic() error path
ptp: ocp: Fix board ID over-read
tls: rx: restore msg_iter before TLS 1.3 optimistic retry
selftests: tls: add a test for splicing onto a full plaintext record
tls: don't leave a full plaintext sk_msg ring unpushed
xdp: reject clones that overrun skb_shared_info tailroom
mptcp: reclaim forward-allocated memory on RX path errors
mptcp: fastopen: only mark MPTFO subflows with SYN data
mptcp: pm: fix memory leak from alloc-during-teardown race
...
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/dibs.h | 2 | ||||
| -rw-r--r-- | include/linux/netdevice.h | 11 | ||||
| -rw-r--r-- | include/linux/netfilter/ipset/ip_set.h | 6 | ||||
| -rw-r--r-- | include/net/addrconf.h | 4 | ||||
| -rw-r--r-- | include/net/ip_vs.h | 21 | ||||
| -rw-r--r-- | include/net/libeth/xsk.h | 2 | ||||
| -rw-r--r-- | include/net/sch_generic.h | 1 | ||||
| -rw-r--r-- | include/net/xdp_sock.h | 45 | ||||
| -rw-r--r-- | include/net/xdp_sock_drv.h | 77 |
9 files changed, 89 insertions, 80 deletions
diff --git a/include/linux/dibs.h b/include/linux/dibs.h index c75607f8a5cf..d3e0777f25ae 100644 --- a/include/linux/dibs.h +++ b/include/linux/dibs.h @@ -439,7 +439,7 @@ static inline void *dibs_get_priv(struct dibs_dev *dev, /** * dibs_dev_alloc() - allocate and reference device structure * - * The following fields will be valid upon successful return: dev + * The following fields will be valid upon successful return: dev, lock * NOTE: Use put_device(dibs_get_dev(@dibs)) to give up your reference instead * of freeing @dibs @dev directly once you have successfully called this * function. diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9981d637f8b5..8840b126979f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -300,9 +300,11 @@ struct hh_cache { * We could use other alignment values, but we must maintain the * relationship HH alignment <= LL alignment. */ -#define LL_RESERVED_SPACE(dev) \ - ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom)) \ +#define LL_RESERVED_SPACE_EX(dev, hlen) \ + ((((hlen) + READ_ONCE((dev)->needed_headroom)) \ & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD) +#define LL_RESERVED_SPACE(dev) \ + LL_RESERVED_SPACE_EX(dev, (dev)->hard_header_len) #define LL_RESERVED_SPACE_EXTRA(dev,extra) \ ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom) + (extra)) \ & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD) @@ -3531,11 +3533,6 @@ static inline bool dev_validate_header(const struct net_device *dev, if (len < dev->min_header_len) return false; - if (capable(CAP_SYS_RAWIO)) { - memset(ll_header + len, 0, dev->hard_header_len - len); - return true; - } - if (dev->header_ops && dev->header_ops->validate) return dev->header_ops->validate(ll_header, len); diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index b98331572ad2..c46864cc6623 100644 --- a/include/linux/netfilter/ipset/ip_set.h +++ b/include/linux/netfilter/ipset/ip_set.h @@ -244,8 +244,8 @@ extern void ip_set_type_unregister(struct ip_set_type *set_type); /* A generic IP set */ struct ip_set { - /* For call_cru in destroy */ - struct rcu_head rcu; + /* for set destruction */ + struct rcu_work rwork; /* The name of the set */ char name[IPSET_MAXNAMELEN]; /* Lock protecting the set data */ @@ -273,7 +273,7 @@ struct ip_set { /* Number of elements (vs timeout) */ u32 elements; /* Size of the dynamic extensions (vs timeout) */ - size_t ext_size; + atomic64_t ext_size; /* Element data size */ size_t dsize; /* Offsets to extensions in elements */ diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 8ced27a8229b..e6764245995f 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -405,8 +405,8 @@ static inline struct inet6_dev *in6_dev_get(const struct net_device *dev) rcu_read_lock(); idev = rcu_dereference(dev->ip6_ptr); - if (idev) - refcount_inc(&idev->refcnt); + if (idev && !refcount_inc_not_zero(&idev->refcnt)) + idev = NULL; rcu_read_unlock(); return idev; } diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index e6ca930a3507..d2813eb795be 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -25,9 +25,7 @@ #include <linux/netfilter.h> /* for union nf_inet_addr */ #include <linux/ip.h> #include <linux/ipv6.h> /* for struct ipv6hdr */ -#include <net/route.h> #include <net/ipv6.h> -#include <net/ip6_fib.h> #if IS_ENABLED(CONFIG_NF_CONNTRACK) #include <net/netfilter/nf_conntrack.h> #endif @@ -2062,7 +2060,7 @@ static inline bool ip_vs_conn_use_hash2(struct ip_vs_conn *cp) void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, struct ip_vs_conn *cp, int dir, unsigned int toff, - bool has_ports); + bool has_ports, struct ip_vs_iphdr *ciph); #ifdef CONFIG_IP_VS_IPV6 void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp, @@ -2095,30 +2093,23 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) return csum_partial(diff, sizeof(diff), oldsum); } -static inline bool ip_vs_checksum_needed(struct sk_buff *skb, int af) +static inline bool ip_vs_checksum_needed(struct sk_buff *skb) { /* Checksum unnecessary or already validated? */ if (skb_csum_unnecessary(skb)) return false; - /* LOCAL_OUT ? */ - if (!skb->dev || skb->dev->flags & IFF_LOOPBACK) + /* Locally generated ? */ + if (!skb->dev) return false; - /* !LOCAL_IN (FORWARD) ? */ - if (af == AF_INET6) { - if (!(dst_rt6_info(skb_dst(skb))->rt6i_flags & RTF_LOCAL)) - return false; - } else { - if (!(skb_rtable(skb)->rt_flags & RTCF_LOCAL)) - return false; - } return true; } static inline bool ip_vs_checksum_common_check(struct sk_buff *skb, int offset, int proto, int af) { - if (!ip_vs_checksum_needed(skb, af)) + if (!ip_vs_checksum_needed(skb)) return true; + /* Validate csum even for FORWARD */ return !nf_checksum(skb, NF_INET_LOCAL_IN, offset, proto, af); } diff --git a/include/net/libeth/xsk.h b/include/net/libeth/xsk.h index 82b5d21aae87..5dcc0d7f65b7 100644 --- a/include/net/libeth/xsk.h +++ b/include/net/libeth/xsk.h @@ -205,7 +205,7 @@ __libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc, BUILD_BUG_ON(!__builtin_constant_p(tmo == libeth_xsktmo)); tmo = tmo == libeth_xsktmo ? &__libeth_xsktmo : tmo; - xsk_tx_metadata_request(ctx.meta, tmo, &desc); + xsk_tx_metadata_request(sq->pool, &ctx.meta, tmo, &desc); return desc; } diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 45a1e8c78222..cbc248776511 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -99,6 +99,7 @@ struct Qdisc { struct hlist_node hash; u32 handle; u32 parent; + int depth; struct netdev_queue *dev_queue; diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h index 8b51876efbed..6e70b320b399 100644 --- a/include/net/xdp_sock.h +++ b/include/net/xdp_sock.h @@ -141,45 +141,16 @@ INDIRECT_CALLABLE_DECLARE(void xsk_destruct_skb(struct sk_buff *)); static inline void xsk_tx_metadata_to_compl(struct xsk_tx_metadata *meta, struct xsk_tx_metadata_compl *compl) { - if (!meta) - return; + compl->tx_timestamp = NULL; - if (meta->flags & XDP_TXMD_FLAGS_TIMESTAMP) - compl->tx_timestamp = &meta->completion.tx_timestamp; - else - compl->tx_timestamp = NULL; -} - -/** - * xsk_tx_metadata_request - Evaluate AF_XDP TX metadata at submission - * and call appropriate xsk_tx_metadata_ops operation. - * @meta: pointer to AF_XDP metadata area - * @ops: pointer to struct xsk_tx_metadata_ops - * @priv: pointer to driver-private aread - * - * This function should be called by the networking device when - * it prepares AF_XDP egress packet. - */ -static inline void xsk_tx_metadata_request(const struct xsk_tx_metadata *meta, - const struct xsk_tx_metadata_ops *ops, - void *priv) -{ if (!meta) return; - if (ops->tmo_request_launch_time) - if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME) - ops->tmo_request_launch_time(meta->request.launch_time, - priv); - - if (ops->tmo_request_timestamp) - if (meta->flags & XDP_TXMD_FLAGS_TIMESTAMP) - ops->tmo_request_timestamp(priv); + /* we can only arrive here if the completion timestamp has been + * requested via XDP_TXMD_FLAGS_TIMESTAMP, see xsk_tx_metadata_request + */ - if (ops->tmo_request_checksum) - if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) - ops->tmo_request_checksum(meta->request.csum_start, - meta->request.csum_offset, priv); + compl->tx_timestamp = &meta->completion.tx_timestamp; } /** @@ -231,12 +202,6 @@ static inline void xsk_tx_metadata_to_compl(struct xsk_tx_metadata *meta, { } -static inline void xsk_tx_metadata_request(struct xsk_tx_metadata *meta, - const struct xsk_tx_metadata_ops *ops, - void *priv) -{ -} - static inline void xsk_tx_metadata_complete(struct xsk_tx_metadata_compl *compl, const struct xsk_tx_metadata_ops *ops, void *priv) diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h index 46797645a0c2..b344789f5df8 100644 --- a/include/net/xdp_sock_drv.h +++ b/include/net/xdp_sock_drv.h @@ -245,7 +245,7 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr) * details. * * Return: new &xdp_desc_ctx struct containing desc's DMA address and metadata - * pointer, if it is present and valid (initialized to %NULL otherwise). + * pointer, if it is present (initialized to %NULL otherwise). */ static inline struct xdp_desc_ctx xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr) @@ -260,24 +260,70 @@ xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr) 0) static inline bool -xsk_buff_valid_tx_metadata(const struct xsk_tx_metadata *meta) +xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool, + const struct xsk_tx_metadata *meta, u64 *flags) { - return !(meta->flags & ~XDP_TXMD_FLAGS_VALID); + *flags = READ_ONCE(meta->flags); + if (*flags & XDP_TXMD_FLAGS_LAUNCH_TIME) + if (pool->tx_metadata_len < + offsetofend(struct xsk_tx_metadata, request.launch_time)) + return false; + return !(*flags & ~XDP_TXMD_FLAGS_VALID); +} + +/** + * xsk_tx_metadata_request - Evaluate AF_XDP TX metadata at submission + * and call appropriate xsk_tx_metadata_ops operation. + * @pool: pointer to AF_XDP buffer pool, used to validate the metadata + * @pmeta: pointer to pointer to AF_XDP metadata area + * @ops: pointer to struct xsk_tx_metadata_ops + * @priv: pointer to driver-private area + * + * This function should be called by the networking device when + * it prepares AF_XDP egress packet. + */ +static inline void +xsk_tx_metadata_request(const struct xsk_buff_pool *pool, + struct xsk_tx_metadata **pmeta, + const struct xsk_tx_metadata_ops *ops, void *priv) +{ + const struct xsk_tx_metadata *meta = *pmeta; + u64 flags; + + if (!meta) + return; + + if (unlikely(!xsk_buff_valid_tx_metadata(pool, meta, &flags))) { + *pmeta = NULL; + return; /* no way to signal the error to the user */ + } + + if (ops->tmo_request_launch_time) + if (flags & XDP_TXMD_FLAGS_LAUNCH_TIME) + ops->tmo_request_launch_time( + READ_ONCE(meta->request.launch_time), priv); + + if (ops->tmo_request_timestamp) + if (flags & XDP_TXMD_FLAGS_TIMESTAMP) + ops->tmo_request_timestamp(priv); + + if (ops->tmo_request_checksum) + if (flags & XDP_TXMD_FLAGS_CHECKSUM) + ops->tmo_request_checksum( + READ_ONCE(meta->request.csum_start), + READ_ONCE(meta->request.csum_offset), priv); + + if (!(flags & XDP_TXMD_FLAGS_TIMESTAMP)) + *pmeta = NULL; } static inline struct xsk_tx_metadata * __xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data) { - struct xsk_tx_metadata *meta; - if (!pool->tx_metadata_len) return NULL; - meta = data - pool->tx_metadata_len; - if (unlikely(!xsk_buff_valid_tx_metadata(meta))) - return NULL; /* no way to signal the error to the user */ - - return meta; + return data - pool->tx_metadata_len; } static inline struct xsk_tx_metadata * @@ -469,11 +515,20 @@ xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr) return (struct xdp_desc_ctx){ }; } -static inline bool xsk_buff_valid_tx_metadata(struct xsk_tx_metadata *meta) +static inline bool +xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool, + const struct xsk_tx_metadata *meta, u64 *flags) { return false; } +static inline void +xsk_tx_metadata_request(const struct xsk_buff_pool *pool, + struct xsk_tx_metadata **pmeta, + const struct xsk_tx_metadata_ops *ops, void *priv) +{ +} + static inline struct xsk_tx_metadata * __xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data) { |
