* Re: [PATCH net-next v2 5/5] ethtool: strset: check nla_len overflow
From: Stanislav Fomichev @ 2026-04-09 15:37 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Stanislav Fomichev, Hangbin Liu, Donald Hunter, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Andrew Lunn, netdev,
linux-kernel
In-Reply-To: <20260408173943.2c239ae8@kernel.org>
On 04/08, Jakub Kicinski wrote:
> On Wed, 8 Apr 2026 09:43:35 -0700 Stanislav Fomichev wrote:
> > On 04/08, Hangbin Liu wrote:
> > > The netlink attribute length field nla_len is a __u16, which can only
> > > represent values up to 65535 bytes. NICs with a large number of
> > > statistics strings (e.g. mlx5_core with thousands of ETH_SS_STATS
> > > entries) can produce a ETHTOOL_A_STRINGSET_STRINGS nest that exceeds
> > > this limit.
> > >
> > > When nla_nest_end() writes the actual nest size back to nla_len, the
> > > value is silently truncated. This results in a corrupted netlink message
> > > being sent to userspace: the parser reads a wrong (truncated) attribute
> > > length and misaligns all subsequent attribute boundaries, causing decode
> > > errors.
> > >
> > > Fix this by using the new helper nla_nest_end_safe and error out if
> > > the size exceeds U16_MAX.
> >
> > Not sure that's the user supposed to do? Does it mean there is no way
> > to retrieve ETHTOOL_A_STRINGSET_STRINGS for those devices with too
> > many strings?
>
> Not via Netlink, they can still read them via the ioctl?
> Since the legacy stats themselves can't be fetched over Netlink
> I'm not sure we should lose sleep over reading the stats strings
> via Netlink.
I guess... Should we update ethtool.yaml doc to tell the users to prefer
ioctl over netlink for strset-get and mention this new EMSGSIZE?
^ permalink raw reply
* Re: [PATCH v2 1/3] dt-bindings: net: dsa: nxp,sja1105: make spi-cpol optional for sja1110
From: Conor Dooley @ 2026-04-09 15:36 UTC (permalink / raw)
To: Josua Mayer
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Yazan Shhady, Mikhail Anikin,
Alexander Dahl, devicetree, linux-kernel, imx, linux-arm-kernel,
Vladimir Oltean, Conor Dooley, Krzysztof Kozlowski, netdev
In-Reply-To: <20260409-imx8dxl-sr-som-v2-1-83ff20629ba0@solid-run.com>
[-- Attachment #1: Type: text/plain, Size: 668 bytes --]
On Thu, Apr 09, 2026 at 02:34:33PM +0200, Josua Mayer wrote:
> Currently, the binding requires 'spi-cpha' for SJA1105 and 'spi-cpol'
> for SJA1110.
>
> However, the SJA1110 supports both SPI modes 0 and 2. Mode 2
> (cpha=0, cpol=1) is used by the NXP LX2160 Bluebox 3.
>
> On the SolidRun i.MX8DXL HummingBoard Telematics, mode 0 is stable,
> while forcing mode 2 introduces CRC errors especially during bursts.
>
> Drop the requirement on spi-cpol for SJA1110.
>
> Fixes: af2eab1a8243 ("dt-bindings: net: nxp,sja1105: document spi-cpol/cpha")
> Signed-off-by: Josua Mayer <josua@solid-run.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v2 3/3] net: mdio: treat PSE EPROBE_DEFER as non-fatal during PHY registration
From: Andrew Lunn @ 2026-04-09 15:34 UTC (permalink / raw)
To: Kory Maincent
Cc: Carlo Szelinsky, o.rempel, andrew+netdev, hkallweit1, linux, kuba,
davem, edumazet, pabeni, horms, netdev, linux-kernel
In-Reply-To: <20260409150922.74d82c39@kmaincent-XPS-13-7390>
> I don't think we should associate it to the MAC. In a hardware point of view the
> PSE Power Interfaces are wired the MDIs. It was associated historically to the
> PHY, because, at that time there was no representation of the MDI. Now thanks
> to Maxime there is, so in the future we should associate the PSE control to the
> MDI only. We will already have to keep the PHY association compatibility to not
> break binding API but please do not add another layer of association that will
> increase more compatibility burden for the future.
>
> As I proposed in another thread, if the PHY can't find the PSE PI, we could
> save the phandle of the PSE PI somewhere in the PHY structure. Then at PSE
> register time, look for each PHY and try to resolve every unresolved phandle.
I still think we should be deferring probe until we have all the parts
available. The question is, how do we actually do that?
We could insist that MACs being used with PSE need to call
phylink_connect() in probe, so we can return EPROBE_DEFER. We might
actually need a new API method, phylink_connect_probe(). That can call
down into phylib, maybe again new API methods, which will not bind
genphy, but return EPROBE_DEFER.
This helps solve this problem. And it puts in place a solution for
other similar problems. We have seen PHY drivers which download
firmware get into a similar situation, genphy used because the
download takes too long. It needs MAC driver changes, which is not
great, but the changes themselves should be easy to do.
I don't think having MDI represented helps us. We still get into the
same situation, open() calls phylink_connect() and there is nothing we
can do except use genphy.
Andrew
^ permalink raw reply
* Re: [PATCH net-next v11 03/14] net: Add lease info to queue-get response
From: Daniel Borkmann @ 2026-04-09 15:32 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, bpf, davem, razor, pabeni, willemb, sdf, john.fastabend,
martin.lau, jordan, maciej.fijalkowski, magnus.karlsson, dw, toke,
yangzhenze, wangdongdong.6
In-Reply-To: <20260409074651.2e58b3dd@kernel.org>
On 4/9/26 4:46 PM, Jakub Kicinski wrote:
> On Thu, 9 Apr 2026 15:52:42 +0200 Daniel Borkmann wrote:
>>>> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
>>> Thanks for looking into it! That looks good to me. I've also retested that
>>> it still works.
>>>
>>> Maybe small nits could be below to move the netif_is_queue_leasee into the
>>> netdev_rx_queue.h header since its used outside of core and it might be
>>> worth to also have the lock assertion in netdev_queue_get_dma_dev.
>
> I suspected it may irk you :) No strong preference on the placement.
> We do include the ../core/dev.h in a couple of places but agreed that
> it is slightly ugly.
How you prefer, I think either is fine if we also do this from a couple
of other places too.
>>> Do you want me to add your patch on top for a v12 of the series?
>
> Yes, please. Let's get it into 7.1.
>
> I think the test has to be reworked but of the available options seems
> like merging it as is and following up quickly is the best. I've only
> set up the container testing in our CI yesterday anyway so there may
> be more things that need changing in the test as we gain experience :S
No objections obviously if you want to land as-is with your refactor on
top. Then we'll follow-up with the selftest feedback + netkit nl dump.
Thanks,
Daniel
^ permalink raw reply
* Re: [PATCH net-next v2 1/5] tools: ynl: move ethtool.py to selftest
From: Stanislav Fomichev @ 2026-04-09 15:30 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Stanislav Fomichev, Hangbin Liu, Donald Hunter, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Andrew Lunn, netdev,
linux-kernel
In-Reply-To: <20260408173716.0dedf22c@kernel.org>
On 04/08, Jakub Kicinski wrote:
> On Wed, 8 Apr 2026 09:42:33 -0700 Stanislav Fomichev wrote:
> > > @@ -8,7 +8,7 @@ KSELFTEST_KTAP_HELPERS="$(dirname "$(realpath "$0")")/../../../testing/selftests
> > > source "$KSELFTEST_KTAP_HELPERS"
> > >
> > > # Default ynl-ethtool path for direct execution, can be overridden by make install
> > > -ynl_ethtool="../pyynl/ethtool.py"
> > > +ynl_ethtool="./ethtool.py"
> > >
> > > readonly NSIM_ID="1337"
> > > readonly NSIM_DEV_NAME="nsim${NSIM_ID}"
> >
> > Do we need to add some expects/asserts to the script to really make it into
> > a test? Right now it just prints things, so it's not really a test.
>
> This file is full of asserts? It's a bash script that runs ethtool.py
> and checks the output. Which one of us is missing the point ? :)
Oh, yes, I did miss the script!
^ permalink raw reply
* Re: [PATCH v2] ax25: fix OOB read after address header strip in ax25_rcv().
From: Eric Dumazet @ 2026-04-09 15:29 UTC (permalink / raw)
To: Ashutosh Desai
Cc: netdev, linux-hams, jreuter, davem, kuba, pabeni, horms,
linux-kernel
In-Reply-To: <20260409152400.2219716-1-ashutoshdesai993@gmail.com>
On Thu, Apr 9, 2026 at 8:24 AM Ashutosh Desai
<ashutoshdesai993@gmail.com> wrote:
>
> ax25_rcv() calls skb_pull(skb, ax25_addr_size(&dp)) to strip the
> address header, then reads skb->data[0] (control byte) and skb->data[1]
> (PID byte) without verifying those bytes are in the linear sk_buff area.
>
> The original fix checked skb->len < 2, but as Eric Dumazet pointed out,
> skb->len counts bytes across the linear head and any non-linear
> fragments. If the two bytes needed sit in a fragment, the check passes
> but the direct skb->data access is still out of bounds.
>
> Use pskb_may_pull(skb, 2) instead, which ensures both bytes are present
> and pulls them into the linear area if needed before we read them.
>
> Suggested-by: Eric Dumazet <edumazet@google.com>
I have not suggested to fix a bug in ax25.
I added a comment on your initial version.
A "Suggested-by" would imply I made the initial discovery.
Please carefully read Documentation/process/maintainer-netdev.rst
We require a 24-hour delay between each version.
^ permalink raw reply
* Re: [PATCH net-next v11 14/14] selftests/net: Add queue leasing tests with netkit
From: David Wei @ 2026-04-09 15:26 UTC (permalink / raw)
To: Jakub Kicinski, Daniel Borkmann
Cc: netdev, bpf, davem, razor, pabeni, willemb, sdf, john.fastabend,
martin.lau, jordan, maciej.fijalkowski, magnus.karlsson, toke,
yangzhenze, wangdongdong.6
In-Reply-To: <20260408162238.16709090@kernel.org>
On 2026-04-08 16:22, Jakub Kicinski wrote:
> On Fri, 3 Apr 2026 01:10:31 +0200 Daniel Borkmann wrote:
>> + ksft_run(
>> + [
>> + test_remove_phys,
>> + test_double_lease,
>> + test_virtual_lessor,
>> + test_phys_lessee,
>> + test_different_lessors,
>> + test_queue_out_of_range,
>> + test_resize_leased,
>
>> + # test_destroy must be last because it destroys the netkit devices
>> + ksft_run(
>> + [test_iou_zcrx, test_attrs, test_attach_xdp_with_mp, test_destroy],
>> + args=(cfg,),
>> + )
>> + ksft_exit()
>
> ksft_run() can't be called multiple times.
>
> The first run looks like it's purely testing netdevsim. So that should
> move to selftests/net. The rest which tests HW should stay here.
> Please also move all the setup inside the test cases.
Sorry, didn't know about multiple ksft_run(). I'll prep the follow up
separately so we can land it soon after 7.1.
^ permalink raw reply
* [PATCH v2] ax25: fix OOB read after address header strip in ax25_rcv().
From: Ashutosh Desai @ 2026-04-09 15:23 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, linux-hams, jreuter, davem, kuba, pabeni, horms,
linux-kernel, Ashutosh Desai
In-Reply-To: <CANn89iK7bzV0VpPsP5nu0mV3GCsN5MOZJgc_s8a3B2X6Ui6mxg@mail.gmail.com>
ax25_rcv() calls skb_pull(skb, ax25_addr_size(&dp)) to strip the
address header, then reads skb->data[0] (control byte) and skb->data[1]
(PID byte) without verifying those bytes are in the linear sk_buff area.
The original fix checked skb->len < 2, but as Eric Dumazet pointed out,
skb->len counts bytes across the linear head and any non-linear
fragments. If the two bytes needed sit in a fragment, the check passes
but the direct skb->data access is still out of bounds.
Use pskb_may_pull(skb, 2) instead, which ensures both bytes are present
and pulls them into the linear area if needed before we read them.
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Ashutosh Desai <ashutoshdesai993@gmail.com>
---
net/ax25/ax25_in.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index d75b3e9ed..6a71dea87 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -217,6 +217,11 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
*/
skb_pull(skb, ax25_addr_size(&dp));
+ if (!pskb_may_pull(skb, 2)) {
+ kfree_skb(skb);
+ return 0;
+ }
+
/* For our port addresses ? */
if (ax25cmp(&dest, dev_addr) == 0 && dp.lastrepeat + 1 == dp.ndigi)
mine = 1;
--
2.34.1
^ permalink raw reply related
* Re: [PATCH nf] netfilter: nf_conntrack_sip: fix OOB read in epaddr_len and ct_sip_parse_header_uri
From: Florian Westphal @ 2026-04-09 15:22 UTC (permalink / raw)
To: Weiming Shi
Cc: Pablo Neira Ayuso, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Phil Sutter, Simon Horman, Patrick McHardy,
netfilter-devel, coreteam, netdev, linux-kernel, Xiang Mei
In-Reply-To: <20260409095056.706441-2-bestswngs@gmail.com>
Weiming Shi <bestswngs@gmail.com> wrote:
> In epaddr_len() and ct_sip_parse_header_uri(), after sip_parse_addr()
> successfully parses an IP address, the code checks whether the next
> character is ':' to determine if a port number follows. However,
> neither function verifies that the pointer is still within bounds
> before dereferencing it.
I already queued up:
https://patchwork.ozlabs.org/project/netfilter-devel/patch/20260313195256.2783257-1-qguanni@gmail.com/
for nf-next (I already sent the 'last' PR for 7.0).
Could you check if that resolves the problem you're reporting?
> p = simple_strtoul(c, (char **)&c, 10);
All of these functions require a c-string, which we usually
don't have with network packet parsing.
IOW, sip helper needs to be audited for these problems
but I don't know when I can get to it.
^ permalink raw reply
* [PATCH v2] rose: fix OOB reads on short CLEAR REQUEST frames.
From: Ashutosh Desai @ 2026-04-09 15:19 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, linux-hams, davem, kuba, pabeni, horms,
linux-kernel, Ashutosh Desai
In-Reply-To: <CANn89iK7bzV0VpPsP5nu0mV3GCsN5MOZJgc_s8a3B2X6Ui6mxg@mail.gmail.com>
rose_process_rx_frame() passes skb directly to rose_decode(), which
reads skb->data[2] without any prior length check. For CLEAR REQUEST
frames the state machines then read skb->data[3] and skb->data[4] as
the cause and diagnostic bytes.
The original fix checked skb->len after the rose_decode() call, which
was wrong for two reasons: rose_decode() already accessed skb->data[2]
before the check ran, and skb->len counts bytes across non-linear
fragments while skb->data only covers the linear head - so even a
passing len check doesn't guarantee the bytes are safe to read directly.
Eric Dumazet pointed out that pskb_may_pull() is the right approach
here. Add a pskb_may_pull(skb, 3) check before rose_decode() to cover
its frame[2] access, and a pskb_may_pull(skb, 5) check afterwards for
the CLEAR REQUEST path to cover the cause and diagnostic reads.
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Ashutosh Desai <ashutoshdesai993@gmail.com>
---
net/rose/rose_in.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
index 0276b393f..b9f01a11e 100644
--- a/net/rose/rose_in.c
+++ b/net/rose/rose_in.c
@@ -269,8 +269,18 @@ int rose_process_rx_frame(struct sock *sk, struct sk_buff *skb)
if (rose->state == ROSE_STATE_0)
return 0;
+ if (!pskb_may_pull(skb, 3)) {
+ kfree_skb(skb);
+ return 0;
+ }
+
frametype = rose_decode(skb, &ns, &nr, &q, &d, &m);
+ if (frametype == ROSE_CLEAR_REQUEST && !pskb_may_pull(skb, 5)) {
+ kfree_skb(skb);
+ return 0;
+ }
+
switch (rose->state) {
case ROSE_STATE_1:
queued = rose_state1_machine(sk, skb, frametype);
--
2.34.1
^ permalink raw reply related
* [PATCH net 1/2] NFC: digital: Bounds check NFC-A cascade depth in SDD response handler
From: Greg Kroah-Hartman @ 2026-04-09 15:18 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, Greg Kroah-Hartman, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Kees Cook,
Thierry Escande, Samuel Ortiz, stable
The NFC-A anti-collision cascade in digital_in_recv_sdd_res() appends 3
or 4 bytes to target->nfcid1 on each round, but the number of cascade
rounds is controlled entirely by the peer device. The peer sets the
cascade tag in the SDD_RES (deciding 3 vs 4 bytes) and the
cascade-incomplete bit in the SEL_RES (deciding whether another round
follows).
ISO 14443-3 limits NFC-A to three cascade levels and target->nfcid1 is
sized accordingly (NFC_NFCID1_MAXSIZE = 10), but nothing in the driver
actually enforces this. This means a malicious peer can keep the
cascade running, writing past the heap-allocated nfc_target with each
round.
Fix this by rejecting the response when the accumulated UID would exceed
the buffer.
Commit e329e71013c9 ("NFC: nci: Bounds check struct nfc_target arrays")
fixed similar missing checks against the same field on the NCI path.
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Thierry Escande <thierry.escande@linux.intel.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Fixes: 2c66daecc409 ("NFC Digital: Add NFC-A technology support")
Cc: stable <stable@kernel.org>
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/digital_technology.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c
index 63f1b721c71d..ae63c5eb06fa 100644
--- a/net/nfc/digital_technology.c
+++ b/net/nfc/digital_technology.c
@@ -424,6 +424,12 @@ static void digital_in_recv_sdd_res(struct nfc_digital_dev *ddev, void *arg,
size = 4;
}
+ if (target->nfcid1_len + size > NFC_NFCID1_MAXSIZE) {
+ PROTOCOL_ERR("4.7.2.1");
+ rc = -EPROTO;
+ goto exit;
+ }
+
memcpy(target->nfcid1 + target->nfcid1_len, sdd_res->nfcid1 + offset,
size);
target->nfcid1_len += size;
--
2.53.0
^ permalink raw reply related
* [PATCH net 2/2] NFC: digital: Bounds check Felica response before sensf_res memcpy
From: Greg Kroah-Hartman @ 2026-04-09 15:18 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, Greg Kroah-Hartman, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Kees Cook,
Thierry Escande, Samuel Ortiz, stable
In-Reply-To: <2026040913-figure-seducing-bd3f@gregkh>
A malicious NFC peer can send a SENSF_RES that is longer than the
NFC_SENSF_RES_MAXSIZE (18 byte) sensf_res field in the onstack struct
nfc_target. digital_in_recv_sensf_res() validates that the response is
at least DIGITAL_SENSF_RES_MIN_LENGTH bytes but applies no upper bound
before memcpy(target.sensf_res, sensf_res, resp->len) is called,
allowing a stack buffer overflow with attacker-controlled length and
content.
Commit e329e71013c9 ("NFC: nci: Bounds check struct nfc_target arrays")
fixed identical missing checks for the same target->sensf_res field on
the NCI path; the Digital Protocol path was never patched.
Fix this all up by just rejecting responses that exceed
NFC_SENSF_RES_MAXSIZE.
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Thierry Escande <thierry.escande@linux.intel.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Fixes: 8c0695e4998d ("NFC Digital: Add NFC-F technology support")
Cc: stable <stable@kernel.org>
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/digital_technology.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c
index ae63c5eb06fa..e18bdb231352 100644
--- a/net/nfc/digital_technology.c
+++ b/net/nfc/digital_technology.c
@@ -774,6 +774,11 @@ static void digital_in_recv_sensf_res(struct nfc_digital_dev *ddev, void *arg,
skb_pull(resp, 1);
+ if (resp->len > NFC_SENSF_RES_MAXSIZE) {
+ rc = -EPROTO;
+ goto exit;
+ }
+
memset(&target, 0, sizeof(struct nfc_target));
sensf_res = (struct digital_sensf_res *)resp->data;
--
2.53.0
^ permalink raw reply related
* [PATCH net] ice: fix double free in ice_sf_eth_activate() error path
From: Greg Kroah-Hartman @ 2026-04-09 15:11 UTC (permalink / raw)
To: intel-wired-lan, netdev
Cc: linux-kernel, Greg Kroah-Hartman, Tony Nguyen, Przemek Kitszel,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Piotr Raczynski, Jiri Pirko, Simon Horman,
Michal Swiatkowski, stable
When auxiliary_device_add() fails, the aux_dev_uninit label calls
auxiliary_device_uninit() and falls through to sf_dev_free and xa_erase.
The uninit invokes ice_sf_dev_release(), which already frees sf_dev via
kfree() and erases the entry from ice_sf_aux_id. The fall-through then
double-frees sf_dev and double-erases the id.
This is reachable from userspace via the devlink port function state-set
netlink command.
Fix this by returning right after uninit because the release callback
handles all cleanup correctly.
Cc: Tony Nguyen <anthony.l.nguyen@intel.com>
Cc: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Piotr Raczynski <piotr.raczynski@intel.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Cc: Simon Horman <horms@kernel.org>
Cc: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Fixes: 177ef7f1e2a0 ("ice: base subfunction aux driver")
Cc: stable <stable@kernel.org>
Assisted-by: gregkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/intel/ice/ice_sf_eth.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_sf_eth.c b/drivers/net/ethernet/intel/ice/ice_sf_eth.c
index 2cf04bc6edce..6bc8aa896762 100644
--- a/drivers/net/ethernet/intel/ice/ice_sf_eth.c
+++ b/drivers/net/ethernet/intel/ice/ice_sf_eth.c
@@ -304,7 +304,9 @@ ice_sf_eth_activate(struct ice_dynamic_port *dyn_port,
return 0;
aux_dev_uninit:
+ /* ice_sf_dev_release() frees sf_dev and erases the xa entry */
auxiliary_device_uninit(&sf_dev->adev);
+ return err;
sf_dev_free:
kfree(sf_dev);
xa_erase:
--
2.53.0
^ permalink raw reply related
* Re: [net-next PATCH v5 1/4] octeontx2-af: npa: cn20k: Add NPA Halo support
From: Alexander Lobakin @ 2026-04-09 15:09 UTC (permalink / raw)
To: Subbaraya Sundeep
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham, gakula,
bbhushan2, netdev, linux-kernel, Linu Cherian
In-Reply-To: <1775728404-28451-2-git-send-email-sbhatta@marvell.com>
From: Subbaraya Sundeep <sbhatta@marvell.com>
Date: Thu, 9 Apr 2026 15:23:21 +0530
> From: Linu Cherian <lcherian@marvell.com>
>
> CN20K silicon implements unified aura and pool context
> type called Halo for better resource usage. Add support to
> handle Halo context type operations.
>
> Signed-off-by: Linu Cherian <lcherian@marvell.com>
> Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
[...]
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/struct.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/struct.h
> index 763f6cabd7c2..2364bafd329d 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/struct.h
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/struct.h
> @@ -377,4 +377,85 @@ struct npa_cn20k_pool_s {
>
> static_assert(sizeof(struct npa_cn20k_pool_s) == NIX_MAX_CTX_SIZE);
>
> +struct npa_cn20k_halo_s {
> + u64 stack_base : 64;
It's redundant to add : 64 to a 64-bit field.
Moreover, on 32-bit systems, the compilers sometimes complain on
bitfields > 32 bits.
> + u64 ena : 1;
> + u64 nat_align : 1;
> + u64 reserved_66_67 : 2;
> + u64 stack_caching : 1;
> + u64 reserved_69_71 : 3;
> + u64 aura_drop_ena : 1;
> + u64 reserved_73_79 : 7;
> + u64 aura_drop : 8;
> + u64 buf_offset : 12;
> + u64 reserved_100_103 : 4;
> + u64 buf_size : 12;
> + u64 reserved_116_119 : 4;
> + u64 ref_cnt_prof : 3;
> + u64 reserved_123_127 : 5;
> + u64 stack_max_pages : 32;
> + u64 stack_pages : 32;
> + u64 bp_0 : 7;
> + u64 bp_1 : 7;
> + u64 bp_2 : 7;
> + u64 bp_3 : 7;
> + u64 bp_4 : 7;
> + u64 bp_5 : 7;
> + u64 bp_6 : 7;
> + u64 bp_7 : 7;
> + u64 bp_ena_0 : 1;
> + u64 bp_ena_1 : 1;
> + u64 bp_ena_2 : 1;
> + u64 bp_ena_3 : 1;
> + u64 bp_ena_4 : 1;
> + u64 bp_ena_5 : 1;
> + u64 bp_ena_6 : 1;
> + u64 bp_ena_7 : 1;
> + u64 stack_offset : 4;
> + u64 reserved_260_263 : 4;
> + u64 shift : 6;
> + u64 reserved_270_271 : 2;
> + u64 avg_level : 8;
> + u64 avg_con : 9;
> + u64 fc_ena : 1;
> + u64 fc_stype : 2;
> + u64 fc_hyst_bits : 4;
> + u64 fc_up_crossing : 1;
> + u64 reserved_297_299 : 3;
> + u64 update_time : 16;
> + u64 reserved_316_319 : 4;
> + u64 fc_addr : 64;
> + u64 ptr_start : 64;
> + u64 ptr_end : 64;
> + u64 bpid_0 : 12;
> + u64 reserved_524_535 : 12;
> + u64 err_int : 8;
> + u64 err_int_ena : 8;
> + u64 thresh_int : 1;
> + u64 thresh_int_ena : 1;
> + u64 thresh_up : 1;
> + u64 reserved_555 : 1;
> + u64 thresh_qint_idx : 7;
> + u64 reserved_563 : 1;
> + u64 err_qint_idx : 7;
> + u64 reserved_571_575 : 5;
> + u64 thresh : 36;
> + u64 reserved_612_615 : 4;
> + u64 fc_msh_dst : 11;
> + u64 reserved_627_630 : 4;
> + u64 op_dpc_ena : 1;
> + u64 op_dpc_set : 5;
> + u64 reserved_637_637 : 1;
> + u64 stream_ctx : 1;
> + u64 unified_ctx : 1;
> + u64 reserved_640_703 : 64;
> + u64 reserved_704_767 : 64;
> + u64 reserved_768_831 : 64;
> + u64 reserved_832_895 : 64;
> + u64 reserved_896_959 : 64;
> + u64 reserved_960_1023 : 64;
> +};
> +
> +static_assert(sizeof(struct npa_cn20k_halo_s) == NIX_MAX_CTX_SIZE);
Now the main question:
Is mailbox's Endianness fixed (LE/BE)? Or is it always the same as the
host's ones (I doubt so)?
If not, these need to be __le{8,16,32,64} (or __be if it's Big Endian)
and you need to handle the conversions manually.
Thanks,
Olek
^ permalink raw reply
* [PATCH v2] nfc: hci: fix OOB heap read on short HCP frames
From: Ashutosh Desai @ 2026-04-09 15:08 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, davem, kuba, pabeni, horms, linux-kernel,
Ashutosh Desai
In-Reply-To: <CANn89iKq=oQOmvDtK-Vtr7r9yrD29cURgv8VOJ15mFHyJ0kXmw@mail.gmail.com>
Both nfc_hci_recv_from_llc() and nfc_hci_msg_rx_work() cast skb->data
to struct hcp_packet and read the message header byte without verifying
the data is present in the linear sk_buff area. The same issue exists in
the NCI HCI path via nci_hci_data_received_cb() and nci_hci_msg_rx_work().
The initial fix checked skb->len, but that counts bytes in non-linear
fragments too. skb->data only covers the linear head, so a fragmented
skb with len >= 2 but the payload in a fragment would still result in
an out-of-bounds read. Eric Dumazet pointed this out.
Switch to pskb_may_pull() which validates that the requested bytes are
available and pulls fragment data into the linear area if needed, which
is the correct approach here.
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Ashutosh Desai <ashutoshdesai993@gmail.com>
---
net/nfc/hci/core.c | 9 +++++++++
net/nfc/nci/hci.c | 9 +++++++++
2 files changed, 18 insertions(+)
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c
index 0d33c81a1..b8fe59f44 100644
--- a/net/nfc/hci/core.c
+++ b/net/nfc/hci/core.c
@@ -134,6 +134,10 @@ static void nfc_hci_msg_rx_work(struct work_struct *work)
u8 instruction;
while ((skb = skb_dequeue(&hdev->msg_rx_queue)) != NULL) {
+ if (!pskb_may_pull(skb, NFC_HCI_HCP_HEADER_LEN)) {
+ kfree_skb(skb);
+ continue;
+ }
pipe = skb->data[0];
skb_pull(skb, NFC_HCI_HCP_PACKET_HEADER_LEN);
message = (struct hcp_message *)skb->data;
@@ -904,6 +908,11 @@ static void nfc_hci_recv_from_llc(struct nfc_hci_dev *hdev, struct sk_buff *skb)
* unblock waiting cmd context. Otherwise, enqueue to dispatch
* in separate context where handler can also execute command.
*/
+ if (!pskb_may_pull(hcp_skb, NFC_HCI_HCP_HEADER_LEN)) {
+ kfree_skb(hcp_skb);
+ return;
+ }
+
packet = (struct hcp_packet *)hcp_skb->data;
type = HCP_MSG_GET_TYPE(packet->message.header);
if (type == NFC_HCI_HCP_RESPONSE) {
diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c
index 40ae8e5a7..4243ca9b1 100644
--- a/net/nfc/nci/hci.c
+++ b/net/nfc/nci/hci.c
@@ -412,6 +412,10 @@ static void nci_hci_msg_rx_work(struct work_struct *work)
for (; (skb = skb_dequeue(&hdev->msg_rx_queue)); kcov_remote_stop()) {
kcov_remote_start_common(skb_get_kcov_handle(skb));
+ if (!pskb_may_pull(skb, NCI_HCI_HCP_HEADER_LEN)) {
+ kfree_skb(skb);
+ continue;
+ }
pipe = NCI_HCP_MSG_GET_PIPE(skb->data[0]);
skb_pull(skb, NCI_HCI_HCP_PACKET_HEADER_LEN);
message = (struct nci_hcp_message *)skb->data;
@@ -482,6 +486,11 @@ void nci_hci_data_received_cb(void *context,
* unblock waiting cmd context. Otherwise, enqueue to dispatch
* in separate context where handler can also execute command.
*/
+ if (!pskb_may_pull(hcp_skb, NCI_HCI_HCP_HEADER_LEN)) {
+ kfree_skb(hcp_skb);
+ return;
+ }
+
packet = (struct nci_hcp_packet *)hcp_skb->data;
type = NCI_HCP_MSG_GET_TYPE(packet->message.header);
if (type == NCI_HCI_HCP_RESPONSE) {
--
2.34.1
^ permalink raw reply related
* [PATCH nf] netfilter: nf_conntrack_sip: fix OOB read in epaddr_len and ct_sip_parse_header_uri
From: Weiming Shi @ 2026-04-09 9:50 UTC (permalink / raw)
To: Pablo Neira Ayuso, Florian Westphal, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Phil Sutter, Simon Horman, Patrick McHardy, netfilter-devel,
coreteam, netdev, linux-kernel, Xiang Mei, Weiming Shi
In epaddr_len() and ct_sip_parse_header_uri(), after sip_parse_addr()
successfully parses an IP address, the code checks whether the next
character is ':' to determine if a port number follows. However,
neither function verifies that the pointer is still within bounds
before dereferencing it.
When a SIP header URI contains an IP address that extends to the last
byte of the packet data, in4_pton() or in6_pton() consumes all
available bytes and returns with the end pointer equal to limit. The
subsequent dereference reads one byte past the valid SIP message data.
ct_sip_parse_request() already handles this correctly:
if (end < limit && *end == ':') {
Apply the same bounds check to the two functions that are missing it.
Fixes: 9fafcd7b2032 ("[NETFILTER]: nf_conntrack/nf_nat: add SIP helper port")
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
net/netfilter/nf_conntrack_sip.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 939502ff7c87..83741901c6fb 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -194,7 +194,7 @@ static int epaddr_len(const struct nf_conn *ct, const char *dptr,
}
/* Port number */
- if (*dptr == ':') {
+ if (dptr < limit && *dptr == ':') {
dptr++;
dptr += digits_len(ct, dptr, limit, shift);
}
@@ -520,7 +520,7 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr,
if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true))
return -1;
- if (*c == ':') {
+ if (c < limit && *c == ':') {
c++;
p = simple_strtoul(c, (char **)&c, 10);
if (p < 1024 || p > 65535)
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2] netfilter: nft_fwd_netdev: use recursion counter in neigh egress path
From: Weiming Shi @ 2026-04-09 15:06 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Florian Westphal, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Phil Sutter, Simon Horman, netfilter-devel, coreteam,
netdev, Xiang Mei
In-Reply-To: <adeLtBMyR3KZInDW@chamomile>
On 26-04-09 13:21, Pablo Neira Ayuso wrote:
> On Thu, Apr 09, 2026 at 01:06:03PM +0200, Pablo Neira Ayuso wrote:
> > On Thu, Apr 09, 2026 at 06:49:12PM +0800, Weiming Shi wrote:
> > > nft_fwd_neigh can be used in egress chains (NF_NETDEV_EGRESS). When the
> > > forwarding rule targets the same device or two devices forward to each
> > > other, neigh_xmit() triggers dev_queue_xmit() which re-enters
> > > nf_hook_egress(), causing infinite recursion and stack overflow.
> > >
> > > Move the nf_get_nf_dup_skb_recursion() accessor and NF_RECURSION_LIMIT
> > > to the shared header nf_dup_netdev.h as a static inline, so that
> > > nft_fwd_netdev can use the recursion counter directly without exported
> > > function call overhead. Guard neigh_xmit() with the same recursion
> > > limit already used in nf_do_netdev_egress().
> > >
> > > Fixes: f87b9464d152 ("netfilter: nft_fwd_netdev: Support egress hook")
> >
> > I would just restrict this "feature", I don't see a point in allowing
> > this from egress?
>
> Hm, actually this can be combined with if0 device, fixing it makes sense.
>
> > > Reported-by: Xiang Mei <xmei5@asu.edu>
> > > Signed-off-by: Weiming Shi <bestswngs@gmail.com>
> > > ---
> > > include/net/netfilter/nf_dup_netdev.h | 13 +++++++++++++
> > > net/netfilter/nf_dup_netdev.c | 16 ----------------
> > > net/netfilter/nft_fwd_netdev.c | 7 +++++++
> > > 3 files changed, 20 insertions(+), 16 deletions(-)
> > >
> > > diff --git a/include/net/netfilter/nf_dup_netdev.h b/include/net/netfilter/nf_dup_netdev.h
> > > index b175d271aec9..609bcf422a9b 100644
> > > --- a/include/net/netfilter/nf_dup_netdev.h
> > > +++ b/include/net/netfilter/nf_dup_netdev.h
> > > @@ -3,10 +3,23 @@
> > > #define _NF_DUP_NETDEV_H_
> > >
> > > #include <net/netfilter/nf_tables.h>
> > > +#include <linux/netdevice.h>
> > > +#include <linux/sched.h>
> > >
> > > void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif);
> > > void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif);
> > >
> > > +#define NF_RECURSION_LIMIT 2
> > > +
> > > +static inline u8 *nf_get_nf_dup_skb_recursion(void)
> > > +{
> > > +#ifndef CONFIG_PREEMPT_RT
> > > + return this_cpu_ptr(&softnet_data.xmit.nf_dup_skb_recursion);
> > > +#else
> > > + return ¤t->net_xmit.nf_dup_skb_recursion;
> > > +#endif
> > > +}
> > > +
> > > struct nft_offload_ctx;
> > > struct nft_flow_rule;
> > >
> > > diff --git a/net/netfilter/nf_dup_netdev.c b/net/netfilter/nf_dup_netdev.c
> > > index fab8b9011098..a958a1b0c5be 100644
> > > --- a/net/netfilter/nf_dup_netdev.c
> > > +++ b/net/netfilter/nf_dup_netdev.c
> > > @@ -13,22 +13,6 @@
> > > #include <net/netfilter/nf_tables_offload.h>
> > > #include <net/netfilter/nf_dup_netdev.h>
> > >
> > > -#define NF_RECURSION_LIMIT 2
> > > -
> > > -#ifndef CONFIG_PREEMPT_RT
> > > -static u8 *nf_get_nf_dup_skb_recursion(void)
> > > -{
> > > - return this_cpu_ptr(&softnet_data.xmit.nf_dup_skb_recursion);
> > > -}
> > > -#else
> > > -
> > > -static u8 *nf_get_nf_dup_skb_recursion(void)
> > > -{
> > > - return ¤t->net_xmit.nf_dup_skb_recursion;
> > > -}
> > > -
> > > -#endif
> > > -
> > > static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev,
> > > enum nf_dev_hooks hook)
> > > {
> > > diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c
> > > index 152a9fb4d23a..492bb599a499 100644
> > > --- a/net/netfilter/nft_fwd_netdev.c
> > > +++ b/net/netfilter/nft_fwd_netdev.c
> > > @@ -141,13 +141,20 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr,
> > > goto out;
> > > }
> > >
> > > + if (*nf_get_nf_dup_skb_recursion() > NF_RECURSION_LIMIT) {
> > > + verdict = NF_DROP;
> > > + goto out;
> > > + }
> > > +
> > > dev = dev_get_by_index_rcu(nft_net(pkt), oif);
> > > if (dev == NULL)
> > > return;
> > >
> > > skb->dev = dev;
> > > skb_clear_tstamp(skb);
> > > + (*nf_get_nf_dup_skb_recursion())++;
> > > neigh_xmit(neigh_table, dev, addr, skb);
> > > + (*nf_get_nf_dup_skb_recursion())--;
> > > out:
> > > regs->verdict.code = verdict;
> > > }
> > > --
> > > 2.43.0
> > >
> > >
Thanks Pablo. So shall I keep v2 as is, or is there anything else you'd
like me to change?
^ permalink raw reply
* Re: [PATCH net-next v3] selftests/net: convert so_txtime to drv-net
From: Willem de Bruijn @ 2026-04-09 15:01 UTC (permalink / raw)
To: Willem de Bruijn, Jakub Kicinski, Willem de Bruijn
Cc: netdev, davem, edumazet, pabeni, horms, Willem de Bruijn
In-Reply-To: <willemdebruijn.kernel.1e324d665bb85@gmail.com>
Willem de Bruijn wrote:
> Jakub Kicinski wrote:
> > On Sun, 5 Apr 2026 22:49:22 -0400 Willem de Bruijn wrote:
> > > +@ksft_variants(_test_variants_mono())
> > > +def test_so_txtime_mono(cfg, ipver, args_tx, args_rx):
> > > + """Run all variants of monotonic (fq) tests."""
> > > + cmd(f"tc qdisc replace dev {cfg.ifname} root fq")
> > > + test_so_txtime(cfg, "mono", ipver, args_tx, args_rx, False)
> > > +
> > > +
> > > +def _test_variants_etf():
> > > + for ipver in ["4", "6"]:
> > > + for testcase in [
> > > + ["no_delay", "a,-1", "a,-1", True],
> > > + ["zero_delay", "a,0", "a,0", True],
> > > + ["one_pkt", "a,10", "a,10", False],
> > > + ["in_order", "a,10,b,20", "a,10,b,20", False],
> > > + ["reverse_order", "a,20,b,10", "b,10,a,20", False],
> > > + ]:
> > > + name = f"_v{ipver}_{testcase[0]}"
> >
> > nit: looking at the results in NIPA:
> > https://netdev-ctrl.bots.linux.dev/logs/vmksft/net-drv/results/593442/5-so-txtime-py/stdout
> > the leading _ seems unnecessary?
> >
> > > + yield KsftNamedVariant(
> > > + name, ipver, testcase[1], testcase[2], testcase[3]
> > > + )
> > > +
> > > +
> > > +@ksft_variants(_test_variants_etf())
> > > +def test_so_txtime_etf(cfg, ipver, args_tx, args_rx, expect_fail):
> > > + """Run all variants of etf tests."""
> > > + try:
> > > + # ETF does not support change, so remove and re-add it instead.
> > > + cmd_prefix = f"tc qdisc replace dev {cfg.ifname} root"
> > > + cmd(f"{cmd_prefix} pfifo_fast")
> > > + cmd(f"{cmd_prefix} etf clockid CLOCK_TAI delta 400000")
> > > + except Exception as e:
> > > + raise KsftSkipEx("tc does not support qdisc etf. skipping") from e
> > > +
> > > + test_so_txtime(cfg, "tai", ipver, args_tx, args_rx, expect_fail)
> >
> > I _think_ we'll leave ETF installed on the device after the test?
> > That seems not super great. As we discussed before rebuilding the
> > whole hierarchy will be tedious but we could at least replace with
> > mq on exit and let it put whatever the default qdisc is as its leaves?
>
> Good point. We can not set mq on netkit. It fails netif_is_multiqueue
> in mq_init_common. I'll do the following.
>
> @@ -81,6 +81,8 @@ def main() -> None:
> """Boilerplate ksft main."""
> with NetDrvEpEnv(__file__) as cfg:
> ksft_run([test_so_txtime_mono, test_so_txtime_etf], args=(cfg,))
> + if not cfg._ns:
> + cmd(f"tc qdisc replace dev {cfg.ifname} root mq")
> ksft_exit()
Actually, looking at a private field is not a good idea.
> Alternatively could record the root qdisc at the start of the test and
> restore that.
This should work:
def main() -> None:
"""Boilerplate ksft main."""
with NetDrvEpEnv(__file__) as cfg:
+ # Record original root qdisc
+ cmd_obj = cmd((f"tc -j qdisc show dev {cfg.ifname} root"))
+ qdisc_root = json.loads(cmd_obj.stdout)[0].get("kind", None)
+
ksft_run([test_so_txtime_mono, test_so_txtime_etf], args=(cfg,))
+
+ # Restore original root qdisc. If mq, populate with default_qdisc nodes
+ if (qdisc_root):
+ cmd(f"tc qdisc replace dev {cfg.ifname} root {qdisc_root}")
ksft_exit()
Do we want to add a tc command similar to ip, bpftool, etc.
^ permalink raw reply
* Re: [PATCH net-next] selftests: net: py: add test case filtering and listing
From: Breno Leitao @ 2026-04-09 14:58 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, shuah,
petrm, willemb, linux-kselftest
In-Reply-To: <20260409075617.0b22db0a@kernel.org>
On Thu, Apr 09, 2026 at 07:56:17AM -0700, Jakub Kicinski wrote:
> On Thu, 9 Apr 2026 05:41:59 -0700 Breno Leitao wrote:
> > > + print(f"Usage: {sys.argv[0]} [-h|-l] [-t|-T name]\n"
> > > + f"\t-h print help\n"
> > > + f"\t-l list all tests\n"
> >
> > I initially expected the help text to mention "(all or filtered)" based
> > on the commit message, but since this option lists all tests
> > unconditionally, the current wording is correct.
>
> Ugh, good catch. Not sure how I lost this. It does display a filtered
> list. I wanted the filtering to take effect so that one can see what
> tests would have been executed with the filters without running them.
> Sort of like a --dry-run.
>
> LMK if you have any thoughts on this, otherwise I'll rephrase as:
>
> f"\t-l list tests (filtered, if filters were specified)\n"
Ack, the above is fine.
^ permalink raw reply
* [PATCH net-next 5/5] net: change sk_filter_trim_cap() to return a drop_reason by value
From: Eric Dumazet @ 2026-04-09 14:56 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet
In-Reply-To: <20260409145625.2306224-1-edumazet@google.com>
Current return value can be replaced with the drop_reason,
reducing kernel bloat:
$ scripts/bloat-o-meter -t vmlinux.old vmlinux.new
add/remove: 0/2 grow/shrink: 1/11 up/down: 32/-603 (-571)
Function old new delta
tcp_v6_rcv 3135 3167 +32
unix_dgram_sendmsg 1731 1726 -5
netlink_unicast 957 945 -12
netlink_dump 1372 1359 -13
sk_filter_trim_cap 882 858 -24
tcp_v4_rcv 3143 3111 -32
__pfx_tcp_filter 32 - -32
netlink_broadcast_filtered 1633 1595 -38
sock_queue_rcv_skb_reason 126 76 -50
tun_net_xmit 1127 1074 -53
__sk_receive_skb 690 632 -58
udpv6_queue_rcv_one_skb 935 869 -66
udp_queue_rcv_one_skb 919 853 -66
tcp_filter 154 - -154
Total: Before=29722783, After=29722212, chg -0.00%
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/filter.h | 14 ++++++--------
include/net/tcp.h | 4 +---
net/core/filter.c | 31 ++++++++++++++-----------------
net/core/sock.c | 5 +++--
net/ipv4/udp.c | 3 ++-
net/ipv6/udp.c | 3 ++-
net/rose/rose_in.c | 3 +--
7 files changed, 29 insertions(+), 34 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 59931e5810b4fcff5788616a3875767421dba3bc..5ac08aa70123cf97ab91dea7e11e47b210a42d4a 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1092,23 +1092,21 @@ bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr)
return set_memory_rox((unsigned long)hdr, hdr->size >> PAGE_SHIFT);
}
-int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap,
- enum skb_drop_reason *reason);
+enum skb_drop_reason
+sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap);
static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
{
- enum skb_drop_reason ignore_reason;
+ enum skb_drop_reason drop_reason;
- return sk_filter_trim_cap(sk, skb, 1, &ignore_reason);
+ drop_reason = sk_filter_trim_cap(sk, skb, 1);
+ return drop_reason ? -EPERM : 0;
}
static inline enum skb_drop_reason
sk_filter_reason(struct sock *sk, struct sk_buff *skb)
{
- enum skb_drop_reason drop_reason;
-
- sk_filter_trim_cap(sk, skb, 1, &drop_reason);
- return drop_reason;
+ return sk_filter_trim_cap(sk, skb, 1);
}
struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 098e52269a04cb8938812a8f43caf11f9d5c68a3..49f45bcff917942e993c627dd3d0017369186f67 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1687,10 +1687,8 @@ static inline enum skb_drop_reason
tcp_filter(struct sock *sk, struct sk_buff *skb)
{
const struct tcphdr *th = (const struct tcphdr *)skb->data;
- enum skb_drop_reason reason;
- sk_filter_trim_cap(sk, skb, __tcp_hdrlen(th), &reason);
- return reason;
+ return sk_filter_trim_cap(sk, skb, __tcp_hdrlen(th));
}
void tcp_set_state(struct sock *sk, int state);
diff --git a/net/core/filter.c b/net/core/filter.c
index 5569d83b8be06dc1fe64ddff2ae338acd1622ed7..bf9c37b27646943e3a6fdad2fadf00f5e1ea8244 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -121,20 +121,20 @@ EXPORT_SYMBOL_GPL(copy_bpf_fprog_from_user);
* @sk: sock associated with &sk_buff
* @skb: buffer to filter
* @cap: limit on how short the eBPF program may trim the packet
- * @reason: record drop reason
*
* Run the eBPF program and then cut skb->data to correct size returned by
* the program. If pkt_len is 0 we toss packet. If skb->len is smaller
* than pkt_len we keep whole skb->data. This is the socket level
* wrapper to bpf_prog_run. It returns 0 if the packet should
- * be accepted or -EPERM if the packet should be tossed.
+ * be accepted or a drop_reason if the packet should be tossed.
*
*/
-int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb,
- unsigned int cap, enum skb_drop_reason *reason)
+enum skb_drop_reason
+sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap)
{
- int err;
+ enum skb_drop_reason drop_reason;
struct sk_filter *filter;
+ int err;
/*
* If the skb was allocated from pfmemalloc reserves, only
@@ -143,21 +143,17 @@ int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb,
*/
if (skb_pfmemalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC)) {
NET_INC_STATS(sock_net(sk), LINUX_MIB_PFMEMALLOCDROP);
- *reason = SKB_DROP_REASON_PFMEMALLOC;
- return -ENOMEM;
+ return SKB_DROP_REASON_PFMEMALLOC;
}
err = BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb);
- if (err) {
- *reason = SKB_DROP_REASON_SOCKET_FILTER;
- return err;
- }
+ if (err)
+ return SKB_DROP_REASON_SOCKET_FILTER;
err = security_sock_rcv_skb(sk, skb);
- if (err) {
- *reason = SKB_DROP_REASON_SECURITY_HOOK;
- return err;
- }
+ if (err)
+ return SKB_DROP_REASON_SECURITY_HOOK;
+ drop_reason = 0;
rcu_read_lock();
filter = rcu_dereference(sk->sk_filter);
if (filter) {
@@ -168,11 +164,12 @@ int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb,
pkt_len = bpf_prog_run_save_cb(filter->prog, skb);
skb->sk = save_sk;
err = pkt_len ? pskb_trim(skb, max(cap, pkt_len)) : -EPERM;
+ if (err)
+ drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
}
rcu_read_unlock();
- *reason = err ? SKB_DROP_REASON_SOCKET_FILTER : 0;
- return err;
+ return drop_reason;
}
EXPORT_SYMBOL(sk_filter_trim_cap);
diff --git a/net/core/sock.c b/net/core/sock.c
index 1ffcb15d0fc5e39201aab24616d40a37aa41c823..367fd7bad4ac2e6557dc73519ac0c04debb43cb3 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -544,11 +544,12 @@ EXPORT_SYMBOL(sock_queue_rcv_skb_reason);
int __sk_receive_skb(struct sock *sk, struct sk_buff *skb,
const int nested, unsigned int trim_cap, bool refcounted)
{
- enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
+ enum skb_drop_reason reason;
int rc = NET_RX_SUCCESS;
int err;
- if (sk_filter_trim_cap(sk, skb, trim_cap, &reason))
+ reason = sk_filter_trim_cap(sk, skb, trim_cap);
+ if (reason)
goto discard_and_relse;
skb->dev = NULL;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ab415de32443c5d32eedca5f093d5d96681f6b48..2fddc7b6b7172045286a8a0902f8bcf41aaca7c4 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2392,7 +2392,8 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
udp_lib_checksum_complete(skb))
goto csum_error;
- if (sk_filter_trim_cap(sk, skb, sizeof(struct udphdr), &drop_reason))
+ drop_reason = sk_filter_trim_cap(sk, skb, sizeof(struct udphdr));
+ if (drop_reason)
goto drop;
udp_csum_pull_header(skb);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d7cf4c9508b2c5c92753eddf8de1717f52347fbf..3fac9cb47ae00fe26c60ba2aee61748b4a241221 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -853,7 +853,8 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
udp_lib_checksum_complete(skb))
goto csum_error;
- if (sk_filter_trim_cap(sk, skb, sizeof(struct udphdr), &drop_reason))
+ drop_reason = sk_filter_trim_cap(sk, skb, sizeof(struct udphdr));
+ if (drop_reason)
goto drop;
udp_csum_pull_header(skb);
diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
index 0276b393f0e530ea2d8f689a3dd95364849910ac..3aff3c2d45a956a5c791beb5c2d5c4e4d7063d6a 100644
--- a/net/rose/rose_in.c
+++ b/net/rose/rose_in.c
@@ -101,7 +101,6 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
*/
static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype, int ns, int nr, int q, int d, int m)
{
- enum skb_drop_reason dr; /* ignored */
struct rose_sock *rose = rose_sk(sk);
int queued = 0;
@@ -163,7 +162,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
rose_frames_acked(sk, nr);
if (ns == rose->vr) {
rose_start_idletimer(sk);
- if (!sk_filter_trim_cap(sk, skb, ROSE_MIN_LEN, &dr) &&
+ if (!sk_filter_trim_cap(sk, skb, ROSE_MIN_LEN) &&
__sock_queue_rcv_skb(sk, skb) == 0) {
rose->vr = (rose->vr + 1) % ROSE_MODULUS;
queued = 1;
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related
* [PATCH net-next 4/5] tcp: change tcp_filter() to return the reason by value
From: Eric Dumazet @ 2026-04-09 14:56 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet
In-Reply-To: <20260409145625.2306224-1-edumazet@google.com>
sk_filter_trim_cap() will soon return the reason by value,
do the same for tcp_filter().
Note:
tcp_filter() is no longer inlined. Following patch will inline it again.
$ scripts/bloat-o-meter -t vmlinux.4 vmlinux.5
add/remove: 2/0 grow/shrink: 0/2 up/down: 186/-43 (143)
Function old new delta
tcp_filter - 154 +154
__pfx_tcp_filter - 32 +32
tcp_v4_rcv 3152 3143 -9
tcp_v6_rcv 3169 3135 -34
Total: Before=29722640, After=29722783, chg +0.00%
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/tcp.h | 8 +++++---
net/ipv4/tcp_ipv4.c | 6 ++++--
net/ipv6/tcp_ipv6.c | 6 ++++--
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 6156d1d068e142f696ec9dfff63e3aaebb0171bc..098e52269a04cb8938812a8f43caf11f9d5c68a3 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1683,12 +1683,14 @@ static inline bool tcp_checksum_complete(struct sk_buff *skb)
bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
enum skb_drop_reason *reason);
-static inline int tcp_filter(struct sock *sk, struct sk_buff *skb,
- enum skb_drop_reason *reason)
+static inline enum skb_drop_reason
+tcp_filter(struct sock *sk, struct sk_buff *skb)
{
const struct tcphdr *th = (const struct tcphdr *)skb->data;
+ enum skb_drop_reason reason;
- return sk_filter_trim_cap(sk, skb, __tcp_hdrlen(th), reason);
+ sk_filter_trim_cap(sk, skb, __tcp_hdrlen(th), &reason);
+ return reason;
}
void tcp_set_state(struct sock *sk, int state);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 69ab236072e7142d5ca9d0703d99f02c1e17c738..e2da3246a641e24328985cf558c322211df02b84 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2164,7 +2164,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
}
refcounted = true;
nsk = NULL;
- if (!tcp_filter(sk, skb, &drop_reason)) {
+ drop_reason = tcp_filter(sk, skb);
+ if (!drop_reason) {
th = (const struct tcphdr *)skb->data;
iph = ip_hdr(skb);
tcp_v4_fill_cb(skb, iph, th);
@@ -2225,7 +2226,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
nf_reset_ct(skb);
- if (tcp_filter(sk, skb, &drop_reason))
+ drop_reason = tcp_filter(sk, skb);
+ if (drop_reason)
goto discard_and_relse;
th = (const struct tcphdr *)skb->data;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 8dc3874e8b9252da60f21ad77a5ca834532e650a..d64d28e9842f7db69389034ac2ecdc76f405d379 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1794,7 +1794,8 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
}
refcounted = true;
nsk = NULL;
- if (!tcp_filter(sk, skb, &drop_reason)) {
+ drop_reason = tcp_filter(sk, skb);
+ if (!drop_reason) {
th = (const struct tcphdr *)skb->data;
hdr = ipv6_hdr(skb);
tcp_v6_fill_cb(skb, hdr, th);
@@ -1855,7 +1856,8 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
nf_reset_ct(skb);
- if (tcp_filter(sk, skb, &drop_reason))
+ drop_reason = tcp_filter(sk, skb);
+ if (drop_reason)
goto discard_and_relse;
th = (const struct tcphdr *)skb->data;
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related
* [PATCH net-next 3/5] net: change sk_filter_reason() to return the reason by value
From: Eric Dumazet @ 2026-04-09 14:56 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet
In-Reply-To: <20260409145625.2306224-1-edumazet@google.com>
sk_filter_trim_cap will soon return the reason by value,
do the same for sk_filter_reason().
$ scripts/bloat-o-meter -t vmlinux.old vmlinux.new
add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-21 (-21)
Function old new delta
sock_queue_rcv_skb_reason 128 126 -2
tun_net_xmit 1146 1127 -19
Total: Before=29722661, After=29722640, chg -0.00%
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
drivers/net/tun.c | 8 +++++---
include/linux/filter.h | 9 ++++++---
net/core/sock.c | 4 ++--
3 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index c492fda6fc15a79c13f56cb15dc273331b854422..b183189f185354051bded95f43bd77ee4f7cde24 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1031,9 +1031,11 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop;
}
- if (tfile->socket.sk->sk_filter &&
- sk_filter_reason(tfile->socket.sk, skb, &drop_reason))
- goto drop;
+ if (tfile->socket.sk->sk_filter) {
+ drop_reason = sk_filter_reason(tfile->socket.sk, skb);
+ if (drop_reason)
+ goto drop;
+ }
len = run_ebpf_filter(tun, skb, len);
if (len == 0) {
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 44d7ae95ddbccd0ba72740b5547e91e1990686f2..59931e5810b4fcff5788616a3875767421dba3bc 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1102,10 +1102,13 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
return sk_filter_trim_cap(sk, skb, 1, &ignore_reason);
}
-static inline int sk_filter_reason(struct sock *sk, struct sk_buff *skb,
- enum skb_drop_reason *reason)
+static inline enum skb_drop_reason
+sk_filter_reason(struct sock *sk, struct sk_buff *skb)
{
- return sk_filter_trim_cap(sk, skb, 1, reason);
+ enum skb_drop_reason drop_reason;
+
+ sk_filter_trim_cap(sk, skb, 1, &drop_reason);
+ return drop_reason;
}
struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err);
diff --git a/net/core/sock.c b/net/core/sock.c
index d39a4d6ccafd9e03f4e82482d3f3e46ce5d58771..1ffcb15d0fc5e39201aab24616d40a37aa41c823 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -526,8 +526,8 @@ sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb)
enum skb_drop_reason drop_reason;
int err;
- err = sk_filter_reason(sk, skb, &drop_reason);
- if (err)
+ drop_reason = sk_filter_reason(sk, skb);
+ if (drop_reason)
return drop_reason;
err = __sock_queue_rcv_skb(sk, skb);
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related
* [PATCH net-next 2/5] net: always set reason in sk_filter_trim_cap()
From: Eric Dumazet @ 2026-04-09 14:56 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet
In-Reply-To: <20260409145625.2306224-1-edumazet@google.com>
sk_filter_trim_cap() will soon return the drop reason by value.
Make sure *reason is cleared when no error is returned,
to ease this conversion.
$ scripts/bloat-o-meter -t vmlinux.old vmlinux.new
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-7 (-7)
Function old new delta
sk_filter_trim_cap 889 882 -7
Total: Before=29722668, After=29722661, chg -0.00%
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/core/filter.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index cf2113af4bc9ae7c976d7c55f3092643e1d875b6..5569d83b8be06dc1fe64ddff2ae338acd1622ed7 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -121,7 +121,7 @@ EXPORT_SYMBOL_GPL(copy_bpf_fprog_from_user);
* @sk: sock associated with &sk_buff
* @skb: buffer to filter
* @cap: limit on how short the eBPF program may trim the packet
- * @reason: record drop reason on errors (negative return value)
+ * @reason: record drop reason
*
* Run the eBPF program and then cut skb->data to correct size returned by
* the program. If pkt_len is 0 we toss packet. If skb->len is smaller
@@ -168,11 +168,10 @@ int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb,
pkt_len = bpf_prog_run_save_cb(filter->prog, skb);
skb->sk = save_sk;
err = pkt_len ? pskb_trim(skb, max(cap, pkt_len)) : -EPERM;
- if (err)
- *reason = SKB_DROP_REASON_SOCKET_FILTER;
}
rcu_read_unlock();
+ *reason = err ? SKB_DROP_REASON_SOCKET_FILTER : 0;
return err;
}
EXPORT_SYMBOL(sk_filter_trim_cap);
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related
* [PATCH net-next 1/5] net: change sock_queue_rcv_skb_reason() to return a drop_reason
From: Eric Dumazet @ 2026-04-09 14:56 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet
In-Reply-To: <20260409145625.2306224-1-edumazet@google.com>
Change sock_queue_rcv_skb_reason() to return the drop_reason directly
instead of using a reference.
This is part of an effort to remove stack canaries and reduce bloat.
$ scripts/bloat-o-meter -t vmlinux.old vmlinux.new
add/remove: 0/0 grow/shrink: 3/7 up/down: 79/-301 (-222)
Function old new delta
vsock_queue_rcv_skb 50 79 +29
ipmr_cache_report 1290 1315 +25
ip6mr_cache_report 1322 1347 +25
packet_rcv_spkt 329 327 -2
sock_queue_rcv_skb_reason 166 128 -38
raw_rcv_skb 122 80 -42
ping_queue_rcv_skb 109 61 -48
ping_rcv 215 162 -53
rawv6_rcv_skb 278 224 -54
raw_rcv 591 527 -64
Total: Before=29722890, After=29722668, chg -0.00%
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/sock.h | 17 ++++++++++++++---
net/can/bcm.c | 5 ++---
net/can/isotp.c | 3 ++-
net/can/j1939/socket.c | 3 ++-
net/can/raw.c | 3 ++-
net/core/sock.c | 20 ++++++--------------
net/ipv4/ping.c | 3 ++-
net/ipv4/raw.c | 3 ++-
net/ipv6/raw.c | 3 ++-
9 files changed, 34 insertions(+), 26 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index 7d51ac9e7d9a87a7f6f0453a3d3e2c6ed34dc151..5831a4d1ebe77e3d6f568d208fafb072f9635242 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2502,12 +2502,23 @@ int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue,
struct sk_buff *skb));
int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
-int sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb,
- enum skb_drop_reason *reason);
+enum skb_drop_reason
+sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb);
static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
- return sock_queue_rcv_skb_reason(sk, skb, NULL);
+ enum skb_drop_reason drop_reason = sock_queue_rcv_skb_reason(sk, skb);
+
+ switch (drop_reason) {
+ case SKB_DROP_REASON_SOCKET_RCVBUFF:
+ return -ENOMEM;
+ case SKB_DROP_REASON_PROTO_MEM:
+ return -ENOBUFS;
+ case 0:
+ return 0;
+ default:
+ return -EPERM;
+ }
}
int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb);
diff --git a/net/can/bcm.c b/net/can/bcm.c
index fd9fa072881e22ced725fa77dd096dea07fb73a6..d6291381afb09c36b30557f1d1a328c9ed0579f7 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -363,7 +363,6 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
struct sockaddr_can *addr;
struct sock *sk = op->sk;
unsigned int datalen = head->nframes * op->cfsiz;
- int err;
unsigned int *pflags;
enum skb_drop_reason reason;
@@ -420,8 +419,8 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
addr->can_family = AF_CAN;
addr->can_ifindex = op->rx_ifindex;
- err = sock_queue_rcv_skb_reason(sk, skb, &reason);
- if (err < 0) {
+ reason = sock_queue_rcv_skb_reason(sk, skb);
+ if (reason) {
struct bcm_sock *bo = bcm_sk(sk);
sk_skb_reason_drop(sk, skb, reason);
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 2770f43f4951884658d54ac90bd1e0ae21c24102..c48b4a818297e2a1348a2b64016d0f4ff613e683 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -291,7 +291,8 @@ static void isotp_rcv_skb(struct sk_buff *skb, struct sock *sk)
addr->can_family = AF_CAN;
addr->can_ifindex = skb->dev->ifindex;
- if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0)
+ reason = sock_queue_rcv_skb_reason(sk, skb);
+ if (reason)
sk_skb_reason_drop(sk, skb, reason);
}
diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
index 0502b030d23851652be252f1342861332ce97367..50a598ef5fd4a5f5e007816a341e04ddbcc724e6 100644
--- a/net/can/j1939/socket.c
+++ b/net/can/j1939/socket.c
@@ -333,7 +333,8 @@ static void j1939_sk_recv_one(struct j1939_sock *jsk, struct sk_buff *oskb)
if (skb->sk)
skcb->msg_flags |= MSG_DONTROUTE;
- if (sock_queue_rcv_skb_reason(&jsk->sk, skb, &reason) < 0)
+ reason = sock_queue_rcv_skb_reason(&jsk->sk, skb);
+ if (reason)
sk_skb_reason_drop(&jsk->sk, skb, reason);
}
diff --git a/net/can/raw.c b/net/can/raw.c
index eee244ffc31ecc0e1cc1aae29cd1d13a4e6b54ca..56c95c768778accaec42cb998c7d679a42c85894 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -207,7 +207,8 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
if (oskb->sk == sk)
*pflags |= MSG_CONFIRM;
- if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0)
+ reason = sock_queue_rcv_skb_reason(sk, skb);
+ if (reason)
sk_skb_reason_drop(sk, skb, reason);
}
diff --git a/net/core/sock.c b/net/core/sock.c
index e821b95e00151ab6b4be89209abcbaa494234433..d39a4d6ccafd9e03f4e82482d3f3e46ce5d58771 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -520,32 +520,24 @@ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
}
EXPORT_SYMBOL(__sock_queue_rcv_skb);
-int sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb,
- enum skb_drop_reason *reason)
+enum skb_drop_reason
+sock_queue_rcv_skb_reason(struct sock *sk, struct sk_buff *skb)
{
enum skb_drop_reason drop_reason;
int err;
err = sk_filter_reason(sk, skb, &drop_reason);
if (err)
- goto out;
+ return drop_reason;
err = __sock_queue_rcv_skb(sk, skb);
switch (err) {
case -ENOMEM:
- drop_reason = SKB_DROP_REASON_SOCKET_RCVBUFF;
- break;
+ return SKB_DROP_REASON_SOCKET_RCVBUFF;
case -ENOBUFS:
- drop_reason = SKB_DROP_REASON_PROTO_MEM;
- break;
- default:
- drop_reason = SKB_NOT_DROPPED_YET;
- break;
+ return SKB_DROP_REASON_PROTO_MEM;
}
-out:
- if (reason)
- *reason = drop_reason;
- return err;
+ return SKB_NOT_DROPPED_YET;
}
EXPORT_SYMBOL(sock_queue_rcv_skb_reason);
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index bda245c808938cf2a26270bcd83c74898e5b36dd..1273d1028ed9ca91734481f65652bfc43efd039a 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -935,7 +935,8 @@ static enum skb_drop_reason __ping_queue_rcv_skb(struct sock *sk,
pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
inet_sk(sk), inet_sk(sk)->inet_num, skb);
- if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) {
+ reason = sock_queue_rcv_skb_reason(sk, skb);
+ if (reason) {
sk_skb_reason_drop(sk, skb, reason);
pr_debug("ping_queue_rcv_skb -> failed\n");
return reason;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 34859e537b4926f15996dd1a684ae59a55a1643a..319428bf06bb89932c0b4295a0f96c275f8ecab1 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -300,7 +300,8 @@ static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb)
/* Charge it to the socket. */
ipv4_pktinfo_prepare(sk, skb, true);
- if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) {
+ reason = sock_queue_rcv_skb_reason(sk, skb);
+ if (reason) {
sk_skb_reason_drop(sk, skb, reason);
return NET_RX_DROP;
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 0ac7046911000d30056e0d1f49a58964c61308cf..3cc58698cbbd3a16cf0145e0afff7a6cec8dc56f 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -369,7 +369,8 @@ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb)
/* Charge it to the socket. */
skb_dst_drop(skb);
- if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) {
+ reason = sock_queue_rcv_skb_reason(sk, skb);
+ if (reason) {
sk_skb_reason_drop(sk, skb, reason);
return NET_RX_DROP;
}
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related
* [PATCH net-next 0/5] net: reduce sk_filter() (and friends) bloat
From: Eric Dumazet @ 2026-04-09 14:56 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet
Some functions return an error by value, and a drop_reason
by an output parameter. This extra parameter can force stack canaries.
A drop_reason is enough and more efficient.
This series reduces bloat by 678 bytes on x86_64:
$ scripts/bloat-o-meter -t vmlinux.old vmlinux.final
add/remove: 0/0 grow/shrink: 3/18 up/down: 79/-757 (-678)
Function old new delta
vsock_queue_rcv_skb 50 79 +29
ipmr_cache_report 1290 1315 +25
ip6mr_cache_report 1322 1347 +25
tcp_v6_rcv 3169 3167 -2
packet_rcv_spkt 329 327 -2
unix_dgram_sendmsg 1731 1726 -5
netlink_unicast 957 945 -12
netlink_dump 1372 1359 -13
sk_filter_trim_cap 889 858 -31
netlink_broadcast_filtered 1633 1595 -38
tcp_v4_rcv 3152 3111 -41
raw_rcv_skb 122 80 -42
ping_queue_rcv_skb 109 61 -48
ping_rcv 215 162 -53
rawv6_rcv_skb 278 224 -54
__sk_receive_skb 690 632 -58
raw_rcv 591 527 -64
udpv6_queue_rcv_one_skb 935 869 -66
udp_queue_rcv_one_skb 919 853 -66
tun_net_xmit 1146 1074 -72
sock_queue_rcv_skb_reason 166 76 -90
Total: Before=29722890, After=29722212, chg -0.00%
Future conversions from sock_queue_rcv_skb() to sock_queue_rcv_skb_reason()
can be done later.
Eric Dumazet (5):
net: change sock_queue_rcv_skb_reason() to return a drop_reason
net: always set reason in sk_filter_trim_cap()
net: change sk_filter_reason() to return the reason by value
tcp: change tcp_filter() to return the reason by value
net: change sk_filter_trim_cap() to return a drop_reason by value
drivers/net/tun.c | 8 +++++---
include/linux/filter.h | 15 ++++++++-------
include/net/sock.h | 17 ++++++++++++++---
include/net/tcp.h | 6 +++---
net/can/bcm.c | 5 ++---
net/can/isotp.c | 3 ++-
net/can/j1939/socket.c | 3 ++-
net/can/raw.c | 3 ++-
net/core/filter.c | 30 +++++++++++++-----------------
net/core/sock.c | 29 +++++++++++------------------
net/ipv4/ping.c | 3 ++-
net/ipv4/raw.c | 3 ++-
net/ipv4/tcp_ipv4.c | 6 ++++--
net/ipv4/udp.c | 3 ++-
net/ipv6/raw.c | 3 ++-
net/ipv6/tcp_ipv6.c | 6 ++++--
net/ipv6/udp.c | 3 ++-
net/rose/rose_in.c | 3 +--
18 files changed, 81 insertions(+), 68 deletions(-)
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox