* [PATCH bpf v3 0/2] Fix partial copy of non-linear test_run output
From: Sun Jian @ 2026-06-17 9:35 UTC (permalink / raw)
To: bpf
Cc: netdev, linux-kselftest, linux-kernel, ast, daniel, andrii,
martin.lau, eddyz87, memxor, song, yonghong.song, jolsa, davem,
edumazet, kuba, pabeni, horms, shuah, hawk, john.fastabend, sdf,
toke, lorenzo, paul.chaignon, Sun Jian
When BPF_PROG_TEST_RUN returns non-linear output and userspace provides a
short data_out buffer, bpf_test_finish() can return -ENOSPC before copying
the packet prefix or updating data_size_out.
Fix this by deriving the linear copy length from the packet layout rather
than from the already-clamped copy_size. Add selftest coverage for both
non-linear skb and XDP frags paths.
Changes in v3:
* Keep the fix patch minimal by leaving the existing offset declaration
unchanged.
* Drop unnecessary memset() calls from the new selftests.
* Keep the pass-through TC program and larger test packet for the skb
case. pkt_v4 is too small once the short IPv4 input check is accounted
for, and the existing packet-access program fails before reaching the
partial copy-out path with such a short linear area.
Changes in v2:
* Fix the Fixes tag to point to the commit that introduced the shared
non-linear copy-out logic.
* Drop skb-specific wording from the fix commit.
* Move the selftest from skb_load_bytes.c to prog_run_opts.c.
* Add XDP frags coverage in addition to non-linear skb coverage.
v2:
https://lore.kernel.org/bpf/20260616093103.471444-1-sun.jian.kdev@gmail.com/
v1:
https://lore.kernel.org/bpf/20260615073856.152479-1-sun.jian.kdev@gmail.com/
Tested with:
./test_progs -t prog_run_opts -v
./test_progs -t skb_load_bytes -v
./test_progs -t xdp_pull_data -v
Sun Jian (2):
bpf: Fix partial copy of non-linear test_run output
selftests/bpf: Cover partial copy of non-linear test_run output
net/bpf/test_run.c | 8 +--
.../selftests/bpf/prog_tests/prog_run_opts.c | 70 +++++++++++++++++++
.../selftests/bpf/progs/test_pkt_access.c | 12 ++++
3 files changed, 84 insertions(+), 6 deletions(-)
--
2.43.0
^ permalink raw reply
* [PATCH net-next v1] net: wangxun: don't advertise IFF_SUPP_NOFCS
From: Rongguang Wei @ 2026-06-17 9:28 UTC (permalink / raw)
To: netdev; +Cc: jiawenwu, mengyuanlou, pabeni, kuba, Rongguang Wei
From: Rongguang Wei <weirongguang@kylinos.cn>
Like commit a24162f18825("i40e: don't advertise IFF_SUPP_NOFCS"),
ngbe and txgbe also advertises IFF_SUPP_NOFCS and allowing users
to use the SO_NOFCS socket option. But the driver does not check
skb->no_fcs, so this option is silently ignored.
With this change, send() fails with -EPROTONOSUPPORT when AF_PACKET
socket is set SO_NOFCS option.
Signed-off-by: Rongguang Wei <weirongguang@kylinos.cn>
---
drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 1 -
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
index d8e3827a8b1f..1e4ebac8e495 100644
--- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
+++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
@@ -713,7 +713,6 @@ static int ngbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_GRO;
netdev->priv_flags |= IFF_UNICAST_FLT;
- netdev->priv_flags |= IFF_SUPP_NOFCS;
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
netdev->min_mtu = ETH_MIN_MTU;
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
index 8b7c3753bb6a..db9262b00a66 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
@@ -801,7 +801,6 @@ static int txgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_RX_UDP_TUNNEL_PORT;
netdev->priv_flags |= IFF_UNICAST_FLT;
- netdev->priv_flags |= IFF_SUPP_NOFCS;
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
netdev->min_mtu = ETH_MIN_MTU;
--
2.25.1
^ permalink raw reply related
* Re: [PATCH] rocker: Fix memory leak in ofdpa_port_fdb()
From: Andrew Lunn @ 2026-06-17 9:26 UTC (permalink / raw)
To: Jacob Keller
Cc: Ziran Zhang, Jiri Pirko, Andrew Lunn, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel
In-Reply-To: <1446e974-0df0-4956-b2af-7a9403da3c8d@intel.com>
On Tue, Jun 16, 2026 at 04:29:59PM -0700, Jacob Keller wrote:
> On 6/15/2026 6:32 PM, Ziran Zhang wrote:
> > In ofdpa_port_fdb(), the hash_del() only unlinks the node from
> > hash table, but does not free it.
> >
> > Fix this by adding kfree(found) after the !found == removing check,
> > where the pointer value is no longer needed.
> >
> > Found by Coccinelle kfree script.
> >
Is rocker actually used any more? I'm not too sure of the history, but
was it not added as a way to develop the early switchdev code? There
was a qemu implementation of the 'hardware'?
Is it still useful? Should we actually just remove the driver?
Andrew
^ permalink raw reply
* Re: [PATCH bpf-next v2 2/4] bpf: Add BPF_FIB_LOOKUP_VLAN flag to bpf_fib_lookup() helper
From: Toke Høiland-Jørgensen @ 2026-06-17 9:26 UTC (permalink / raw)
To: Avinash Duduskar, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko
Cc: Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis,
John Fastabend, Stanislav Fomichev, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, David Ahern,
Shuah Khan, Jesper Dangaard Brouer, Mykyta Yatsenko, Leon Hwang,
KP Singh, Anton Protopopov, Amery Hung, Eyal Birger, Rong Tao,
bpf, netdev, linux-kselftest, linux-kernel
In-Reply-To: <20260616223426.3568080-3-avinash.duduskar@gmail.com>
Avinash Duduskar <avinash.duduskar@gmail.com> writes:
> bpf_fib_lookup() returns the FIB-resolved egress ifindex straight
> from the fib result. When the egress is a VLAN device, the returned
> ifindex is the VLAN netdev's, which has no XDP xmit handler; XDP
> programs that want to forward the frame (e.g. xdp-forward) must
> instead target the underlying physical device and push the VLAN tag
> themselves. Today the program has no way to learn either the
> underlying ifindex or the VLAN tag without maintaining its own
> VLAN-to-ifindex map in userspace and refreshing it on netlink
> events.
>
> Add BPF_FIB_LOOKUP_VLAN. When the caller sets this flag and the fib
> result is a VLAN device whose immediate parent is a real (non-VLAN)
> device in the same network namespace, populate the existing output
> fields params->h_vlan_proto and params->h_vlan_TCI from the VLAN
> device and replace params->ifindex with the parent's ifindex.
> params->h_vlan_TCI carries the VID only, with PCP and DEI bits zero; a
> consumer wanting to set egress priority writes PCP itself.
> params->smac is the VLAN device's own address, which can differ from
> the parent's.
>
> Only the immediate parent is resolved, via vlan_dev_priv(dev)->real_dev
> and not vlan_dev_real_dev(), which walks to the bottom of a stack. For a
> stacked VLAN (QinQ) the immediate parent is itself a VLAN device; since
> one h_vlan_proto/h_vlan_TCI pair cannot describe two tags, ifindex is
> left unchanged and the vlan fields remain zero in that case. The swap
> is also skipped when the parent lives in another network namespace (a
> VLAN device can be moved while its parent stays), since its ifindex
> would be meaningless or match an unrelated device in the caller's
> namespace. The swap and the vlan fields are written only on success;
> other output fields keep their existing behaviour, so a frag-needed
> result still reports the route mtu in params->mtu_result. When the
> flag is not set, behaviour is unchanged: h_vlan_proto and h_vlan_TCI
> are zeroed and ifindex is left at the FIB result.
>
> The new block is compiled only under CONFIG_VLAN_8021Q since
> vlan_dev_priv() is not defined otherwise; without that config
> is_vlan_dev() is constant false and the flag is accepted but never
> acts.
>
> This lets an XDP redirect target the physical device and learn the
> tag to push in a single lookup, which xdp-forward's optional VLAN
> mode (xdp-project/xdp-tools#504) wants from the kernel side.
>
> The helper's input semantics are unchanged; the reverse direction
> (supplying a tag as lookup input) is added in the following patch.
>
> Suggested-by: Toke Høiland-Jørgensen <toke@redhat.com>
> Signed-off-by: Avinash Duduskar <avinash.duduskar@gmail.com>
> ---
> include/uapi/linux/bpf.h | 31 ++++++++++++++++++++++++++-
> net/core/filter.c | 39 ++++++++++++++++++++++++++++++----
> tools/include/uapi/linux/bpf.h | 31 ++++++++++++++++++++++++++-
> 3 files changed, 95 insertions(+), 6 deletions(-)
>
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 11dd610fa5fa..f77aa9472bf1 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -3527,6 +3527,31 @@ union bpf_attr {
> * Use the mark present in *params*->mark for the fib lookup.
> * This option should not be used with BPF_FIB_LOOKUP_DIRECT,
> * as it only has meaning for full lookups.
> + * **BPF_FIB_LOOKUP_VLAN**
> + * If the fib lookup resolves to a VLAN device whose
> + * parent is a real (non-VLAN) device, set
> + * *params*->h_vlan_proto and *params*->h_vlan_TCI from
> + * the VLAN device and replace *params*->ifindex with the
> + * parent's ifindex. This lets XDP programs that target
> + * the underlying physical device (VLAN devices have no
> + * XDP xmit) discover both the real egress ifindex and
> + * the VLAN tag to push in one call. *params*->h_vlan_TCI
> + * carries the VID only, with PCP and DEI bits zero; a
> + * consumer wanting to set egress priority writes PCP
> + * itself. *params*->smac is the VLAN device's own
> + * address, which can differ from the parent's. Only the
> + * immediate parent is resolved: for a stacked VLAN (QinQ)
> + * the parent is itself a VLAN device, and since one tag
> + * pair cannot describe two tags, *params*->ifindex is
> + * left unchanged and the vlan fields remain zero. The
> + * same applies when the parent is in another network
> + * namespace, where its ifindex would be meaningless.
> + * The swap and the vlan fields are written only on
> + * success; other output fields keep the helper's
> + * existing behaviour, so a frag-needed result still
> + * reports the route mtu in *params*->mtu_result, and on
> + * the tc path without tot_len the mtu check runs after
> + * the swap, against the parent device.
This comment is quite long, please trim. At the very least drop:
"This lets XDP programs that target the underlying physical device (VLAN
devices have no XDP xmit) discover both the real egress ifindex and the
VLAN tag to push in one call."
and shorten:
"Only the immediate parent is resolved: for a stacked VLAN
(QinQ) the parent is itself a VLAN device, and since one tag pair cannot
describe two tags, *params*->ifindex is left unchanged and the vlan
fields remain zero. The same applies when the parent is in another
network namespace, where its ifindex would be meaningless."
to:
"The lookup only resolves the immediate parent (QinQ is not supported),
and fails if the parent is in a different namespace."
> *
> * *ctx* is either **struct xdp_md** for XDP programs or
> * **struct sk_buff** tc cls_act programs.
> @@ -7322,6 +7347,7 @@ enum {
> BPF_FIB_LOOKUP_TBID = (1U << 3),
> BPF_FIB_LOOKUP_SRC = (1U << 4),
> BPF_FIB_LOOKUP_MARK = (1U << 5),
> + BPF_FIB_LOOKUP_VLAN = (1U << 6),
> };
>
> enum {
> @@ -7388,7 +7414,10 @@ struct bpf_fib_lookup {
>
> union {
> struct {
> - /* output */
> + /* output with BPF_FIB_LOOKUP_VLAN: set from the
> + * resolved egress VLAN device (see the flag); zeroed
> + * on other successful lookups.
> + */
> __be16 h_vlan_proto;
> __be16 h_vlan_TCI;
> };
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 6fa172cb1348..b37a12321fba 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -6119,10 +6119,40 @@ static const struct bpf_func_proto bpf_skb_get_xfrm_state_proto = {
> #endif
>
> #if IS_ENABLED(CONFIG_INET) || IS_ENABLED(CONFIG_IPV6)
> -static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params, u32 mtu)
> +static int bpf_fib_set_fwd_params(struct net_device *dev,
> + struct bpf_fib_lookup *params,
> + u32 flags, u32 mtu)
> {
> params->h_vlan_TCI = 0;
> params->h_vlan_proto = 0;
> +
> +#if IS_ENABLED(CONFIG_VLAN_8021Q)
> + /* vlan_dev_priv() is only defined when 8021q is built in or as a
> + * module; under !CONFIG_VLAN_8021Q is_vlan_dev() is constant false
> + * so this would be dead, but it still has to compile.
> + */
Superfluous comment - please drop.
> + if ((flags & BPF_FIB_LOOKUP_VLAN) && is_vlan_dev(dev)) {
> + struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
> +
> + /* Resolve the immediate parent only. For a stacked VLAN
> + * (QinQ) the parent is itself a VLAN device, and a single
> + * h_vlan_proto/h_vlan_TCI pair cannot describe both tags;
> + * leave ifindex and the vlan fields untouched in that case
> + * rather than report the lower device with only one tag.
> + * The same applies when the parent lives in another netns
> + * (a VLAN device can be moved while its parent stays):
> + * its ifindex would be meaningless, or match an unrelated
> + * device, in the caller's namespace.
> + */
And this one - it's redundant with the flag description (and commit message).
-Toke
^ permalink raw reply
* [PATCH v2] net: mvneta: free/request IRQ across suspend/resume
From: Yun Zhou @ 2026-06-17 9:20 UTC (permalink / raw)
To: marcin.s.wojtas, andrew+netdev, davem, edumazet, kuba, pabeni,
bigeasy, clrkwllms, rostedt
Cc: netdev, linux-kernel, linux-rt-devel, yun.zhou
On PREEMPT_RT, the mvneta IRQ handler is force-threaded. Under high
network traffic, the IRQ can enter suspend with desc->depth == 1
(masked by the oneshot mechanism between handler invocations).
During suspend, the kernel increments depth to 2 and masks the
interrupt at the MPIC level (clearing the SRC_CTL CPU routing bit,
due to IRQCHIP_MASK_ON_SUSPEND). On resume, depth is decremented
back to 1, but since it does not reach 0, the unmask is never
called. The MPIC CPU routing remains cleared, permanently disabling
interrupt delivery.
Fix by freeing the IRQ in suspend and re-requesting it in resume.
This ensures a clean IRQ state (depth=0, proper hardware routing)
on every resume cycle, regardless of the pre-suspend depth. This
follows the approach used by other drivers (e.g. igb).
Fixes: 9768b45ceb0b ("net: mvneta: support suspend and resume")
Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
---
v2:
- Move request_irq before cpuhp registration in resume (matching
mvneta_open ordering) so that failure does not leave cpuhp
callbacks registered on a non-functional device.
- On request_irq failure, call netif_device_detach() to prevent
further traffic on the dead interface.
drivers/net/ethernet/marvell/mvneta.c | 29 +++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index b4a845f04c05..02ea867d07a3 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5826,6 +5826,20 @@ static int mvneta_suspend(struct device *device)
mvneta_stop_dev(pp);
rtnl_unlock();
+ /* Release IRQ to avoid stale MPIC mask state on resume.
+ * On PREEMPT_RT, forced-threaded oneshot IRQs may leave the
+ * interrupt masked (depth>0) at suspend time. This prevents
+ * resume_device_irqs() from restoring the MPIC CPU routing,
+ * permanently disabling the interrupt. Re-requesting the IRQ
+ * on resume guarantees a clean state.
+ */
+ if (pp->neta_armada3700)
+ free_irq(dev->irq, pp);
+ else {
+ on_each_cpu(mvneta_percpu_disable, pp, true);
+ free_percpu_irq(dev->irq, pp->ports);
+ }
+
for (queue = 0; queue < rxq_number; queue++) {
struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
@@ -5892,6 +5906,21 @@ static int mvneta_resume(struct device *device)
mvneta_txq_hw_init(pp, txq);
}
+ /* Re-request IRQ (see comment in mvneta_suspend) */
+ if (pp->neta_armada3700) {
+ err = request_irq(dev->irq, mvneta_isr, 0, dev->name, pp);
+ } else {
+ err = request_percpu_irq(dev->irq, mvneta_percpu_isr,
+ dev->name, pp->ports);
+ if (!err)
+ on_each_cpu(mvneta_percpu_enable, pp, true);
+ }
+ if (err) {
+ netdev_err(dev, "cannot request irq %d\n", dev->irq);
+ netif_device_detach(dev);
+ return err;
+ }
+
if (!pp->neta_armada3700) {
spin_lock(&pp->lock);
pp->is_stopped = false;
--
2.43.0
^ permalink raw reply related
* Re: [RESEND PATCH v1] net: dsa: motorcomm: add yt92xx dsa driver
From: Andrew Lunn @ 2026-06-17 9:19 UTC (permalink / raw)
To: Kyle Switch
Cc: mmyangfl, olteanv, davem, edumazet, kuba, pabeni, horms, netdev,
linux-kernel, ming.xu, xiaolin.xu, jianmin.wang, de.ge
In-Reply-To: <adc1dc4b-1d9d-42e6-8983-f0a7c650a6cd@motor-comm.com>
> Thank you for your reminding, this patch will submitted in a series
> of small patches.
> This patch mainly contains three contents:
> 1. Underlying function interface for different motorcomm switch series in
> the file driver/net/dsa/motorcomm/switch/.
> 2. Optimization existing yt921x dsa driver using common switch function apis.
> 3. New yt922x dsa driver.
> Can you accept break this up into lots of small patch according to this logic?
> if not, do you have any suggestion? thank you.
We need to see the patches, but keep them small, and add functionality
little by little. I had a very quick look at your first version, and i
see a lot you will need to change. So just post small bits of code,
learn from the review comments, and fixup all the rest of the code
before posting it.
One thing i need to point out. Linux has a long tradition of not
replacing existing code with a new implementation. You take the
existing code and step by step improve it. So i do not want to see a
patch which just removes the existing driver. I want to see patches
which add new functionality to the existing driver, doing refactors as
needed.
Please also remember:
MOTORCOMM YT921X ETHERNET SWITCH DRIVER
M: David Yang <mmyangfl@gmail.com>
L: netdev@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/net/dsa/motorcomm,yt921x.yaml
F: drivers/net/dsa/yt921x.*
F: net/dsa/tag_yt921x.c
David is the Maintainer of this driver. Listen to what he says. In
time, when you have shown you can also can do the job of being a
Maintainer, your name will be added.
Andrew
^ permalink raw reply
* Re: [PATCH net] net/mlx5e: macsec: fix use-after-free of metadata_dst on RX SC delete
From: Simon Horman @ 2026-06-17 9:16 UTC (permalink / raw)
To: doruk
Cc: Simon Horman, saeedm, leon, tariqt, mbloch, andrew+netdev, davem,
edumazet, kuba, pabeni, borisp, sd, raeds, ehakim, netdev,
linux-rdma, linux-kernel, stable
In-Reply-To: <20260615140534.52691-1-doruk@0sec.ai>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
net/mlx5e: macsec: fix use-after-free of metadata_dst on RX SC delete
This patch replaces metadata_dst_free() with dst_release() during MACsec
RX SC deletion. It relies on the dst subsystem's refcounting to defer freeing
the metadata_dst until the last reference is dropped, aiming to fix a
use-after-free when an skb still references it.
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
> index 71b3a059c9647..2a4e7ed76d315 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
> @@ -829,7 +829,7 @@ static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec
> */
> list_del_rcu(&rx_sc->rx_sc_list_element);
> xa_erase(&macsec->sc_xarray, rx_sc->sc_xarray_element->fs_id);
> - metadata_dst_free(rx_sc->md_dst);
> + dst_release(&rx_sc->md_dst->dst);
[Severity: High]
Does this change introduce a new use-after-free in the RX datapath?
When dst_release() drops the refcount to 0, concurrent readers in
mlx5e_macsec_offload_handle_rx_skb() can still find the object via RCU
and call dst_hold(). Because dst_hold() uses rcuref_get(), it fails on a
0-refcount object without incrementing the count.
However, the datapath still attaches the 0-refcount dst to the skb. When the
skb is later freed, skb_dst_drop() will call dst_release() on already-freed
memory.
Should the datapath be updated to use dst_hold_safe() instead?
> kfree(rx_sc->sc_xarray_element);
[Severity: High]
This is a pre-existing issue, but does this synchronous kfree() cause a
use-after-free for concurrent datapath readers?
The element was just removed from the RCU-protected xarray via xa_erase(),
but the RX datapath can still be accessing it via xa_load() under
rcu_read_lock() in mlx5e_macsec_offload_handle_rx_skb().
Should this use an RCU-deferred free mechanism instead?
[Severity: Critical]
This is a pre-existing issue, but does mlx5e_macsec_offload_handle_rx_skb()
blindly dereference the result of xa_load()?
drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c:mlx5e_macsec_offload_handle_rx_skb() {
...
sc_xarray_element = xa_load(&macsec->sc_xarray, fs_id);
rx_sc = sc_xarray_element->rx_sc;
...
}
If xa_load() returns NULL (e.g., if the entry was concurrently deleted by
xa_erase() or the packet has an unrecognized fs_id), will this cause a
deterministic kernel panic?
Is a NULL check needed before accessing the returned element?
> kfree_rcu_mightsleep(rx_sc);
> }
^ permalink raw reply
* [PATCH net v3 2/2] net: macb: drop in-flight Tx SKBs on close
From: Théo Lebrun @ 2026-06-17 9:17 UTC (permalink / raw)
To: Nicolas Ferre, Claudiu Beznea, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Haavard Skinnemoen,
Jeff Garzik, Conor Dooley
Cc: Paolo Valerio, Nicolai Buchwitz, netdev, linux-kernel,
Vladimir Kondratiev, Gregory CLEMENT, Benoît Monin,
Tawfik Bayouk, Thomas Petazzoni, Maxime Chevallier,
Théo Lebrun, stable
In-Reply-To: <20260617-macb-drop-tx-v3-0-d4c7e57d890b@bootlin.com>
The MACB driver has since forever leaked the outgoing SKBs that
have not yet been marked as completed. They live in queue->tx_skb
which gets freed without remorse nor checking.
macb_free_consistent() gets called in a few codepaths, but only
close will trigger the added expressions. In macb_open() and
macb_alloc_consistent() failure cases, tx_skb just got allocated
and is empty.
Use the new macb_tx_unmap() prototype to report our error as
SKB_DROP_REASON_NOT_SPECIFIED rather than SKB_CONSUMED which makes it
sound like no error occurred. Equivalent to dev_kfree_skb_any().
Fixes: 89e5785fc8a6 ("[PATCH] Atmel MACB ethernet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
drivers/net/ethernet/cadence/macb_main.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 9caae1ef52b1..5a2500bd59a6 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -2678,8 +2678,26 @@ static void macb_free_consistent(struct macb *bp)
dma_free_coherent(dev, size, bp->queues[0].rx_ring, bp->queues[0].rx_ring_dma);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
- kfree(queue->tx_skb);
- queue->tx_skb = NULL;
+ if (queue->tx_skb) {
+ unsigned int dropped = 0, tail;
+
+ for (tail = queue->tx_tail; tail != queue->tx_head;
+ tail++) {
+ if (macb_tx_skb(queue, tail)->skb)
+ dropped++;
+ macb_tx_unmap(bp, macb_tx_skb(queue, tail), 0,
+ SKB_DROP_REASON_NOT_SPECIFIED);
+ }
+
+ queue->stats.tx_dropped += dropped;
+ bp->dev->stats.tx_dropped += dropped;
+
+ kfree(queue->tx_skb);
+ queue->tx_skb = NULL;
+ }
+
+ queue->tx_head = 0;
+ queue->tx_tail = 0;
queue->tx_ring = NULL;
queue->rx_ring = NULL;
}
--
2.54.0
^ permalink raw reply related
* [PATCH net v3 1/2] net: macb: give reasons for Tx SKB kfree
From: Théo Lebrun @ 2026-06-17 9:17 UTC (permalink / raw)
To: Nicolas Ferre, Claudiu Beznea, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Haavard Skinnemoen,
Jeff Garzik, Conor Dooley
Cc: Paolo Valerio, Nicolai Buchwitz, netdev, linux-kernel,
Vladimir Kondratiev, Gregory CLEMENT, Benoît Monin,
Tawfik Bayouk, Thomas Petazzoni, Maxime Chevallier,
Théo Lebrun, stable
In-Reply-To: <20260617-macb-drop-tx-v3-0-d4c7e57d890b@bootlin.com>
Using dev_consume_skb_any() marks the drop reason as SKB_CONSUMED every
time we free a Tx SKB. Instead, replace by SKB_DROP_REASON_NOT_SPECIFIED
when packet has been dropped without sending.
It is not precise but at least differs from SKB_CONSUMED and is used by
many drivers for their error codepaths through dev_kfree_skb_{any,irq}().
Pass a reason around rather than call dev_consume_skb_any() or
dev_kfree_skb_any() because macb_tx_unmap() is called for cleanup in
all cases.
macb_tx_error_task() is made complex because some SKBs encountered have
been successfully sent.
Fixes: 89e5785fc8a6 ("[PATCH] Atmel MACB ethernet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
drivers/net/ethernet/cadence/macb_main.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index a12aa21244e8..9caae1ef52b1 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1201,7 +1201,8 @@ static int macb_halt_tx(struct macb *bp)
bp, TSR);
}
-static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budget)
+static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb,
+ int budget, enum skb_drop_reason reason)
{
if (tx_skb->mapping) {
if (tx_skb->mapped_as_page)
@@ -1214,7 +1215,7 @@ static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budge
}
if (tx_skb->skb) {
- dev_consume_skb_any(tx_skb->skb);
+ dev_kfree_skb_any_reason(tx_skb->skb, reason);
tx_skb->skb = NULL;
}
}
@@ -1297,7 +1298,8 @@ static void macb_tx_error_task(struct work_struct *work)
* Free transmit buffers in upper layer.
*/
for (tail = queue->tx_tail; tail != queue->tx_head; tail++) {
- u32 ctrl;
+ enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
+ u32 ctrl;
desc = macb_tx_desc(queue, tail);
ctrl = desc->ctrl;
@@ -1307,7 +1309,10 @@ static void macb_tx_error_task(struct work_struct *work)
if (ctrl & MACB_BIT(TX_USED)) {
/* skb is set for the last buffer of the frame */
while (!skb) {
- macb_tx_unmap(bp, tx_skb, 0);
+ /* The reason parameter is unused because it
+ * only matters when skb is valid.
+ */
+ macb_tx_unmap(bp, tx_skb, 0, SKB_CONSUMED);
tail++;
tx_skb = macb_tx_skb(queue, tail);
skb = tx_skb->skb;
@@ -1326,6 +1331,7 @@ static void macb_tx_error_task(struct work_struct *work)
bp->dev->stats.tx_bytes += skb->len;
queue->stats.tx_bytes += skb->len;
bytes += skb->len;
+ reason = SKB_CONSUMED;
}
} else {
/* "Buffers exhausted mid-frame" errors may only happen
@@ -1339,7 +1345,7 @@ static void macb_tx_error_task(struct work_struct *work)
desc->ctrl = ctrl | MACB_BIT(TX_USED);
}
- macb_tx_unmap(bp, tx_skb, 0);
+ macb_tx_unmap(bp, tx_skb, 0, reason);
}
netdev_tx_completed_queue(netdev_get_tx_queue(bp->dev, queue_index),
@@ -1458,7 +1464,7 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
}
/* Now we can safely release resources */
- macb_tx_unmap(bp, tx_skb, budget);
+ macb_tx_unmap(bp, tx_skb, budget, SKB_CONSUMED);
/* skb is set only for the last buffer of the frame.
* WARNING: at this point skb has been freed by
@@ -2357,7 +2363,11 @@ static unsigned int macb_tx_map(struct macb *bp,
for (i = queue->tx_head; i != tx_head; i++) {
tx_skb = macb_tx_skb(queue, i);
- macb_tx_unmap(bp, tx_skb, 0);
+ /* The reason parameter is unused, tx_skb->skb has not yet
+ * been assigned. Parent caller is responsible for freeing
+ * the SKB.
+ */
+ macb_tx_unmap(bp, tx_skb, 0, SKB_DROP_REASON_NOT_SPECIFIED);
}
return -ENOMEM;
--
2.54.0
^ permalink raw reply related
* [PATCH net v3 0/2] Drop in-flight Tx SKBs on MACB close
From: Théo Lebrun @ 2026-06-17 9:17 UTC (permalink / raw)
To: Nicolas Ferre, Claudiu Beznea, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Haavard Skinnemoen,
Jeff Garzik, Conor Dooley
Cc: Paolo Valerio, Nicolai Buchwitz, netdev, linux-kernel,
Vladimir Kondratiev, Gregory CLEMENT, Benoît Monin,
Tawfik Bayouk, Thomas Petazzoni, Maxime Chevallier,
Théo Lebrun, stable
The first patch is here to allow giving a drop reason.
We dissociate consumed packets from dropped ones that way.
Second patch is the main one: it drops unsent packets on close.
MACB driver forgot freeing its SKBs (and associated DMA mappings).
---
Changes in v3:
- Drop stats fixing. A proper fix deserves its own net-next refactoring
series to migrate to netdev_stat_ops (ynltool uAPI), which will come
in later. We keep the tx_dropped++ because they are safe as every
other context is disabled when macb_free_consistent() is called.
- Rebased to latest net/main (406e8a651a7b), nothing to report.
- Link to v2: https://patch.msgid.link/20260428-macb-drop-tx-v2-0-647f5199d8df@bootlin.com
Changes in v2:
- Increment tx_dropped stat once per SKB, not once per frame.
- Reset tx_head & tx_tail to avoid keeping stalled cursors.
- Fix SKB dropped reasons throughout by adding the reason as parameter
to macb_tx_unmap(). This is a new patch. Then the drop-all-on-close
fix can use this ability to report we are not consuming SKBs.
- Add increment to stats->tx_dropped on DMA mapping failure and
tx_error_task. Done as separate patches (3 and 4).
- Rebase upon net/main @ 46f74a3f7d57, nothing to report.
- Link to v1: https://patch.msgid.link/20260424-macb-drop-tx-v1-1-b3ecb787d84d@bootlin.com
To: Nicolas Ferre <nicolas.ferre@microchip.com>
To: Claudiu Beznea <claudiu.beznea@tuxon.dev>
To: Andrew Lunn <andrew+netdev@lunn.ch>
To: "David S. Miller" <davem@davemloft.net>
To: Eric Dumazet <edumazet@google.com>
To: Jakub Kicinski <kuba@kernel.org>
To: Paolo Abeni <pabeni@redhat.com>
To: Haavard Skinnemoen <hskinnemoen@atmel.com>
To: Jeff Garzik <jeff@garzik.org>
To: Conor Dooley <conor.dooley@microchip.com>
Cc: Paolo Valerio <pvalerio@redhat.com>
Cc: Nicolai Buchwitz <nb@tipi-net.de>
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
Cc: Gregory CLEMENT <gregory.clement@bootlin.com>
Cc: Benoît Monin <benoit.monin@bootlin.com>
Cc: Tawfik Bayouk <tawfik.bayouk@mobileye.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
Théo Lebrun (2):
net: macb: give reasons for Tx SKB kfree
net: macb: drop in-flight Tx SKBs on close
drivers/net/ethernet/cadence/macb_main.c | 46 +++++++++++++++++++++++++-------
1 file changed, 37 insertions(+), 9 deletions(-)
---
base-commit: 712927eaa34199bb62cf370af591c0550ba977de
change-id: 20260423-macb-drop-tx-f9ce72720d05
Best regards,
--
Théo Lebrun <theo.lebrun@bootlin.com>
^ permalink raw reply
* Re: [PATCH net] net: airoha: Fix TX scheduler queue mask loop upper bound
From: Lorenzo Bianconi @ 2026-06-17 9:17 UTC (permalink / raw)
To: Wayen Yan; +Cc: netdev, nbd, linux-arm-kernel, linux-mediatek
In-Reply-To: <178168650178.2224380.3950331731013129336@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2931 bytes --]
> On Tue, Jun 17, 2026, Lorenzo Bianconi wrote:
> > Even if the current codebase supports just AIROHA_NUM_QOS_CHANNEL (4), the hw
> > exposes 32 hw QoS channels (AIROHA_NUM_TX_RING). Here we are just clearing the
> > configuration, so I guess the current implementation is correct.
>
> Hi Lorenzo,
>
> You are right that there is no functional impact, and I agree this
> should not go to net. Let me explain the register layout I was worried
> about, and you can decide whether it is worth a net-next cleanup or
> should just be dropped.
>
> The two macros are:
>
> REG_QUEUE_CLOSE_CFG(_n) = 0x00a0 + ((_n) & 0xfc)
> TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) = BIT((_m) + (((_n) & 0x3) << 3))
>
> REG_QUEUE_CLOSE_CFG() masks the channel with 0xfc, and the bit macro
> folds the channel with & 0x3 (mod 4) shifted by 3. So one 32-bit
> register holds 4 channels x 8 queues, 8 queue bits per channel:
>
> channel 0 -> reg 0x00a0, bits 0..7
> channel 1 -> reg 0x00a0, bits 8..15
> channel 2 -> reg 0x00a0, bits 16..23
> channel 3 -> reg 0x00a0, bits 24..31
> channel 4 -> reg 0x00a4, bits 0..7
> ...
>
> In airoha_qdma_set_chan_tx_sched() the loop variable 'i' is passed as
> the *queue* argument _m, not as a channel:
>
> for (i = 0; i < AIROHA_NUM_TX_RING; i++) // i = 0..31
> airoha_qdma_clear(qdma, REG_QUEUE_CLOSE_CFG(channel),
> TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
>
> Since each channel only has AIROHA_NUM_QOS_QUEUES (8) queues, the correct
> logic is to clear the 8 queue bits belonging to 'channel'. With i running
> up to 31 the BIT() shift instead walks past those 8 bits and into the bit
> ranges of the other channels folded into the same register. For channel 0
> the accumulated mask becomes 0xffffffff, i.e. it touches channels 1..3 as
> well.
>
> This is harmless today only because REG_QUEUE_CLOSE_CFG is written
> exclusively here, via airoha_qdma_clear() (RMW clear), and the register
> resets to 0 and is never set anywhere -- so clearing extra bits is a
> no-op. Functionally the current code is fine, as you say.
>
> The point is just the loop-bound semantics: 'i' is a per-channel queue
> index, so the bound should be AIROHA_NUM_QOS_QUEUES (8), not
> AIROHA_NUM_TX_RING (32). The two happen to be related (32 == 4 channels *
> 8 queues) but mean different things.
>
> Since there is no functional change, feel free to drop this if you would
> rather not carry a cosmetic patch. If you think the clarity is worth it I
> can resend against net-next without the Fixes tag.
>
> Thanks,
> Wayen
>
Sorry you are right, I misread the code, your patch is correct. Since as you
pointed out REG_QUEUE_CLOSE_CFG() is actually never set at the moment and the
default register value is 0, I would repost this patch for net-next as soon as
it is opened (this will avoid merge conflicts).
Regards,
Lorenzo
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [RESEND PATCH v1] net: dsa: motorcomm: add yt92xx dsa driver
From: Andrew Lunn @ 2026-06-17 9:07 UTC (permalink / raw)
To: Kyle Switch
Cc: David Yang, olteanv, davem, edumazet, kuba, pabeni, horms, netdev,
linux-kernel, ming.xu, xiaolin.xu, jianmin.wang, de.ge
In-Reply-To: <88f726d5-1617-4d2e-8fbb-d3da9478b386@motor-comm.com>
> >> +#define CMM_PARAM_CHK(expr, err_code) \
> >> + do { \
> >> + if ((u32)(expr)) { \
> >> + return err_code; \
> >> + } \
> >> + } while (0)
> >> +
> >> +#define CMM_ERR_CHK(op, ret) \
> >> + do { \
> >> + ret = (op); \
> >> + if (ret != CMM_ERR_OK) \
> >> + return ret; \
> >> + } while (0)
> >
> > Do not use macros like this.
>
> Ans: Acknowledged, i will consider how to optimize them in the future.
It is not about optimization. Hiding a return statement in a macro is
very bad style. It will lead to locking bugs, and resource leaks,
because nobody knows the return is there.
> >> +/*
> >> + * Macro Definition
> >> + */
> >> +#ifndef NULL
> >> +#define NULL 0
> >> +#endif
> >> +
> >> +#ifndef FALSE
> >> +#define FALSE 0
> >> +#endif
> >> +
> >> +#ifndef TRUE
> >> +#define TRUE 1
> >> +#endif
> >
> > Nonsense.
>
> Ans: Acknowledge, will be fixed later.
No. They will be fixed now.
> >> + /* Print chipid here since we are interested in lower 16 bits */
> >> + dev_info(dev,
> >> + "Motorcomm %s ethernet switch.\n",
> >> + info->name);
> >
> > Stop copy-n-paste.
>
> Ans: Sry for this, i will recheck the code to make sure each line of comments and code
> meaningful again.
Also, consider the comments. Do the comments add anything useful which
is not already obvious from the code. Comments should be about "Why?".
> >> --- a/include/uapi/linux/if_ether.h
> >> +++ b/include/uapi/linux/if_ether.h
> >> @@ -118,7 +118,7 @@
> >> #define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
> >> #define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
> >> #define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
> >> -#define ETH_P_YT921X 0x9988 /* Motorcomm YT921x DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
> >> +#define ETH_P_YT92XX 0x9988 /* Motorcomm YT92xx DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
> >> #define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
> >> #define ETH_P_DSA_8021Q 0xDADB /* Fake VLAN Header for DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
> >> #define ETH_P_DSA_A5PSW 0xE001 /* A5PSW Tag Value [ NOT AN OFFICIALLY REGISTERED ID ] */
> >
> > UAPI stands for User-space API. Do not change it unless there is a
> > very very good reason.
> >
>
> Ans: The default tpid both yt921x and yt922x is 0x9988. I have modified this to
> allow for simultaneous use in both yt922x and yt921x scenarios.
As pointed out, this is UAPI. Any changes to this file need a good
explanation how it does not change the user API. Do this break
backwards compatibility with user space applications? Maybe tcpdump or
wireshark has a dissector which expects ETH_P_YT921X and you have just
broken it?
> >> +#define YT922X_TAG_FORMAT2_NAME "yt922x-8b"
> >> +#define YT922X_FORMAT2_TAG_LEN 8
> >> +#define YT922X_PKT_TYPE GENMASK(15, 14)
> >> +#define YT922X_8B_CPUTAG_PKT_FROM_CPU 0x1
> >> +#define YT922X_8B_CPUTAG_SRC_PORT GENMASK(6, 2)
> >> +#define YT922X_8B_CPUTAG_DST_PORTMASK GENMASK(8, 0)
> >> +#define YT922X_8B_CPUTAG_DST_PORTMASK_0 BIT(15)
> >> +#define YT922X_8B_CPUTAG_DST_PORTMASK_0_EN 0x1
> >> +#define YT922X_8B_CPUTAG_FORCE_DST BIT(9)
> >> +#define YT922X_8B_CPUTAG_FORCE_DST_EN 0x1
> >
> > If yt922x tag format shares no common with yt921x, make a new tag driver.
>
> Ans: thank you for your suggestion, we will consider whether to create a new driver in the new file.
When you look at other tag drivers, you will also notice some drivers
implement two taggers in one file. So consider this if there is any
shared code.
> >> +static struct dsa_tag_driver *dsa_tag_driver_array[] = {
> >> + &DSA_TAG_DRIVER_NAME(yt921x_netdev_ops),
> >> + &DSA_TAG_DRIVER_NAME(yt922x_4b_netdev_ops),
> >> + &DSA_TAG_DRIVER_NAME(yt922x_8b_netdev_ops),
> >> +};
> >
> > If both are supported by the chip and 4b does nothing more than 8b
> > does, do not bother with it.
>
> Ans: 4b and 8b dsa tag may have different application scenarios. from my opinion,
> 1. 4b dsa tag can save 4 bytes of payload
> 2. 8b dsa tag carry more package info.
How do you plan to swap between the different formats?
The user perspective is that the machine has a collection of interface
which are used just as normal, using Linux tools likes like
iproute2. If the user enables a feature which requires the 8b tag
format, will you change the format from the DSA driver? And swap back
to the 4 byte format when the feature is no longer needed?
Andrew
^ permalink raw reply
* Re: [PATCH bpf-next v2 1/4] bpf: Initialize the l3mdev field for the fib lookup flow
From: Toke Høiland-Jørgensen @ 2026-06-17 9:06 UTC (permalink / raw)
To: Avinash Duduskar, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko
Cc: Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis,
John Fastabend, Stanislav Fomichev, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, David Ahern,
Shuah Khan, Jesper Dangaard Brouer, Mykyta Yatsenko, Leon Hwang,
KP Singh, Anton Protopopov, Amery Hung, Eyal Birger, Rong Tao,
bpf, netdev, linux-kselftest, linux-kernel
In-Reply-To: <20260616223426.3568080-2-avinash.duduskar@gmail.com>
> The helper already initializes the other flow fields the rules path
> consumes (flowi4_mark, flowi4_tun_key.tun_id, flowi4_uid and the v6
> counterparts); flowi*_l3mdev was added to that set afterwards and this
> helper was never updated to match. ip_route_input_slow() likewise zeroes
> the field before its input lookup. Do the same here.
So how about we explicitly zero-init the whole struct instead of adding
more fields ad-hoc like this? Otherwise this seems like something that
is likely to happen again if we ever add another field to the struct?
-Toke
^ permalink raw reply
* [PATCH net-next] net: airoha: Make use of the helper function dev_err_probe()
From: Lei Zhu @ 2026-06-17 9:03 UTC (permalink / raw)
To: lorenzo, andrew+netdev, davem, edumazet, kuba, pabeni; +Cc: netdev, zhulei_szu
From: Lei Zhu <zhulei@kylinos.cn>
Use dev_err_probe() to reduce code size and simplify the code.
Signed-off-by: Lei Zhu <zhulei@kylinos.cn>
---
drivers/net/ethernet/airoha/airoha_eth.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 31cdb11cd78d..189f64e83a46 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -3071,10 +3071,9 @@ static int airoha_probe(struct platform_device *pdev)
eth->dev = &pdev->dev;
err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32));
- if (err) {
- dev_err(eth->dev, "failed configuring DMA mask\n");
- return err;
- }
+ if (err)
+ return dev_err_probe(eth->dev, err,
+ "failed configuring DMA mask\n");
eth->fe_regs = devm_platform_ioremap_resource_byname(pdev, "fe");
if (IS_ERR(eth->fe_regs))
@@ -3087,10 +3086,9 @@ static int airoha_probe(struct platform_device *pdev)
err = devm_reset_control_bulk_get_exclusive(eth->dev,
ARRAY_SIZE(eth->rsts),
eth->rsts);
- if (err) {
- dev_err(eth->dev, "failed to get bulk reset lines\n");
- return err;
- }
+ if (err)
+ return dev_err_probe(eth->dev, err,
+ "failed to get bulk reset lines\n");
xsi_rsts = devm_kcalloc(eth->dev,
eth->soc->num_xsi_rsts, sizeof(*xsi_rsts),
@@ -3105,10 +3103,9 @@ static int airoha_probe(struct platform_device *pdev)
err = devm_reset_control_bulk_get_exclusive(eth->dev,
eth->soc->num_xsi_rsts,
eth->xsi_rsts);
- if (err) {
- dev_err(eth->dev, "failed to get bulk xsi reset lines\n");
- return err;
- }
+ if (err)
+ return dev_err_probe(eth->dev, err,
+ "failed to get bulk xsi reset lines\n");
eth->napi_dev = alloc_netdev_dummy(0);
if (!eth->napi_dev)
--
2.25.1
^ permalink raw reply related
* Re: [Intel-wired-lan] [PATCH iwl-next v1] ixgbe: Implement PCI reset handler
From: Paul Menzel @ 2026-06-17 9:03 UTC (permalink / raw)
To: Sergey Temerkhanov
Cc: intel-wired-lan, netdev, Aleksandr Loktionov, Bjorn Helgaas,
linux-pci
In-Reply-To: <20260617084329.199110-1-sergey.temerkhanov@intel.com>
[Cc: +Aleksandr (as in Reviewed-by:), +PCI subsystem]
Dear Sergey,
Thank you for your patch.
Am 17.06.26 um 10:43 schrieb Sergey Temerkhanov:
> Implement PCI device reset handler to allow the network device to
> get re-initialized and function after a PCI-level reset.
Please describe the problem in more detail. When does PCI-level reset
occur, and what is the current problematic situation?
Also, what is ixgbe specific compared to a general PCIe implementation?
Please share details how to test it, and how you tested it.
> Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 72 +++++++++++++++++++
> 2 files changed, 73 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> index 594ccb28da20..c4b0c5bb89c6 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> @@ -912,6 +912,7 @@ enum ixgbe_state_t {
> __IXGBE_PTP_TX_IN_PROGRESS,
> __IXGBE_RESET_REQUESTED,
> __IXGBE_PHY_INIT_COMPLETE,
> + __IXGBE_PCIE_RESET_IN_PROGRESS,
> };
>
> struct ixgbe_cb {
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 2ac274c73d61..a61ee5fff7be 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -12352,6 +12352,76 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
> return result;
> }
>
> +#define IXGBE_PCIE_RESET_RETRIES 1000
Why 1000? Isn’t there a generic PCIe macro? Please extend the commit
message.
> +
> +/**
> + * ixgbe_reset_prep - called before the pci bus is reset.
> + * @pdev: Pointer to PCI device
> + *
> + * Prepare the card for a reset, preventing the service task from running.
> + */
> +static void ixgbe_reset_prep(struct pci_dev *pdev)
> +{
> + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
> + unsigned int timeout = IXGBE_PCIE_RESET_RETRIES;
> +
> + if (!adapter)
> + return;
> +
> + /* Prevent the service task from being requeued in the timer callback
> + * while we're resetting.
> + */
> + if (test_bit(__IXGBE_SERVICE_INITED, &adapter->state)) {
> + timer_delete_sync(&adapter->service_timer);
> + /* Prevent the service task from running while we're resetting. */
One of the two comments seems redundant.
> + cancel_work_sync(&adapter->service_task);
> + }
> +
> + pci_clear_master(pdev);
> +
> + while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state) && --timeout)
> + usleep_range(1000, 2000);
> +
> + if (!timeout) {
> + e_err(drv, "Timed out waiting for __IXGBE_RESETTING to be released. Reset is needed\n");
> + pci_set_master(pdev);
> + return;
> + }
> +
> + set_bit(__IXGBE_PCIE_RESET_IN_PROGRESS, &adapter->state);
> + smp_mb__after_atomic();
> +}
> +
> +/**
> + * ixgbe_reset_done - called after the pci bus has been reset.
> + * @pdev: Pointer to PCI device
> + *
> + * Allow the service task to run and schedule re-initialization.
> + */
> +static void ixgbe_reset_done(struct pci_dev *pdev)
> +{
> + struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
> +
> + smp_mb__before_atomic();
> + if (!test_and_clear_bit(__IXGBE_PCIE_RESET_IN_PROGRESS, &adapter->state)) {
> + e_err(drv, "Reset done called without PCIe reset in progress\n");
How can this happen? What should the user reading this error do?
> + return;
> + }
> +
> + /* Allow the service task to run */
> + if (!test_bit(__IXGBE_REMOVING, &adapter->state)) {
> + clear_bit(__IXGBE_RESETTING, &adapter->state);
> + smp_mb__after_atomic();
> + }
> +
> + /* Schedule re-initialization */
> + if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
> + set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
> + if (test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
> + mod_timer(&adapter->service_timer, jiffies + 1);
> + }
> +}
> +
> /**
> * ixgbe_io_resume - called when traffic can start flowing again.
> * @pdev: Pointer to PCI device
> @@ -12384,6 +12454,8 @@ static const struct pci_error_handlers ixgbe_err_handler = {
> .error_detected = ixgbe_io_error_detected,
> .slot_reset = ixgbe_io_slot_reset,
> .resume = ixgbe_io_resume,
> + .reset_prepare = ixgbe_reset_prep,
> + .reset_done = ixgbe_reset_done,
> };
>
> static DEFINE_SIMPLE_DEV_PM_OPS(ixgbe_pm_ops, ixgbe_suspend, ixgbe_resume);
Kind regards,
Paul
^ permalink raw reply
* Re: [PATCH net v3] rtase: Workaround for TX hang caused by short UDP packets entering hardware PTP parsing
From: Simon Horman @ 2026-06-17 8:59 UTC (permalink / raw)
To: justinlai0215
Cc: Simon Horman, kuba, davem, edumazet, pabeni, andrew+netdev,
linux-kernel, netdev, stable, richardcochran, david.laight.linux,
aleksander.lobakin, pkshih, larry.chiu
In-Reply-To: <20260615131653.15730-1-justinlai0215@realtek.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
rtase: Workaround for TX hang caused by short UDP packets entering hardware PTP parsing
The patch adds a workaround for a hardware bug in rtase where short UDP
packets triggering PTP parsing can cause a TX hang due to out-of-bounds reads.
It pads affected packets so the transport data reaches a minimum length.
Cc: stable@vger.kernel.org
> diff --git a/drivers/net/ethernet/realtek/rtase/rtase_main.c b/drivers/net/ethernet/realtek/rtase/rtase_main.c
> index 55105d34bc797..4c295a39c7a0c 100644
> --- a/drivers/net/ethernet/realtek/rtase/rtase_main.c
> +++ b/drivers/net/ethernet/realtek/rtase/rtase_main.c
[ ... ]
> @@ -1249,6 +1250,81 @@ static u32 rtase_tx_csum(struct sk_buff *skb, const struct net_device *dev)
> return csum_cmd;
> }
>
> +static bool rtase_get_udp_offset(struct sk_buff *skb, u32 *udp_offset)
> +{
> + int no = skb_network_offset(skb);
> + struct ipv6hdr *i6h, _i6h;
> + struct iphdr *ih, _ih;
> +
> + switch (vlan_get_protocol(skb)) {
> + case htons(ETH_P_IP):
[Severity: High]
Does relying on vlan_get_protocol(skb) allow an unprivileged user to bypass
this workaround?
If an attacker uses an AF_PACKET/SOCK_RAW socket to inject a raw Ethernet
frame containing an IPv4/UDP packet, they could set skb->protocol to an
arbitrary value like htons(ETH_P_ALL). The switch statement will fall
through to the default case and return false, causing rtase_skb_pad() to
skip the padding.
Since the hardware independently parses the raw frame based on the EtherType,
could it still process the unpadded packet and trigger the TX hang?
> + ih = skb_header_pointer(skb, no, sizeof(_ih), &_ih);
> + if (!ih)
> + return false;
[ ... ]
> +static bool rtase_skb_pad(struct sk_buff *skb)
> +{
> + __be16 *dest, _dest;
> + u32 trans_data_len;
> + u32 udp_offset;
> + u16 dest_port;
> + u32 pad_len;
> +
> + if (!rtase_get_udp_offset(skb, &udp_offset))
> + return true;
> +
> + trans_data_len = skb->len - udp_offset;
> + if (trans_data_len < offsetof(struct udphdr, len) ||
> + trans_data_len >= RTASE_MIN_PAD_LEN)
> + return true;
[Severity: High]
Does this logic inadvertently skip padding for underflowed lengths and tiny
payloads?
If the IP header is malformed such that skb->len < udp_offset, the unsigned
subtraction for trans_data_len will underflow to a large positive value.
This causes trans_data_len >= RTASE_MIN_PAD_LEN to be true, bypassing the
padding.
Additionally, if the packet has fewer than 4 bytes of UDP payload, meaning
trans_data_len < offsetof(struct udphdr, len), it explicitly returns true.
Since the hardware blindly fetches the UDP destination port at
udp_offset + 2 via DMA, won't transmitting these short or malformed packets
without padding still expose the hardware to out-of-bounds reads?
> +
> + dest = skb_header_pointer(skb,
> + udp_offset + offsetof(struct udphdr, dest),
> + sizeof(_dest), &_dest);
[ ... ]
> @@ -1362,6 +1438,9 @@ static netdev_tx_t rtase_start_xmit(struct sk_buff *skb,
> opts2 |= rtase_tx_csum(skb, dev);
> }
>
> + if (!rtase_skb_pad(skb))
> + goto err_dma_0;
> +
> frags = rtase_xmit_frags(ring, skb, opts1, opts2);
> if (unlikely(frags < 0))
> goto err_dma_0;
[Severity: High]
This is a pre-existing issue, but does the err_dma_1 error path in
rtase_start_xmit() contain a double free of the skb?
When transmitting a fragmented packet, rtase_xmit_frags() maps the
fragments and assigns ring->skbuff[entry] = skb for the last fragment
descriptor. Back in rtase_start_xmit(), if dma_map_single() fails for the
linear part, it jumps to err_dma_1:
err_dma_1:
ring->skbuff[entry] = NULL;
rtase_tx_clear_range(ring, ring->cur_idx + 1, frags);
err_dma_0:
tp->stats.tx_dropped++;
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
rtase_tx_clear_range() iterates over the mapped fragments and calls
dev_kfree_skb_any() when it finds the skb pointer. Execution then falls
through to err_dma_0, which unconditionally calls dev_kfree_skb_any(skb) a
second time on the same skb pointer.
^ permalink raw reply
* Re: [PATCH net] net: airoha: Fix TX scheduler queue mask loop upper bound
From: Wayen Yan @ 2026-06-17 8:55 UTC (permalink / raw)
To: lorenzo; +Cc: netdev, nbd, linux-arm-kernel, linux-mediatek
In-Reply-To: <178166704952.2212140.11002626760717132754@gmail.com>
On Tue, Jun 17, 2026, Lorenzo Bianconi wrote:
> Even if the current codebase supports just AIROHA_NUM_QOS_CHANNEL (4), the hw
> exposes 32 hw QoS channels (AIROHA_NUM_TX_RING). Here we are just clearing the
> configuration, so I guess the current implementation is correct.
Hi Lorenzo,
You are right that there is no functional impact, and I agree this
should not go to net. Let me explain the register layout I was worried
about, and you can decide whether it is worth a net-next cleanup or
should just be dropped.
The two macros are:
REG_QUEUE_CLOSE_CFG(_n) = 0x00a0 + ((_n) & 0xfc)
TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) = BIT((_m) + (((_n) & 0x3) << 3))
REG_QUEUE_CLOSE_CFG() masks the channel with 0xfc, and the bit macro
folds the channel with & 0x3 (mod 4) shifted by 3. So one 32-bit
register holds 4 channels x 8 queues, 8 queue bits per channel:
channel 0 -> reg 0x00a0, bits 0..7
channel 1 -> reg 0x00a0, bits 8..15
channel 2 -> reg 0x00a0, bits 16..23
channel 3 -> reg 0x00a0, bits 24..31
channel 4 -> reg 0x00a4, bits 0..7
...
In airoha_qdma_set_chan_tx_sched() the loop variable 'i' is passed as
the *queue* argument _m, not as a channel:
for (i = 0; i < AIROHA_NUM_TX_RING; i++) // i = 0..31
airoha_qdma_clear(qdma, REG_QUEUE_CLOSE_CFG(channel),
TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
Since each channel only has AIROHA_NUM_QOS_QUEUES (8) queues, the correct
logic is to clear the 8 queue bits belonging to 'channel'. With i running
up to 31 the BIT() shift instead walks past those 8 bits and into the bit
ranges of the other channels folded into the same register. For channel 0
the accumulated mask becomes 0xffffffff, i.e. it touches channels 1..3 as
well.
This is harmless today only because REG_QUEUE_CLOSE_CFG is written
exclusively here, via airoha_qdma_clear() (RMW clear), and the register
resets to 0 and is never set anywhere -- so clearing extra bits is a
no-op. Functionally the current code is fine, as you say.
The point is just the loop-bound semantics: 'i' is a per-channel queue
index, so the bound should be AIROHA_NUM_QOS_QUEUES (8), not
AIROHA_NUM_TX_RING (32). The two happen to be related (32 == 4 channels *
8 queues) but mean different things.
Since there is no functional change, feel free to drop this if you would
rather not carry a cosmetic patch. If you think the clarity is worth it I
can resend against net-next without the Fixes tag.
Thanks,
Wayen
^ permalink raw reply
* Re: [PATCH net v3] rtase: Workaround for TX hang caused by short UDP packets entering hardware PTP parsing
From: Simon Horman @ 2026-06-17 8:54 UTC (permalink / raw)
To: justinlai0215
Cc: Simon Horman, kuba, davem, edumazet, pabeni, andrew+netdev,
linux-kernel, netdev, stable, richardcochran, david.laight.linux,
aleksander.lobakin, pkshih, larry.chiu
In-Reply-To: <20260615131653.15730-1-justinlai0215@realtek.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://netdev-ai.bots.linux.dev/sashiko/
---
rtase: Workaround for TX hang caused by short UDP packets entering hardware PTP parsing
This patch adds a workaround for a hardware TX hang that occurs when
short UDP packets matching destination ports 319/320 enter a PTP parsing
path that reads beyond the packet end. The workaround pads affected
packets so the transport data reaches RTASE_MIN_PAD_LEN before
transmission.
> diff --git a/drivers/net/ethernet/realtek/rtase/rtase_main.c b/drivers/net/ethernet/realtek/rtase/rtase_main.c
> index 55105d34bc79..4c295a39c7a0 100644
> --- a/drivers/net/ethernet/realtek/rtase/rtase_main.c
> +++ b/drivers/net/ethernet/realtek/rtase/rtase_main.c
[ ... ]
> +static bool rtase_get_udp_offset(struct sk_buff *skb, u32 *udp_offset)
> +{
> + int no = skb_network_offset(skb);
> + struct ipv6hdr *i6h, _i6h;
> + struct iphdr *ih, _ih;
> +
> + switch (vlan_get_protocol(skb)) {
> + case htons(ETH_P_IP):
> + ih = skb_header_pointer(skb, no, sizeof(_ih), &_ih);
> + if (!ih)
> + return false;
> +
> + if (ih->ihl < 5)
> + return false;
> +
> + if (ih->protocol != IPPROTO_UDP)
> + return false;
> +
> + *udp_offset = no + ih->ihl * 4;
[Low]
Should ih->ihl also be checked against the actual data present in the
skb? With ihl up to 15 (60 bytes), if the skb only contains the basic
20-byte IP header, the computed udp_offset can exceed skb->len.
Downstream in rtase_skb_pad():
trans_data_len = skb->len - udp_offset;
trans_data_len is u32, so when udp_offset > skb->len this underflows to
a very large value, which trivially satisfies:
trans_data_len >= RTASE_MIN_PAD_LEN
and rtase_skb_pad() silently skips the padding. A malformed packet from
an AF_PACKET sender with CAP_NET_RAW could craft a mismatched ihl and
bypass the workaround. Would clamping or validating udp_offset against
skb->len before the subtraction be appropriate?
> +
> + return true;
> + case htons(ETH_P_IPV6):
> + i6h = skb_header_pointer(skb, no, sizeof(_i6h), &_i6h);
> + if (!i6h)
> + return false;
> +
> + if (i6h->nexthdr != IPPROTO_UDP)
> + return false;
> +
> + *udp_offset = no + sizeof(*i6h);
> +
> + return true;
> + default:
> + return false;
> + }
> +}
> +
> +static bool rtase_skb_pad(struct sk_buff *skb)
> +{
> + __be16 *dest, _dest;
> + u32 trans_data_len;
> + u32 udp_offset;
> + u16 dest_port;
> + u32 pad_len;
> +
> + if (!rtase_get_udp_offset(skb, &udp_offset))
> + return true;
> +
> + trans_data_len = skb->len - udp_offset;
> + if (trans_data_len < offsetof(struct udphdr, len) ||
> + trans_data_len >= RTASE_MIN_PAD_LEN)
> + return true;
[Low]
When trans_data_len is less than offsetof(struct udphdr, len) (i.e., the
transport region is under 4 bytes), this returns true and skips the
padding entirely.
The commit message states the hardware "may access data beyond the end
of the packet" during PTP parsing. If the hardware also reads out of
bounds while classifying the packet, an IPv4 last fragment with 1-3
trailing bytes could still be misclassified as PTP based on whatever
garbage memory the hardware happens to read, and the workaround would
be bypassed.
The implicit assumption here seems to be "if the driver cannot read the
dest port from the skb, the hardware cannot classify it either", which
appears to contradict the premise that the hardware reads beyond the
packet boundary. Should these very short transport-data cases also be
padded to be safe?
> +
> + dest = skb_header_pointer(skb,
> + udp_offset + offsetof(struct udphdr, dest),
> + sizeof(_dest), &_dest);
[ ... ]
^ permalink raw reply
* RE: [PATCH net v2] tipc: fix use-after-free of the discoverer in tipc_disc_rcv()
From: Tung Quang Nguyen @ 2026-06-17 8:47 UTC (permalink / raw)
To: Weiming Shi
Cc: jmaloy@redhat.com, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, davem@davemloft.net,
xmei5@asu.edu, netdev@vger.kernel.org,
tipc-discussion@lists.sourceforge.net,
linux-kernel@vger.kernel.org
In-Reply-To: <20260616122246.3136462-2-bestswngs@gmail.com>
>Subject: [PATCH net v2] tipc: fix use-after-free of the discoverer in
>tipc_disc_rcv()
>
>bearer_disable() frees b->disc with tipc_disc_delete()'s plain kfree(), but
>tipc_disc_rcv() still dereferences b->disc in RX softirq under
>rcu_read_lock() (tipc_udp_recv -> tipc_rcv -> tipc_disc_rcv).
>
>L2 bearers are safe thanks to the synchronize_net() in tipc_disable_l2_media(),
>but the UDP bearer defers that call to the
>cleanup_bearer() workqueue, so the discoverer is freed with no grace
>period:
>
> BUG: KASAN: slab-use-after-free in tipc_disc_rcv (net/tipc/discover.c:149)
>Read of size 8 at addr ffff88802348b728 by task poc_tipc/184 <IRQ>
> tipc_disc_rcv (net/tipc/discover.c:149)
> tipc_rcv (net/tipc/node.c:2126)
> tipc_udp_recv (net/tipc/udp_media.c:391)
> udp_rcv (net/ipv4/udp.c:2643)
> ip_local_deliver_finish (net/ipv4/ip_input.c:241) </IRQ> Freed by task 181:
> kfree (mm/slub.c:6565)
> bearer_disable (net/tipc/bearer.c:418)
> tipc_nl_bearer_disable (net/tipc/bearer.c:1001)
>
>The bearer is freed with kfree_rcu(); free the discoverer the same way.
>Add an rcu_head to struct tipc_discoverer and free it and its skb from an RCU
>callback.
>
>Because the RCU callback (tipc_disc_free_rcu) lives in module text, a
>call_rcu() that is still pending when the tipc module is unloaded would invoke a
>freed function. Add an rcu_barrier() to tipc_exit() after the bearer subsystem
>has been torn down, so all pending discoverer callbacks have run before the
>module text goes away.
>
>Reachable from an unprivileged user namespace: the TIPCv2 genl family is
>netnsok and its bearer commands have no GENL_ADMIN_PERM. Needs
>CONFIG_TIPC and CONFIG_TIPC_MEDIA_UDP.
>
>Fixes: 25b0b9c4e835 ("tipc: handle collisions of 32-bit node address hash
>values")
>Reported-by: Xiang Mei <xmei5@asu.edu>
>Assisted-by: Claude:claude-opus-4-8
>Signed-off-by: Weiming Shi <bestswngs@gmail.com>
>---
>v2:
> - split the over-80-column container_of() line (Tung Quang Nguyen)
> - add rcu_barrier() to tipc_exit() so a pending call_rcu() cannot fire
> into freed module text after rmmod (Eric Dumazet)
>
> net/tipc/core.c | 3 +++
> net/tipc/discover.c | 14 ++++++++++++--
> 2 files changed, 15 insertions(+), 2 deletions(-)
>
>diff --git a/net/tipc/core.c b/net/tipc/core.c index
>434e70eabe08..747328e58d30 100644
>--- a/net/tipc/core.c
>+++ b/net/tipc/core.c
>@@ -218,6 +218,9 @@ static void __exit tipc_exit(void)
> unregister_pernet_device(&tipc_net_ops);
> tipc_unregister_sysctl();
>
>+ /* Wait for tipc_disc_free_rcu() callbacks queued from module text. */
Please change above comment to: /* TODO: Wait for all timers that called call_rcu() to finish before calling rcu_barrier() */
Note that call_rcu() are used in discover.c and node.c. So, the TODO comment helps we add more checking code later in another patch.
>+ rcu_barrier();
>+
> pr_info("Deactivated\n");
> }
>
>diff --git a/net/tipc/discover.c b/net/tipc/discover.c index
>3e54d2df5683..696b7a8ed54d 100644
>--- a/net/tipc/discover.c
>+++ b/net/tipc/discover.c
>@@ -58,6 +58,7 @@
> * @skb: request message to be (repeatedly) sent
> * @timer: timer governing period between requests
> * @timer_intv: current interval between requests (in ms)
>+ * @rcu: RCU head for deferred freeing
> */
> struct tipc_discoverer {
> u32 bearer_id;
>@@ -69,6 +70,7 @@ struct tipc_discoverer {
> struct sk_buff *skb;
> struct timer_list timer;
> unsigned long timer_intv;
>+ struct rcu_head rcu;
> };
>
> /**
>@@ -382,6 +384,15 @@ int tipc_disc_create(struct net *net, struct tipc_bearer
>*b,
> return 0;
> }
>
>+static void tipc_disc_free_rcu(struct rcu_head *rp) {
>+ struct tipc_discoverer *d =
>+ container_of(rp, struct tipc_discoverer, rcu);
>+
>+ kfree_skb(d->skb);
>+ kfree(d);
>+}
>+
> /**
> * tipc_disc_delete - destroy object sending periodic link setup requests
> * @d: ptr to link dest structure
>@@ -389,8 +400,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer
>*b, void tipc_disc_delete(struct tipc_discoverer *d) {
> timer_shutdown_sync(&d->timer);
>- kfree_skb(d->skb);
>- kfree(d);
>+ call_rcu(&d->rcu, tipc_disc_free_rcu);
> }
>
> /**
>--
>2.43.0
^ permalink raw reply
* Re: [PATCH net] ice: eswitch: fix use-after-free of metadata_dst in repr release
From: Simon Horman @ 2026-06-17 8:47 UTC (permalink / raw)
To: Doruk Tan Ozturk
Cc: anthony.l.nguyen, przemyslaw.kitszel, andrew+netdev, davem,
edumazet, kuba, pabeni, piotr.raczynski, michal.swiatkowski,
wojciech.drewek, intel-wired-lan, netdev, linux-kernel, stable
In-Reply-To: <20260615140532.52676-1-doruk@0sec.ai>
On Mon, Jun 15, 2026 at 04:05:32PM +0200, Doruk Tan Ozturk wrote:
> ice_eswitch_release_repr() frees the port representor metadata_dst via
> metadata_dst_free(), which directly kfree()s the object and ignores the
> dst_entry refcount. The eswitch slow-path TX routine
> ice_eswitch_port_start_xmit() takes a reference on this dst with
> dst_hold() and attaches it to the skb via skb_dst_set(). If such an skb
> is still in flight (e.g. queued in a qdisc) when the representor is torn
> down, the metadata_dst is freed while the skb still points at it. When
> the skb is later freed, dst_release() operates on already-freed memory.
>
> Replace metadata_dst_free() with dst_release() so the metadata_dst is
> freed only after the last reference is dropped. The dst subsystem frees
> metadata_dst objects from dst_destroy() once the refcount reaches zero
> (DST_METADATA is set by metadata_dst_alloc()).
>
> Same class of bug and fix as commit c32b26aaa2f9 ("netfilter:
> nft_tunnel: fix use-after-free on object destroy").
I think that the commit cited above moves the code in question around
but did not introduce the call to dst_release. And I think that this
bug goes back to when switchdev support was added.
I would suggest:
Fixes: 1a1c40df2e80 ("ice: set and release switchdev environment")
> Cc: stable@vger.kernel.org
> Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Otherwise, this looks good to me.
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply
* [PATCH iwl-next v1] ixgbe: Implement PCI reset handler
From: Sergey Temerkhanov @ 2026-06-17 8:43 UTC (permalink / raw)
To: intel-wired-lan; +Cc: netdev
Implement PCI device reset handler to allow the network device to
get re-initialized and function after a PCI-level reset.
Signed-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 72 +++++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 594ccb28da20..c4b0c5bb89c6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -912,6 +912,7 @@ enum ixgbe_state_t {
__IXGBE_PTP_TX_IN_PROGRESS,
__IXGBE_RESET_REQUESTED,
__IXGBE_PHY_INIT_COMPLETE,
+ __IXGBE_PCIE_RESET_IN_PROGRESS,
};
struct ixgbe_cb {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 2ac274c73d61..a61ee5fff7be 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -12352,6 +12352,76 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
return result;
}
+#define IXGBE_PCIE_RESET_RETRIES 1000
+
+/**
+ * ixgbe_reset_prep - called before the pci bus is reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Prepare the card for a reset, preventing the service task from running.
+ */
+static void ixgbe_reset_prep(struct pci_dev *pdev)
+{
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+ unsigned int timeout = IXGBE_PCIE_RESET_RETRIES;
+
+ if (!adapter)
+ return;
+
+ /* Prevent the service task from being requeued in the timer callback
+ * while we're resetting.
+ */
+ if (test_bit(__IXGBE_SERVICE_INITED, &adapter->state)) {
+ timer_delete_sync(&adapter->service_timer);
+ /* Prevent the service task from running while we're resetting. */
+ cancel_work_sync(&adapter->service_task);
+ }
+
+ pci_clear_master(pdev);
+
+ while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state) && --timeout)
+ usleep_range(1000, 2000);
+
+ if (!timeout) {
+ e_err(drv, "Timed out waiting for __IXGBE_RESETTING to be released. Reset is needed\n");
+ pci_set_master(pdev);
+ return;
+ }
+
+ set_bit(__IXGBE_PCIE_RESET_IN_PROGRESS, &adapter->state);
+ smp_mb__after_atomic();
+}
+
+/**
+ * ixgbe_reset_done - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Allow the service task to run and schedule re-initialization.
+ */
+static void ixgbe_reset_done(struct pci_dev *pdev)
+{
+ struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
+
+ smp_mb__before_atomic();
+ if (!test_and_clear_bit(__IXGBE_PCIE_RESET_IN_PROGRESS, &adapter->state)) {
+ e_err(drv, "Reset done called without PCIe reset in progress\n");
+ return;
+ }
+
+ /* Allow the service task to run */
+ if (!test_bit(__IXGBE_REMOVING, &adapter->state)) {
+ clear_bit(__IXGBE_RESETTING, &adapter->state);
+ smp_mb__after_atomic();
+ }
+
+ /* Schedule re-initialization */
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
+ if (test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
+ mod_timer(&adapter->service_timer, jiffies + 1);
+ }
+}
+
/**
* ixgbe_io_resume - called when traffic can start flowing again.
* @pdev: Pointer to PCI device
@@ -12384,6 +12454,8 @@ static const struct pci_error_handlers ixgbe_err_handler = {
.error_detected = ixgbe_io_error_detected,
.slot_reset = ixgbe_io_slot_reset,
.resume = ixgbe_io_resume,
+ .reset_prepare = ixgbe_reset_prep,
+ .reset_done = ixgbe_reset_done,
};
static DEFINE_SIMPLE_DEV_PM_OPS(ixgbe_pm_ops, ixgbe_suspend, ixgbe_resume);
base-commit: c50bfa9768ff3a5163746c6362a8a910a0b4dca0
--
2.53.0
^ permalink raw reply related
* Re: [GIT PULL] Networking for 7.2
From: pr-tracker-bot @ 2026-06-17 8:41 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: torvalds, kuba, davem, netdev, linux-kernel, pabeni
In-Reply-To: <20260617000705.931602-1-kuba@kernel.org>
The pull request you sent on Tue, 16 Jun 2026 17:07:05 -0700:
> git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git tags/net-next-7.2
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/b85966adbf5de0668a815c6e3527f87e0c387fb4
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [PATCH v18 net-next 01/11] net/nebula-matrix: add minimum nbl build framework
From: Uwe Kleine-König @ 2026-06-17 8:40 UTC (permalink / raw)
To: illusion.wang
Cc: dimon.zhao, alvin.wang, sam.chen, netdev, andrew+netdev, corbet,
kuba, horms, linux-doc, pabeni, vadim.fedorenko, lukas.bulwahn,
edumazet, enelsonmoore, skhan, hkallweit1, open list
In-Reply-To: <20260611044916.2383-2-illusion.wang@nebula-matrix.com>
[-- Attachment #1: Type: text/plain, Size: 3848 bytes --]
On Thu, Jun 11, 2026 at 12:49:00PM +0800, illusion.wang wrote:
> +static int nbl_probe(struct pci_dev *pdev,
> + const struct pci_device_id *id)
> +{
> + return 0;
> +}
> +
> +static void nbl_remove(struct pci_dev *pdev)
> +{
> +}
> [...]
> +static const struct pci_device_id nbl_id_table[] = {
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_LX),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_BASE_T),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_LX_BASE_T),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_OCP),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_LX_OCP),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_BASE_T_OCP),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_LX_BASE_T_OCP),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_LX),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_BASE_T),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_LX_BASE_T),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_OCP),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_LX_OCP),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_BASE_T_OCP),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_LX_BASE_T_OCP),
> + .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
> + BIT(NBL_CAP_IS_LEONIS_BIT) },
> + /* required as sentinel */
> + {
> + 0,
Please drop this zero. The most usual style is `{ }`.
> + }
> +};
> +MODULE_DEVICE_TABLE(pci, nbl_id_table);
> +
> +static struct pci_driver nbl_driver = {
> + .name = NBL_DRIVER_NAME,
> + .id_table = nbl_id_table,
> + .probe = nbl_probe,
> + .remove = nbl_remove,
> +};
The pci bus probe function has (pci_device_probe() ->
__pci_device_probe()):
int error = 0;
if (drv->probe) {
...
}
return error;
So given that the probe function does nothing apart from returning zero,
you can just drop .probe(). (There is an additional check against
.id_table, but I'm pretty sure that isn't relevant because
pci_bus_match() already makes sure that there is a match.) The same is
true for .remove().
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH net] net: rnpgbe: fix mailbox endianness handling
From: Dong Yibo @ 2026-06-17 8:35 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, vadim.fedorenko
Cc: netdev, linux-kernel, dong100, yaojun
Mailbox data is exchanged through 32-bit MMIO accesses but the
mailbox payload is defined using little-endian FW structures with
__le16 and __le32 fields.
The mailbox read/write helpers previously operated on raw u32
buffers without performing endian conversion. On big-endian
systems this causes mailbox payload fields to be byte-swapped in
memory, resulting in corrupted FW command and reply structures.
Convert mailbox data between CPU-endian MMIO values and the
little-endian mailbox wire format using cpu_to_le32() on reads and
le32_to_cpu() on writes.
Also switch the helper interfaces to use void */const void * since
the mailbox transport layer operates on opaque payload buffers
rather than native-endian u32 arrays.
Fixes: 4543534c3ef5 ("net: rnpgbe: Add basic mbx ops support")
Signed-off-by: Dong Yibo <dong100@mucse.com>
---
drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c | 16 ++++++++++------
drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h | 5 +++--
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c | 7 +++----
3 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c
index de5e29230b3c..0fccfc49ffc7 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c
@@ -166,10 +166,12 @@ static void mucse_mbx_inc_pf_ack(struct mucse_hw *hw)
*
* Return: 0 on success, negative errno on failure
**/
-static int mucse_read_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
+static int mucse_read_mbx_pf(struct mucse_hw *hw, void *msg, u16 size)
{
const int size_in_words = size / sizeof(u32);
struct mucse_mbx_info *mbx = &hw->mbx;
+ int off = MUCSE_MBX_FWPF_SHM;
+ __le32 *msg_le32 = msg;
int err;
err = mucse_obtain_mbx_lock_pf(hw);
@@ -177,7 +179,7 @@ static int mucse_read_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
return err;
for (int i = 0; i < size_in_words; i++)
- msg[i] = mbx_data_rd32(mbx, MUCSE_MBX_FWPF_SHM + 4 * i);
+ msg_le32[i] = cpu_to_le32(mbx_data_rd32(mbx, off + 4 * i));
/* Hw needs write data_reg at last */
mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM, 0);
/* flush reqs as we have read this request data */
@@ -236,7 +238,7 @@ static int mucse_poll_for_msg(struct mucse_hw *hw)
* Return: 0 if it successfully received a message notification and
* copied it into the receive buffer, negative errno on failure
**/
-int mucse_poll_and_read_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
+int mucse_poll_and_read_mbx(struct mucse_hw *hw, void *msg, u16 size)
{
int err;
@@ -290,10 +292,11 @@ static void mucse_mbx_inc_pf_req(struct mucse_hw *hw)
* Return: 0 if it successfully copied message into the buffer,
* negative errno on failure
**/
-static int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
+static int mucse_write_mbx_pf(struct mucse_hw *hw, const void *msg, u16 size)
{
const int size_in_words = size / sizeof(u32);
struct mucse_mbx_info *mbx = &hw->mbx;
+ const __le32 *msg_le32 = msg;
int err;
err = mucse_obtain_mbx_lock_pf(hw);
@@ -301,7 +304,8 @@ static int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
return err;
for (int i = 0; i < size_in_words; i++)
- mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM + i * 4, msg[i]);
+ mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM + i * 4,
+ le32_to_cpu(msg_le32[i]));
/* flush acks as we are overwriting the message buffer */
hw->mbx.fw_ack = mucse_mbx_get_fwack(mbx);
@@ -360,7 +364,7 @@ static int mucse_poll_for_ack(struct mucse_hw *hw)
* Return: 0 if it successfully copied message into the buffer and
* received an ack to that message within delay * timeout_cnt period
**/
-int mucse_write_and_wait_ack_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
+int mucse_write_and_wait_ack_mbx(struct mucse_hw *hw, const void *msg, u16 size)
{
int err;
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h
index e6fcc8d1d3ca..25bfc97c24c0 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h
@@ -14,7 +14,8 @@
#define MUCSE_MBX_REQ BIT(0) /* Request a req to mailbox */
#define MUCSE_MBX_PFU BIT(3) /* PF owns the mailbox buffer */
-int mucse_write_and_wait_ack_mbx(struct mucse_hw *hw, u32 *msg, u16 size);
+int mucse_write_and_wait_ack_mbx(struct mucse_hw *hw,
+ const void *msg, u16 size);
void mucse_init_mbx_params_pf(struct mucse_hw *hw);
-int mucse_poll_and_read_mbx(struct mucse_hw *hw, u32 *msg, u16 size);
+int mucse_poll_and_read_mbx(struct mucse_hw *hw, void *msg, u16 size);
#endif /* _RNPGBE_MBX_H */
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c
index 8c8bd5e8e1db..2ac97915a098 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c
@@ -28,12 +28,11 @@ static int mucse_fw_send_cmd_wait_resp(struct mucse_hw *hw,
int err;
mutex_lock(&hw->mbx.lock);
- err = mucse_write_and_wait_ack_mbx(hw, (u32 *)req, len);
+ err = mucse_write_and_wait_ack_mbx(hw, req, len);
if (err)
goto out;
do {
- err = mucse_poll_and_read_mbx(hw, (u32 *)reply,
- sizeof(*reply));
+ err = mucse_poll_and_read_mbx(hw, reply, sizeof(*reply));
if (err)
goto out;
/* mucse_write_and_wait_ack_mbx return 0 means fw has
@@ -125,7 +124,7 @@ int mucse_mbx_powerup(struct mucse_hw *hw, bool is_powerup)
len = le16_to_cpu(req.datalen);
mutex_lock(&hw->mbx.lock);
- err = mucse_write_and_wait_ack_mbx(hw, (u32 *)&req, len);
+ err = mucse_write_and_wait_ack_mbx(hw, &req, len);
mutex_unlock(&hw->mbx.lock);
return err;
--
2.25.1
^ permalink raw reply related
* Re: [PATCH net] ipv6: ndisc: fix NULL deref in accept_untracked_na()
From: Jiayuan Chen @ 2026-06-17 8:32 UTC (permalink / raw)
To: Weiming Shi, David S . Miller, David Ahern, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, linux-kernel, Xiang Mei
In-Reply-To: <20260617065512.2529757-2-bestswngs@gmail.com>
On 6/17/26 2:55 PM, Weiming Shi wrote:
> accept_untracked_na() re-fetches the inet6_dev with __in6_dev_get(dev)
> and dereferences idev->cnf.accept_untracked_na without a NULL check,
Does ipv6_rpl_srh_rcv have same problem?
^ 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