* [PATCH net-next 4/4] netem: add per-impairment extended statistics
From: Stephen Hemminger @ 2026-05-02 0:17 UTC (permalink / raw)
To: netdev
Cc: jhs, jiri, Stephen Hemminger, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, open list:TC subsystem,
open list
In-Reply-To: <20260502001844.19107-1-stephen@networkplumber.org>
Adds new counters that keep track of when netem applied
impairments (delay, loss, corruption, duplication, reordering).
Add a struct tc_netem_xstats reported via TCA_STATS_APP so that
userspace (tc -s qdisc show) can display per-impairment counters.
Use the WRITE_ONCE/READ_ONCE pattern to allow for lockless
qdisc usage.
Accompanying iproute2 change is submitted separately.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/uapi/linux/pkt_sched.h | 9 ++++++++
net/sched/sch_netem.c | 40 +++++++++++++++++++++++++++++++---
2 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index 66e8072f44df..1c84c8076e22 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -569,6 +569,15 @@ struct tc_netem_gemodel {
#define NETEM_DIST_SCALE 8192
#define NETEM_DIST_MAX 16384
+struct tc_netem_xstats {
+ __u64 delayed; /* packets delayed */
+ __u64 dropped; /* packets dropped by loss model */
+ __u64 corrupted; /* packets with bit errors injected */
+ __u64 duplicated; /* duplicate packets generated */
+ __u64 reordered; /* packets sent out of order */
+ __u64 ecn_marked; /* packets ECN CE-marked (not dropped)*/
+};
+
/* DRR */
enum {
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 116e96d79ddf..c871c7a3b117 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -152,6 +152,14 @@ struct netem_sched_data {
} slot;
struct disttable *slot_dist;
+
+ /* Per-impairment counters */
+ __u64 delayed;
+ __u64 dropped;
+ __u64 corrupted;
+ __u64 duplicated;
+ __u64 reordered;
+ __u64 ecn_marked;
};
/* Time stamp put into socket buffer control block
@@ -459,17 +467,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
skb->prev = NULL;
/* Random duplication */
- if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor, &q->prng))
+ if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor, &q->prng)) {
++count;
+ WRITE_ONCE(q->duplicated, q->duplicated + 1);
+ }
/* Drop packet? */
if (loss_event(q)) {
- if (q->ecn && INET_ECN_set_ce(skb))
+ if (q->ecn && INET_ECN_set_ce(skb)) {
qdisc_qstats_drop(sch); /* mark packet */
- else
+ WRITE_ONCE(q->ecn_marked, q->ecn_marked + 1);
+ } else {
--count;
+ }
}
+
if (count == 0) {
+ WRITE_ONCE(q->dropped, q->dropped + 1);
qdisc_qstats_drop(sch);
__qdisc_drop(skb, to_free);
return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
@@ -495,6 +509,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
* do it now in software before we mangle it.
*/
if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor, &q->prng)) {
+ WRITE_ONCE(q->corrupted, q->corrupted + 1);
if (skb_is_gso(skb)) {
skb = netem_segment(skb, sch, to_free);
if (!skb)
@@ -600,12 +615,15 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
cb->time_to_send = now + delay;
++q->counter;
+ WRITE_ONCE(q->delayed, q->delayed + 1);
+
tfifo_enqueue(skb, sch);
} else {
/*
* Do re-ordering by putting one out of N packets at the front
* of the queue.
*/
+ WRITE_ONCE(q->reordered, q->reordered + 1);
cb->time_to_send = ktime_get_ns();
q->counter = 0;
@@ -1344,6 +1362,21 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
return -1;
}
+static int netem_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
+{
+ struct netem_sched_data *q = qdisc_priv(sch);
+ struct tc_netem_xstats st = {
+ .delayed = READ_ONCE(q->delayed),
+ .dropped = READ_ONCE(q->dropped),
+ .corrupted = READ_ONCE(q->corrupted),
+ .duplicated = READ_ONCE(q->duplicated),
+ .reordered = READ_ONCE(q->reordered),
+ .ecn_marked = READ_ONCE(q->ecn_marked),
+ };
+
+ return gnet_stats_copy_app(d, &st, sizeof(st));
+}
+
static int netem_dump_class(struct Qdisc *sch, unsigned long cl,
struct sk_buff *skb, struct tcmsg *tcm)
{
@@ -1406,6 +1439,7 @@ static struct Qdisc_ops netem_qdisc_ops __read_mostly = {
.destroy = netem_destroy,
.change = netem_change,
.dump = netem_dump,
+ .dump_stats = netem_dump_stats,
.owner = THIS_MODULE,
};
MODULE_ALIAS_NET_SCH("netem");
--
2.53.0
^ permalink raw reply related
* Re: [PATCH net] ipv4: igmp: annotate data-races in igmp_heard_query()
From: patchwork-bot+netdevbpf @ 2026-05-02 0:20 UTC (permalink / raw)
To: Eric Dumazet
Cc: davem, kuba, pabeni, horms, idosch, dsahern, netdev, eric.dumazet,
syzbot+ae9a171f239b14485310
In-Reply-To: <20260430164836.872079-1-edumazet@google.com>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 30 Apr 2026 16:48:36 +0000 you wrote:
> Multiple cpus can run igmp_heard_query() concurrently.
>
> Add missing READ_ONCE()/WRITE_ONCE() over following in_dev fields.
>
> - mr_qrv
> - mr_qi
> - mr_qri
> - mr_v1_seen
> - mr_v2_seen
>
> [...]
Here is the summary with links:
- [net] ipv4: igmp: annotate data-races in igmp_heard_query()
https://git.kernel.org/netdev/net/c/c6bebaa744f7
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next] selftests: drv-net: Enable ntuple-filters if supported
From: patchwork-bot+netdevbpf @ 2026-05-02 0:20 UTC (permalink / raw)
To: Dimitri Daskalakis
Cc: davem, andrew+netdev, edumazet, kuba, pabeni, shuah, daskald, dw,
joe, dtatulea, vishs, asml.silence, horms, pavan.chebbi,
michael.chan, gal, linux-kselftest, netdev
In-Reply-To: <20260430165217.3700469-1-dimitri.daskalakis1@gmail.com>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 30 Apr 2026 09:52:17 -0700 you wrote:
> From: Dimitri Daskalakis <daskald@meta.com>
>
> Certain devices which support ntuple-filters do not enable the feature
> by default. The existing tests will skip (if they check for the feature),
> or fail if they blindly attempt to install rules. Therefore, attempt to turn
> on ntuple-filters if the device supports them.
>
> [...]
Here is the summary with links:
- [net-next] selftests: drv-net: Enable ntuple-filters if supported
https://git.kernel.org/netdev/net-next/c/c301658dfe08
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next] net: usb: cdc_ncm: add Apple Mac USB-C direct networking quirk
From: patchwork-bot+netdevbpf @ 2026-05-02 0:30 UTC (permalink / raw)
To: Alex Cheema
Cc: oliver, bjorn, oleavr, kuba, pabeni, davem, edumazet,
andrew+netdev, netdev, linux-usb, linux-kernel
In-Reply-To: <20260429175739.34426-1-alex@exolabs.net>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 29 Apr 2026 18:57:39 +0100 you wrote:
> Apple Silicon Macs expose two CDC NCM "private" data interfaces over
> USB-C with VID:PID 0x05ac:0x1905 and product string "Mac". This is the
> same protocol Apple already ships on iPhone (0x05ac:0x12a8) and iPad
> (0x05ac:0x12ab) for RemoteXPC since iOS 17 -- both data interfaces lack
> an interrupt status endpoint, so they rely on the FLAG_LINK_INTR-
> conditional bind path introduced in commit 3ec8d7572a69 ("CDC-NCM: add
> support for Apple's private interface").
>
> [...]
Here is the summary with links:
- [net-next] net: usb: cdc_ncm: add Apple Mac USB-C direct networking quirk
https://git.kernel.org/netdev/net/c/a5148bc2fa27
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next v6 1/3] selftests: net: py: support cmd verifying expected failure
From: Jakub Kicinski @ 2026-05-02 0:39 UTC (permalink / raw)
To: Willem de Bruijn
Cc: netdev, davem, edumazet, pabeni, horms, linux-kselftest, shuah,
Willem de Bruijn
In-Reply-To: <20260430132820.1944517-2-willemdebruijn.kernel@gmail.com>
On Thu, 30 Apr 2026 09:28:04 -0400 Willem de Bruijn wrote:
> From: Willem de Bruijn <willemb@google.com>
>
> Support negative tests, where cmd raises an exception if the command
> succeeded.
>
> Existing fail values are
>
> - True: Pass if returncode == 0, raise Exception otherwise
> - False: Pass unconditionally
> - None: True iff not terminated explicitly
>
> Introduce a variant of True that inverses the condition:
>
> - 'verify_failed': Pass if returncode != 0, raise Exception otherwise
>
> We cannot reuse False for this, because existing tests rely on current
> behavior to pass unconditionally.
>
> Only suppress regular test failure. Python subprocess may set a
> negative return code on process crash or timeout. Those are not
> anticipated failures.
The fact that subprocess sets retcode to negative on crash / timeout
may be worth a comment in the code. I didn't know that.
> diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
> index 6c44a3d2bbf7..ef31c0ba47fc 100644
> --- a/tools/testing/selftests/net/lib/py/utils.py
> +++ b/tools/testing/selftests/net/lib/py/utils.py
> @@ -111,10 +111,14 @@ class cmd:
>
> stdout, stderr = self._process_terminate(terminate=terminate,
> timeout=timeout)
> - if self.proc.returncode != 0 and fail:
> +
> + if (self.proc.returncode != 0 and fail and
> + (self.proc.returncode < 0 or fail != 'verify_failed')):
Personal preference but doesn't feel clean. I would have added
a dedicated argument for this. Up to you..
> if len(stderr) > 0 and stderr[-1] == "\n":
> stderr = stderr[:-1]
> raise CmdExitFailure("Command failed", self)
> + elif self.proc.returncode == 0 and fail == 'verify_failed':
> + raise CmdExitFailure("Command succeeded while should fail", self)
Can we create a new exception type? Just inherit CmdExitFailure
but name it more appropriately.
Regarding the message maybe: "Command succeeded (expected fail)" or
"Command succeeded (unexpectedly)"
^ permalink raw reply
* Re: [PATCH net-next v6 3/3] selftests: drv-net: convert so_txtime to drv-net
From: Jakub Kicinski @ 2026-05-02 0:45 UTC (permalink / raw)
To: Willem de Bruijn
Cc: netdev, davem, edumazet, pabeni, horms, linux-kselftest, shuah,
Willem de Bruijn
In-Reply-To: <20260430132820.1944517-4-willemdebruijn.kernel@gmail.com>
On Thu, 30 Apr 2026 09:28:06 -0400 Willem de Bruijn wrote:
> From: Willem de Bruijn <willemb@google.com>
>
> In preparation for extending to pacing hardware offload, convert the
> so_txtime.sh test to a drv-net test that can be run against netdevsim
> and real hardware.
>
> Also update so_txtime.c to not exit on first failure, but run to
> completion and report exit code there. This helps with debugging
> unexpected results, especially when processing multiple packets,
> as happens in the "reverse_order" testcase.
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
^ permalink raw reply
* Re: [PATCH net-next v7] net: mana: Expose hardware diagnostic info via debugfs
From: Jakub Kicinski @ 2026-05-02 0:54 UTC (permalink / raw)
To: ernis
Cc: Jakub Kicinski, kys, haiyangz, wei.liu, decui, longli,
andrew+netdev, davem, edumazet, pabeni, kotaranov, horms,
shradhagupta, dipayanroy, yury.norov, shirazsaleem, kees,
linux-hyperv, netdev, linux-kernel, linux-rdma
In-Reply-To: <20260430075342.1871554-1-ernis@linux.microsoft.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.
---
net: mana: Expose hardware diagnostic info via debugfs
This patch adds debugfs entries under /sys/kernel/debug/mana/<BDF>/ to
expose device-level and per-vPort hardware configuration and diagnostic
information. Debugfs creation and removal are moved into mana_gd_setup()
and a renamed mana_gd_cleanup_device() so probe, remove, suspend, resume
and shutdown share a single path.
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index a654b3699c4c..077d3a1ff6bf 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
[ ... ]
> @@ -3659,6 +3684,11 @@ int mana_probe(struct gdma_dev *gd, bool resuming)
>
> ac->bm_hostmode = bm_hostmode;
>
> + debugfs_create_u16("num_vports", 0400, gc->mana_pci_debugfs,
> + &ac->num_ports);
> + debugfs_create_u8("bm_hostmode", 0400, gc->mana_pci_debugfs,
> + &ac->bm_hostmode);
> +
> if (!resuming) {
> ac->num_ports = num_ports;
> } else {
Is the num_vports debugfs file pointed at ac->num_ports before that
field has been assigned from the queried num_ports value?
On a fresh probe (!resuming), the sequence in mana_probe() is:
err = mana_query_device_cfg(ac, ..., &num_ports, &bm_hostmode);
...
ac->bm_hostmode = bm_hostmode;
debugfs_create_u16("num_vports", 0400, gc->mana_pci_debugfs,
&ac->num_ports);
...
if (!resuming) {
ac->num_ports = num_ports;
} else {
...
}
...
if (ac->num_ports > MAX_PORTS_IN_MANA_DEV)
ac->num_ports = MAX_PORTS_IN_MANA_DEV;
During the window between debugfs_create_u16() and the assignment (and
subsequent clamp to MAX_PORTS_IN_MANA_DEV), would a reader of the
num_vports debugfs file observe 0 rather than the hardware-reported
value?
Would it be clearer to create this file after ac->num_ports has been
assigned and clamped, so the exposed value matches what the commit
message describes as "Device configuration"?
--
pw-bot: cr
^ permalink raw reply
* Re: [PATCH net] net/sched: sch_pie: annotate more data-races in pie_dump_stats()
From: patchwork-bot+netdevbpf @ 2026-05-02 1:00 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, kuba, pabeni, horms, jhs, jiri, netdev, eric.dumazet
In-Reply-To: <20260430080056.35104-1-edumazet@google.com>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 30 Apr 2026 08:00:56 +0000 you wrote:
> My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations.
>
> Fixes: 5154561d9b11 ("net/sched: sch_pie: annotate data-races in pie_dump_stats()")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> net/sched/sch_pie.c | 14 ++++++--------
> 1 file changed, 6 insertions(+), 8 deletions(-)
Here is the summary with links:
- [net] net/sched: sch_pie: annotate more data-races in pie_dump_stats()
https://git.kernel.org/netdev/net/c/6d4106e8df94
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next 0/5] tcp: move some fastpath fields to appropriate groups
From: patchwork-bot+netdevbpf @ 2026-05-02 1:00 UTC (permalink / raw)
To: Eric Dumazet
Cc: davem, kuba, pabeni, horms, ncardwell, kuniyu, netdev,
eric.dumazet
In-Reply-To: <20260430100021.211139-1-edumazet@google.com>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 30 Apr 2026 10:00:16 +0000 you wrote:
> Move following fields to better groups to increase data locality.
>
> - delivered
> - delivered_ce
> - segs_in
> - segs_out
> - first_tx_mstamp
> - delivered_mstamp
> - max_packets_out
> - cwnd_usage_seq
> - rate_delivered
> - rate_interval_us
>
> [...]
Here is the summary with links:
- [net-next,1/5] tcp: move tp->delivered and tp->delivered_ce to tcp_sock_write_tx group
https://git.kernel.org/netdev/net-next/c/9f810527a343
- [net-next,2/5] tcp: move tp->segs_in and tp->segs_out to tcp_sock_write_txrx group
https://git.kernel.org/netdev/net-next/c/2b28dd212a8a
- [net-next,3/5] tcp: move tp->first_tx_mstamp and tp->delivered_mstamp to tcp_sock_write_tx
https://git.kernel.org/netdev/net-next/c/07db42c4b3eb
- [net-next,4/5] tcp: move tp->bytes_acked to tcp_sock_write_tx group
https://git.kernel.org/netdev/net-next/c/dd033ec406b4
- [net-next,5/5] tcp: move max_packets_out, cwnd_usage_seq, rate_delivered and rate_interval_us to tcp_sock_write_tx group
https://git.kernel.org/netdev/net-next/c/affe6c27651a
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next] net: airoha: configure QoS channel for HW accelerated flowtable traffic
From: patchwork-bot+netdevbpf @ 2026-05-02 1:00 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms,
linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260430-airoha-ppe-qos-channel-v1-1-5ef9221e85c1@kernel.org>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 30 Apr 2026 10:47:38 +0200 you wrote:
> As done for the SW path, configure the QoS channel for HW accelerated
> traffic according to the user port index when forwarding to a DSA port,
> or rely on the GDM port identifier otherwise. This allows HTB shaping
> to be applied to HW accelerated traffic.
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
>
> [...]
Here is the summary with links:
- [net-next] net: airoha: configure QoS channel for HW accelerated flowtable traffic
https://git.kernel.org/netdev/net-next/c/286efd34d1a1
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next 1/3] net: Do not unconditionally turn on carrier when clearing protodown
From: Jakub Kicinski @ 2026-05-02 1:08 UTC (permalink / raw)
To: Ido Schimmel; +Cc: netdev, davem, pabeni, edumazet, andrew+netdev, horms, petrm
In-Reply-To: <20260429124624.835335-2-idosch@nvidia.com>
On Wed, 29 Apr 2026 15:46:22 +0300 Ido Schimmel wrote:
> Solve this by adding a new NDO that allows different drivers to react
> differently to protodown being cleared. Change the core to invoke the
> NDO and implement it for vxlan and macvlan. Maintain the current
> behavior for the former, but for macvlan implement the NDO by
> transferring the operational state from its lower device.
Maybe just me but an NDO for this seems like an overkill.
Isn't our range of options for the callback either follow
lower or carrier on? Do you expect more complex logic?
^ permalink raw reply
* Re: [PATCH net-next 2/3] macvlan: Do not transfer operational state when protodown is enabled
From: Jakub Kicinski @ 2026-05-02 1:09 UTC (permalink / raw)
To: Ido Schimmel; +Cc: netdev, davem, pabeni, edumazet, andrew+netdev, horms, petrm
In-Reply-To: <20260429124624.835335-3-idosch@nvidia.com>
On Wed, 29 Apr 2026 15:46:23 +0300 Ido Schimmel wrote:
> - list_for_each_entry(vlan, &port->vlans, list)
> + list_for_each_entry(vlan, &port->vlans, list) {
> + if (vlan->dev->proto_down)
> + continue;
> netif_stacked_transfer_operstate(vlan->lowerdev,
> vlan->dev);
Doesn't feel particularly macvlan-specific?
Other simple upper devs don't support protodown
but when they do presumably they'll have to add
this exact condition, too, so why not add it in
netif_stacked_transfer_operstate()?
^ permalink raw reply
* Re: [RFC PATCH 1/2] net: af_unix: Useful handling of LSM denials on SCM_RIGHTS
From: Kuniyuki Iwashima @ 2026-05-02 1:24 UTC (permalink / raw)
To: Jori Koolstra
Cc: Alexander Viro, Christian Brauner, Jan Kara, Eric Dumazet,
Paolo Abeni, Willem de Bruijn, David S . Miller, Jakub Kicinski,
Jens Axboe, Kees Cook, Simon Horman, Andy Lutomirski, Will Drewry,
Jeff Layton, Oleg Nesterov, Andrei Vagin, Pavel Tikhomirov,
Mateusz Guzik, Joel Granados, Charlie Mirabile, Aleksa Sarai,
linux-fsdevel, linux-kernel, netdev, io-uring
In-Reply-To: <89346381.2074764.1777649680664@kpc.webmail.kpnmail.nl>
On Fri, May 1, 2026 at 8:34 AM Jori Koolstra <jkoolstra@xs4all.nl> wrote:
>
>
> > Op 30-04-2026 04:04 CEST schreef Kuniyuki Iwashima <kuniyu@google.com>:
> >
> >
> > On Tue, Apr 28, 2026 at 10:51 AM Jori Koolstra <jkoolstra@xs4all.nl> wrote:
> > >
> > > Right now if some LSM such as Smack denies an AF_UNIX socket peer to
> > > receive an SCM_RIGHTS fd the SCM_RIGHTS fd array will be cut short at
> > > that point, and MSG_CTRUNC is set on return of recvmsg(). This is
> > > highly problematic behaviour, because it leaves the receiver
> > > wondering what happened. As per man page MSG_CTRUNC is supposed to
> > > indicate that the control buffer was sized too short, but suddenly
> > > a permission error might result in the exact same flag being set.
> > > Moreover, the receiver has no chance to determine how many fds got
> > > originally sent and how many were suppressed.[1]
> > >
> > > Add two MSG_* flags:
> >
> > Since we only have 5 bits remaining for future extension,
> > we need to consider the use case a bit more carefully.
> >
>
> Right. Since it wasn't a lot of work I implemented it exactly as the request
> was made from userspace, and then discuss it from there. By the way, I suppose
> nothing can be done about that small flag space?
We could reuse an existing flag (e.g. MSG_FIN, MSG_RST)
if we were confident enough that the userspace does not use
the flag for a specific socket type.
Another option is to add another syscall, recvmsg2.
>
> >
> > > - MSG_RIGHTS_DENIAL is set whenever any file is rejected by the LSM
> > > during recvmsg() of SCM_RIGHTS fds.
> >
> > Is this really needed ?
> >
> > Even if the fd array is truncated, the application will traverse
> > the array anyway since it has some fds already installed (to
> > clean up in case of MSG_CTRUNC ?).
> >
> > Then, it will find the -EPERM entry.
> >
> > I assume no one uses MSG_RIGHTS_DENIAL without
> > MSG_RIGHTS_FILTER.
> >
>
> I guess that is a fair assumption to make. We can certainly do without
> MSG_RIGHTS_DENIAL if saving flags is important. I also suggested that
> we may see whether we can make MSG_RIGHTS_FILTER the default behavior.
> In the mean time I've found grep.app, and it turns out the answer is no.
> Apparently almost no one checks even for the truncation flag (mostly 1 fd
> is passed and then it is check the cmsg lenght). But cpython has this for
> instance:
>
> /* Close all descriptors coming from SCM_RIGHTS, so they don't leak. */
> for (cmsgh = ((msg.msg_controllen > 0) ? CMSG_FIRSTHDR(&msg) : NULL);
> cmsgh != NULL; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) {
> cmsg_status = get_cmsg_data_len(&msg, cmsgh, &cmsgdatalen);
> if (cmsg_status < 0)
> break;
> if (cmsgh->cmsg_level == SOL_SOCKET &&
> cmsgh->cmsg_type == SCM_RIGHTS) {
> size_t numfds;
> int *fdp;
> numfds = cmsgdatalen / sizeof(int);
> fdp = (int *)CMSG_DATA(cmsgh);
> while (numfds-- > 0)
> close(*fdp++);
> }
> if (cmsg_status != 0)
> break;
> }
>
> >
> > > - If MSG_RIGHTS_FILTER is passed as a flag to recvmsg(), the SCM_RIGHTS
> >
> > Does this flag need per-recvmsg() granularity ?
> >
>
> Perhaps not. What would be the alternative? A fcntl option for the socket fd?
I'd add a new socket option like
setsockopt(SOL_SOCKET, SO_RIGHTS_TRUNC, &(int){0}, sizeof(int));
>
> > If the application does not welcome the truncated fd array,
> > it would have passed MSG_RIGHTS_FILTER to every
> > recvmsg(), no ?
> >
>
> Correct.
>
>
> Thanks,
> Jori.
^ permalink raw reply
* Re: [PATCH net v3] ipv6: validate extension header length before copying to cmsg
From: Qi Tang @ 2026-05-02 1:24 UTC (permalink / raw)
To: Paolo Abeni
Cc: David S . Miller, David Ahern, Eric Dumazet, Jakub Kicinski,
Simon Horman, netdev, linux-kernel, Qi Tang
In-Reply-To: <d0cc3e95-f03d-4bed-b18f-0517f56b8f05@redhat.com>
On Tue, Apr 28, 2026, Paolo Abeni <pabeni@redhat.com> wrote:
> > +static u16 ipv6_get_exthdr_len(const struct sk_buff *skb, const u8 *ptr)
> > +{
> > + u16 len = (ptr[1] + 1) << 3;
>
> Sashiko notes that you should validate even this offset (1) before
> accessing it.
Good catch. I will add a "ptr + 2 > skb_tail_pointer(skb)" check
before reading ptr[1], in both the helper and the inline AH path.
> You may also consider switching to pskb_may_pull().
I considered this but would prefer to keep skb_tail_pointer().
Two reasons:
1. ipv6_parse_hopopts() / dst_opts_rcv() / ipv6_rthdr_rcv() already
pskb_may_pull() the full extension header during input parsing,
so by the time ip6_datagram_recv_specific_ctl() runs the headers
are guaranteed to be in the linear area; another pskb_may_pull()
would be a no-op.
2. When pskb_may_pull() does have work to do, __pskb_pull_tail() can
call pskb_expand_head() and reallocate skb->head, which would
invalidate the caller's `ptr` (computed as nh + offset).
WDYT? Happy to switch if I'm missing something.
Thanks,
Qi
^ permalink raw reply
* Re: [PATCH 0/6] lib: rework bitreverse
From: Yury Norov @ 2026-05-02 1:40 UTC (permalink / raw)
To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Yury Norov, Rasmus Villemoes, Arnd Bergmann, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Morton, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev,
Jinjie Ruan, linux-kernel, linux-riscv, linux-arch, netdev, bpf
In-Reply-To: <20260430211351.658193-1-ynorov@nvidia.com>
On Thu, Apr 30, 2026 at 05:13:44PM -0400, Yury Norov wrote:
> This series is a resend for Jinjie Ruan's "arch/riscv: Add bitrev.h file
> to support rev8 and brev8" [1], my follow-up "lib: compile generic
> bitrev based on GENERIC_BITREVERSE" [2], and the fix for a build error
> reported by Nathan Chancellor [3].
>
> No changes, except for combining pieces together and rebasing on top of
> the tree.
>
> [1] https://lore.kernel.org/all/20260421130752.607500-1-ruanjinjie@huawei.com/
> [2] https://lore.kernel.org/all/20260427205210.397471-1-ynorov@nvidia.com/
> [3] https://lore.kernel.org/all/20260429202922.GA3575295@ax162/
>
> Build-tested against x86 tinyconfig and defconfig, having disabled and
> enabiled CRC32 and BITREVERSE, correspondingly.
I've got a feedback from sashiko bot.
1. We need to do #if IS_DEFINED(CONFIG_CRC32) instead of #ifdef,
because it may be a module.
2. Selecting GENERIC_BITREVERSE without BITREVERSE causes the unmet
direct dependency warning:
WARNING: unmet direct dependencies detected for GENERIC_BITREVERSE
Depends on [n]: BITREVERSE [=n]
Selected by [m]:
- MYCONFIG [=m]
I'll send a v2 to fix it
Thanks,
Yury
^ permalink raw reply
* Re: [PATCH] qed: fix division by zero in qed_init_wfq_param when all vports configured
From: Jakub Kicinski @ 2026-05-02 1:46 UTC (permalink / raw)
To: evg28bur
Cc: Jakub Kicinski, stable, gregkh, andrew+netdev, davem, edumazet,
pabeni, kees, horms, darinzon, bhelgaas, netdev, linux-kernel
In-Reply-To: <20260429151136.19308-1-evg28bur@yandex.ru>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
qed: fix division by zero in qed_init_wfq_param when all vports configured
This patch adds a guard for non_requested_count == 0 in qed_init_wfq_param()
to prevent a division-by-zero when every vport already has the configured
flag set, returning -EINVAL in that case.
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
> index 42c6dcfb1f0f..b287e04c8adc 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
> @@ -5105,6 +5105,13 @@ static int qed_init_wfq_param(struct qed_hwfn *p_hwfn,
>
> total_left_rate = min_pf_rate - total_req_min_rate;
>
> + if (non_requested_count == 0) {
> + DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
> + "All %d vports are already configured for WFQ, no unconfigured vports to distribute remaining bandwidth\n",
> + num_vports);
> + return -EINVAL;
> + }
> +
> left_rate_per_vp = total_left_rate / non_requested_count;
Is returning -EINVAL here the right behavior when non_requested_count
reaches zero, or does it turn a division-by-zero into a functional
regression in at least two reachable paths?
Path 1: qed_configure_vport_wfq() configuring the final vport.
Looking at the counting logic in qed_init_wfq_param():
for (i = 0; i < num_vports; i++) {
u32 tmp_speed;
if ((i != vport_id) &&
p_hwfn->qm_info.wfq_data[i].configured) {
req_count++;
...
}
}
/* Include current vport data as well */
req_count++;
total_req_min_rate += req_rate;
non_requested_count = num_vports - req_count;
When num_vports - 1 vports are already configured and the user is
explicitly configuring the last remaining one, the loop counts
num_vports - 1 configured vports (skipping vport_id), then the
unconditional req_count++ for the current vport makes req_count ==
num_vports, so non_requested_count == 0. With this patch the call
through qed_configure_vport_wfq() -> __qed_configure_vport_wfq() ->
qed_init_wfq_param() now rejects that operation with -EINVAL.
Path 2: __qed_configure_vp_wfq_on_link_change() with all vports
configured.
for (i = 0; i < p_hwfn->qm_info.num_vports; i++) {
...
if (!p_hwfn->qm_info.wfq_data[i].configured)
continue;
rate = p_hwfn->qm_info.wfq_data[i].min_speed;
use_wfq = true;
rc = qed_init_wfq_param(p_hwfn, i, rate, min_pf_rate);
if (rc) {
DP_NOTICE(p_hwfn,
"WFQ validation failed while configuring min rate\n");
break;
}
}
if (!rc && use_wfq)
qed_configure_wfq_for_all_vports(p_hwfn, p_ptt, min_pf_rate);
else
qed_disable_wfq_for_all_vports(p_hwfn, p_ptt, min_pf_rate);
If every vport has been configured, each iteration re-validates via
qed_init_wfq_param() and now hits the new -EINVAL return, so the loop
breaks, rc is non-zero, and the else branch calls
qed_disable_wfq_for_all_vports() on every link-state change.
Would it be more appropriate to skip just the division and the
subsequent percent-of-min_pf_rate check when non_requested_count is
zero, and then fall through to record wfq_data[vport_id] and return 0
(the final distribution loop is then naturally a no-op because every
vport hits the configured continue)?
One additional question on the commit metadata: the same function was
previously patched for an adjacent num_vports < 2 division-by-zero in
commit 1a9dc5610ef8 ("qed/qed_dev: guard against a possible division by
zero"), which carried a Fixes: bcd197c81f63 ("qed: Add vport WFQ
configuration APIs") tag. Since this patch closes a second
division-by-zero path in the same function with the same root cause,
would it be worth adding a matching Fixes: bcd197c81f63 tag so stable
backport tooling picks it up?
--
pw-bot: cr
^ permalink raw reply
* Re: [PATCH net v2 0/2] ipv6: fix ECMP route failover on carrier loss
From: patchwork-bot+netdevbpf @ 2026-05-02 1:50 UTC (permalink / raw)
To: Sagarika Sharma
Cc: davem, dsahern, edumazet, kuba, pabeni, shuah, horms, kuniyu,
netdev, linux-kselftest
In-Reply-To: <20260430200909.527827-1-sharmasagarika@google.com>
Hello:
This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 30 Apr 2026 20:08:59 +0000 you wrote:
> This patchset resolves an issue where established IPv6 connections are
> unable to transition to alternative ECMP nexthops upon carrier loss.
>
> Unlike IPv4, the IPv6 routing subsystem does not actively invalidate
> cached destinations during a NETDEV_CHANGE event. Sockets persist
> with dead routes, leading to stalled traffic or connection drops.
>
> [...]
Here is the summary with links:
- [net,v2,1/2] ipv6: update route serial number on NETDEV_CHANGE
https://git.kernel.org/netdev/net/c/4bc852006b62
- [net,v2,2/2] selftest: net: Add test for TCP flow failover with ECMP routes.
https://git.kernel.org/netdev/net/c/d1ae37dc6881
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net, v2] net: mana: Fix crash from unvalidated SHM offset read from BAR0 during FLR
From: Jakub Kicinski @ 2026-05-02 1:53 UTC (permalink / raw)
To: Dipayaan Roy
Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
pabeni, leon, longli, kotaranov, horms, shradhagupta, ssengar,
ernis, shirazsaleem, linux-hyperv, netdev, linux-kernel,
linux-rdma, stephen, jacob.e.keller, dipayanroy, leitao, kees,
john.fastabend, hawk, bpf, daniel, ast, sdf, yury.norov
In-Reply-To: <afJUszROT+yKjth0@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
On Wed, 29 Apr 2026 11:57:55 -0700 Dipayaan Roy wrote:
> During Function Level Reset recovery, the MANA driver reads
> hardware BAR0 registers that may temporarily contain garbage values.
> The SHM (Shared Memory) offset read from GDMA_REG_SHM_OFFSET is used
> to compute gc->shm_base, which is later dereferenced via readl() in
> mana_smc_poll_register(). If the hardware returns an unaligned or
> out-of-range value, the driver must not blindly use it, as this would
> propagate the hardware error into a kernel crash.
>
> The following crash was observed on an arm64 Hyper-V guest running
> kernel 6.17.0-3013-azure during VF reset recovery triggered by HWC
> timeout.
>
> [13291.785274] Unable to handle kernel paging request at virtual address ffff8000a200001b
> [13291.785311] Mem abort info:
> [13291.785332] ESR = 0x0000000096000021
> [13291.785343] EC = 0x25: DABT (current EL), IL = 32 bits
> [13291.785355] SET = 0, FnV = 0
> [13291.785363] EA = 0, S1PTW = 0
> [13291.785372] FSC = 0x21: alignment fault
> [13291.785382] Data abort info:
> [13291.785391] ISV = 0, ISS = 0x00000021, ISS2 = 0x00000000
> [13291.785404] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [13291.785412] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [13291.785421] swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000014df3a1000
> [13291.785432] [ffff8000a200001b] pgd=1000000100438403, p4d=1000000100438403, pud=1000000100439403, pmd=0068000fc2000711
> [13291.785703] Internal error: Oops: 0000000096000021 [#1] SMP
> [13291.830975] Modules linked in: tls qrtr mana_ib ib_uverbs ib_core xt_owner xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nft_compat nf_tables cfg80211 8021q garp mrp stp llc binfmt_misc joydev serio_raw nls_iso8859_1 hid_generic aes_ce_blk aes_ce_cipher polyval_ce ghash_ce sm4_ce_gcm sm4_ce_ccm sm4_ce sm4_ce_cipher hid_hyperv sm4 sm3_ce sha3_ce hv_netvsc hid vmgenid hyperv_keyboard hyperv_drm sch_fq_codel nvme_fabrics efi_pstore dm_multipath nfnetlink vsock_loopback vmw_vsock_virtio_transport_common hv_sock vmw_vsock_vmci_transport vmw_vmci vsock dmi_sysfs ip_tables x_tables autofs4
> [13291.862630] CPU: 122 UID: 0 PID: 61796 Comm: kworker/122:2 Tainted: G W 6.17.0-3013-azure #13-Ubuntu VOLUNTARY
> [13291.869902] Tainted: [W]=WARN
> [13291.871901] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 01/08/2026
> [13291.878086] Workqueue: events mana_serv_func
> [13291.880718] pstate: 62400005 (nZCv daif +PAN -UAO +TCO -DIT -SSBS BTYPE=--)
> [13291.884835] pc : mana_smc_poll_register+0x48/0xb0
> [13291.887902] lr : mana_smc_setup_hwc+0x70/0x1c0
> [13291.890493] sp : ffff8000ab79bbb0
> [13291.892364] x29: ffff8000ab79bbb0 x28: ffff00410c8b5900 x27: ffff00410d630680
> [13291.896252] x26: ffff004171f9fd80 x25: 000000016ed55000 x24: 000000017f37e000
> [13291.899990] x23: 0000000000000000 x22: 000000016ed55000 x21: 0000000000000000
> [13291.904497] x20: ffff8000a200001b x19: 0000000000004e20 x18: ffff8000a6183050
> [13291.908308] x17: 0000000000000000 x16: 0000000000000000 x15: 000000000000000a
> [13291.912542] x14: 0000000000000004 x13: 0000000000000000 x12: 0000000000000000
> [13291.916298] x11: 0000000000000000 x10: 0000000000000001 x9 : ffffc45006af1bd8
> [13291.920945] x8 : ffff000151129000 x7 : 0000000000000000 x6 : 0000000000000000
> [13291.925293] x5 : 000000015f214000 x4 : 000000017217a000 x3 : 000000016ed50000
> [13291.930436] x2 : 000000016ed55000 x1 : 0000000000000000 x0 : ffff8000a1ffffff
> [13291.934342] Call trace:
> [13291.935736] mana_smc_poll_register+0x48/0xb0 (P)
> [13291.938611] mana_smc_setup_hwc+0x70/0x1c0
> [13291.941113] mana_hwc_create_channel+0x1a0/0x3a0
> [13291.944283] mana_gd_setup+0x16c/0x398
> [13291.946584] mana_gd_resume+0x24/0x70
> [13291.948917] mana_do_service+0x13c/0x1d0
> [13291.951583] mana_serv_func+0x34/0x68
> [13291.953732] process_one_work+0x168/0x3d0
> [13291.956745] worker_thread+0x2ac/0x480
> [13291.959104] kthread+0xf8/0x110
> [13291.961026] ret_from_fork+0x10/0x20
> [13291.963560] Code: d2807d00 9417c551 71000673 54000220 (b9400281)
> [13291.967299] ---[ end trace 0000000000000000 ]---
>
> Disassembly of mana_smc_poll_register() around the crash site:
>
> Disassembly of section .text:
>
> 00000000000047c8 <mana_smc_poll_register>:
> 47c8: d503201f nop
> 47cc: d503201f nop
> 47d0: d503233f paciasp
> 47d4: f800865e str x30, [x18], #8
> 47d8: a9bd7bfd stp x29, x30, [sp, #-48]!
> 47dc: 910003fd mov x29, sp
> 47e0: a90153f3 stp x19, x20, [sp, #16]
> 47e4: 91007014 add x20, x0, #0x1c
> 47e8: 5289c413 mov w19, #0x4e20
> 47ec: f90013f5 str x21, [sp, #32]
> 47f0: 12001c35 and w21, w1, #0xff
> 47f4: 14000008 b 4814 <mana_smc_poll_register+0x4c>
> 47f8: 36f801e1 tbz w1, #31, 4834 <mana_smc_poll_register+0x6c>
> 47fc: 52800042 mov w2, #0x2
> 4800: d280fa01 mov x1, #0x7d0
> 4804: d2807d00 mov x0, #0x3e8
> 4808: 94000000 bl 0 <usleep_range_state>
> 480c: 71000673 subs w19, w19, #0x1
> 4810: 54000200 b.eq 4850 <mana_smc_poll_register+0x88>
> 4814: b9400281 ldr w1, [x20] <-- **** CRASHED HERE *****
> 4818: d50331bf dmb oshld
> 481c: 2a0103e2 mov w2, w1
> ...
>
> From the crash signature x20 = ffff8000a200001b, this address
> ends in 0x1b which is not 4-byte aligned, so the 'ldr w1, [x20]'
> instruction (readl) triggers the arm64 alignment fault (FSC = 0x21).
>
> The root cause is in mana_gd_init_vf_regs(), which computes:
>
> gc->shm_base = gc->bar0_va + mana_gd_r64(gc, GDMA_REG_SHM_OFFSET);
>
> The offset is used without any validation. The same problem exists
> in mana_gd_init_pf_regs() for sriov_base_off and sriov_shm_off.
>
> Fix this by validating all offsets before use:
>
> - VF: check shm_off is within BAR0, properly aligned to 4 bytes
> (readl requirement), and leaves room for the full 256-bit
> (32-byte) SMC aperture.
>
> - PF: check sriov_base_off is within BAR0, aligned to 8 bytes
> (readq requirement), and leaves room to safely read the
> sriov_shm_off register at sriov_base_off + GDMA_PF_REG_SHM_OFF.
> Then check sriov_shm_off leaves room for the full SMC aperture.
> All arithmetic uses subtraction rather than addition to avoid
> integer overflow on garbage firmware values.
>
> without validating the offset read from hardware. If the register
> returns a garbage value that is neither within bar 0 bounds nor aligned
> to the 4-byte granularity, thus causing the alignment fault.
>
> Define SMC_APERTURE_SIZE (32 bytes, derived from the 256-bit aperture
> width)
>
> Return -EPROTO on invalid values. The existing recovery path in
> mana_serv_reset() already handles -EPROTO by falling through to PCI
> device rescan, giving the hardware another chance to present valid
> register values after reset.
>
> Fixes: 9bf66036d686 ("net: mana: Handle hardware recovery events when probing the device")
> Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
>
> ---
> Changes in v2:
> - Fix sriov_base_off alignment check: sizeof(u32) to sizeof(u64), since
> mana_gd_r64() (readq) requires 8-byte alignment on arm64.
> - Fix sriov_base_off bounds: also verify enough space remains in BAR0
> to safely read sriov_shm_off at offset GDMA_PF_REG_SHM_OFF + 8 bytes.
> - Fix integer overflow: rewrite bounds checks using subtraction
> (remaining = bar0_size - base) instead of addition.
> - Fix SMC aperture size: add gc->bar0_size - shm_off < SMC_APERTURE_SIZE
> checks in both VF and PF paths; previously only the start address was
> validated, but mana_smc_poll_register() accesses up to shm_base + 0x1c
> (28 bytes from base, 32 bytes total).
> - Export SMC_APERTURE_SIZE to shm_channel.h.
> ---
> .../net/ethernet/microsoft/mana/gdma_main.c | 40 ++++++++++++++++---
> include/net/mana/shm_channel.h | 6 +++
> 2 files changed, 41 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> index 098fbda0d128..d8e816882f02 100644
> --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
> +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> @@ -43,8 +43,9 @@ static u64 mana_gd_r64(struct gdma_context *g, u64 offset)
> static int mana_gd_init_pf_regs(struct pci_dev *pdev)
> {
> struct gdma_context *gc = pci_get_drvdata(pdev);
> - void __iomem *sriov_base_va;
> + u64 remaining_barsize;
> u64 sriov_base_off;
> + u64 sriov_shm_off;
>
> gc->db_page_size = mana_gd_r32(gc, GDMA_PF_REG_DB_PAGE_SIZE) & 0xFFFF;
>
> @@ -73,10 +74,28 @@ static int mana_gd_init_pf_regs(struct pci_dev *pdev)
> gc->phys_db_page_base = gc->bar0_pa + gc->db_page_off;
>
> sriov_base_off = mana_gd_r64(gc, GDMA_SRIOV_REG_CFG_BASE_OFF);
> + if (sriov_base_off >= gc->bar0_size ||
> + gc->bar0_size - sriov_base_off <
> + GDMA_PF_REG_SHM_OFF + sizeof(u64) ||
nit: fits on a single line, I think?
> + !IS_ALIGNED(sriov_base_off, sizeof(u64))) {
> + dev_err(gc->dev,
> + "SRIOV base offset 0x%llx out of range or unaligned (BAR0 size 0x%llx)\n",
> + sriov_base_off, (u64)gc->bar0_size);
> + return -EPROTO;
> + }
>
> - sriov_base_va = gc->bar0_va + sriov_base_off;
> - gc->shm_base = sriov_base_va +
> - mana_gd_r64(gc, sriov_base_off + GDMA_PF_REG_SHM_OFF);
> + remaining_barsize = gc->bar0_size - sriov_base_off;
> + sriov_shm_off = mana_gd_r64(gc, sriov_base_off + GDMA_PF_REG_SHM_OFF);
> + if (sriov_shm_off >= remaining_barsize ||
> + remaining_barsize - sriov_shm_off < SMC_APERTURE_SIZE ||
> + !IS_ALIGNED(sriov_shm_off, sizeof(u32))) {
> + dev_err(gc->dev,
> + "SRIOV SHM offset 0x%llx out of range or unaligned (BAR0 size 0x%llx)\n",
> + sriov_shm_off, (u64)gc->bar0_size);
> + return -EPROTO;
> + }
> +
> + gc->shm_base = gc->bar0_va + sriov_base_off + sriov_shm_off;
>
> return 0;
> }
> @@ -84,6 +103,7 @@ static int mana_gd_init_pf_regs(struct pci_dev *pdev)
> static int mana_gd_init_vf_regs(struct pci_dev *pdev)
> {
> struct gdma_context *gc = pci_get_drvdata(pdev);
> + u64 shm_off;
>
> gc->db_page_size = mana_gd_r32(gc, GDMA_REG_DB_PAGE_SIZE) & 0xFFFF;
>
> @@ -111,7 +131,17 @@ static int mana_gd_init_vf_regs(struct pci_dev *pdev)
> gc->db_page_base = gc->bar0_va + gc->db_page_off;
> gc->phys_db_page_base = gc->bar0_pa + gc->db_page_off;
>
> - gc->shm_base = gc->bar0_va + mana_gd_r64(gc, GDMA_REG_SHM_OFFSET);
> + shm_off = mana_gd_r64(gc, GDMA_REG_SHM_OFFSET);
> + if (shm_off >= gc->bar0_size ||
> + gc->bar0_size - shm_off < SMC_APERTURE_SIZE ||
> + !IS_ALIGNED(shm_off, sizeof(u32))) {
> + dev_err(gc->dev,
> + "SHM offset 0x%llx out of range or unaligned (BAR0 size 0x%llx)\n",
> + shm_off, (u64)gc->bar0_size);
> + return -EPROTO;
> + }
> +
> + gc->shm_base = gc->bar0_va + shm_off;
>
> return 0;
> }
> diff --git a/include/net/mana/shm_channel.h b/include/net/mana/shm_channel.h
> index 5199b41497ff..dbabcfb95daf 100644
> --- a/include/net/mana/shm_channel.h
> +++ b/include/net/mana/shm_channel.h
> @@ -4,6 +4,12 @@
> #ifndef _SHM_CHANNEL_H
> #define _SHM_CHANNEL_H
>
> +#define SMC_APERTURE_BITS 256
> +#define SMC_BASIC_UNIT (sizeof(u32))
> +#define SMC_APERTURE_DWORDS (SMC_APERTURE_BITS / (SMC_BASIC_UNIT * 8))
> +#define SMC_LAST_DWORD (SMC_APERTURE_DWORDS - 1)
> +#define SMC_APERTURE_SIZE (SMC_APERTURE_BITS / 8)
AI bots complain that we're redefining this.
Since it's a fix I think it's better to remove the existing definition
even if it lives in a driver that goes via a different tree.
> struct shm_channel {
> struct device *dev;
> void __iomem *base;
--
pw-bot: cr
^ permalink raw reply
* Re: [PATCH net-next V2 0/3] net/mlx5: enable sub-page allocations for mlx5_frag_buf
From: patchwork-bot+netdevbpf @ 2026-05-02 2:20 UTC (permalink / raw)
To: Tariq Toukan
Cc: edumazet, kuba, pabeni, andrew+netdev, davem, saeedm, leon,
mbloch, netdev, linux-rdma, linux-kernel, gal, dtatulea, moshe
In-Reply-To: <20260429201429.223809-1-tariqt@nvidia.com>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 29 Apr 2026 23:14:26 +0300 you wrote:
> Hi,
>
> See detailed description by Nimrod below [1].
>
> Regards,
> Tariq
>
> [...]
Here is the summary with links:
- [net-next,V2,1/3] net/mlx5: wire frag buf pools lifecycle hooks
https://git.kernel.org/netdev/net-next/c/3796df7645e5
- [net-next,V2,2/3] net/mlx5: add frag buf pools create/destroy paths
https://git.kernel.org/netdev/net-next/c/3b16155425af
- [net-next,V2,3/3] net/mlx5: use internal dma pools for frag buf alloc
https://git.kernel.org/netdev/net-next/c/fbf6f64a4322
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next v2] pppoe: optimize hash with word access
From: patchwork-bot+netdevbpf @ 2026-05-02 2:20 UTC (permalink / raw)
To: Qingfang Deng
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, gnault, kees,
ericwouds, netdev, linux-kernel, linux-ppp
In-Reply-To: <20260429023848.153425-1-qingfang.deng@linux.dev>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 29 Apr 2026 10:38:46 +0800 you wrote:
> Currently, hash_item() processes the 6-byte Ethernet address and the
> 2-byte session ID byte-wise to compute a hash.
>
> Optimize this by using 16-bit word operations: XOR three 16-bit words
> from the Ethernet address and the 16-bit session ID, then fold the
> result. This reduces the total number of loads and XORs. The Ethernet
> addresses in a skb and struct pppoe_addr are both 2-byte aligned, so the
> u16 pointer cast is safe.
>
> [...]
Here is the summary with links:
- [net-next,v2] pppoe: optimize hash with word access
https://git.kernel.org/netdev/net-next/c/ff393252f99f
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v2] net: net_failover: Fix the deadlock in slave register
From: faicker mo @ 2026-05-02 2:46 UTC (permalink / raw)
To: Jakub Kicinski
Cc: horms, sridhar.samudrala, andrew+netdev, davem, edumazet, pabeni,
sdf, netdev, linux-kernel
In-Reply-To: <20260429011954.1519021-1-kuba@kernel.org>
>
> > @@ -512,11 +512,11 @@ static int net_failover_slave_register(struct net_device *slave_dev,
> > dev_hold(slave_dev);
> >
> > if (netif_running(failover_dev)) {
> > - err = dev_open(slave_dev, NULL);
> > + err = netif_open(slave_dev, NULL);
>
> Same question for this call. netif_open() -> __dev_open() also does
> netdev_ops_assert_locked(dev), and on the failover_existing_slave_register()
> path the slave's ops lock is not held.
Yes.
>
> Before this change, dev_set_mtu()/dev_open()/dev_close() acquired the ops
> lock internally via netdev_lock_ops(), so the pre-existing-slave path was
> covered. Does switching unconditionally to the non-locking variants
> regress that path for slaves whose drivers use the per-device ops lock,
> both as a lockdep splat when CONFIG_PROVE_LOCKING is set and as a loss of
> ops-lock serialization against concurrent ethtool, queue and netdev-genl
> operations on the slave?
>
> > @@ -562,10 +562,10 @@ static int net_failover_slave_register(struct net_device *slave_dev,
> > err_vlan_add:
> > dev_uc_unsync(slave_dev, failover_dev);
> > dev_mc_unsync(slave_dev, failover_dev);
> > - dev_close(slave_dev);
> > -err_dev_open:
> > + netif_close(slave_dev);
> > +err_netif_open:
> > dev_put(slave_dev);
> > - dev_set_mtu(slave_dev, orig_mtu);
> > + netif_set_mtu(slave_dev, orig_mtu);
>
> Would it be more appropriate to acquire netdev_lock_ops(slave_dev) in
> net_failover_slave_register() when the caller is not the NETDEV_REGISTER
> notifier (where the ops lock is already held), instead of dropping the
> locking unconditionally?
Yes, we should add netdev_lock_ops in failover_existing_slave_register
before calling failover_slave_register.
^ permalink raw reply
* [PATCH v1 net-next 00/15] udp_tunnel: Speed up UDP tunnel device destruction (Part I)
From: Kuniyuki Iwashima @ 2026-05-02 3:12 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Lunn
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
Most of the UDP tunnel devices call synchronize_rcu() twice
during destruction, for example, vxlan has
1) synchronize_rcu() in udp_tunnel_sock_release()
2) synchronize_net() in vxlan_sock_release()
The goal of this series is to remove the former, and another
followup series removes the latter.
synchronize_rcu() was added in udp_tunnel_sock_release() by
commit 3cf7203ca620 ("net/tunnel: wait until all sk_user_data
reader finish before releasing the sock").
This was intended to protect the fast path of a dying vxlan
from dereferencing vxlan_sock->sock->sk after sock_orphan()
has set sock->sk to NULL.
Most of the UDP tunnel devices store struct socket to its
private struct, but it is NOT needed in the fast paths;
struct sock is used there, but struct socket is only used
for tunnel setup / teardown.
This is probably because UDP tunnel functions accept struct
socket, but even such functions do not need it, except for
udp_tunnel_sock_release(), which can safely access sk->sk_socket.
The overview of the series:
Patch 1 - 5 : Convert UDP tunnel helper to take struct sock
Patch 6 : Small fix for 10-years-old bug
Patch 7 - 14 : Store struct sock in tunnel devices
Patch 15 : Remove synchronize_rcu() in udp_tunnel_sock_release()
(I noted bugs of fou and amt, so Sashiko may point out
such pre-existing issues in fou, amt, .. and pfcp and tipc,
but they are orthogonal and I can follow up separately.)
With this change, a script creating/upping vxlan in 4000 netns
runs 10x faster.
$ cat vxlan.sh
for i in `seq 1 40`
do
(for j in `seq 1 100` ; do
unshare -n bash -c "ip link add vxlan0 type vxlan id 100 local 127.0.0.1 dstport 4789 && ip link set vxlan0 up";
done) &
done
wait
With bpftrace, we can see vxlan_stop() is significantly faster too.
bpftrace -e '
kprobe:vxlan_stop {
@start[tid] = nsecs;
}
kretprobe:vxlan_stop /@start[tid]/ {
@duration_us = hist((nsecs - @start[tid]) / 1000);
delete(@start[tid]);
}
END {
printf("\nExecution time of vxlan_stop (us):\n");
}'
Before:
# time ./vxlan.sh // without bpftrace
real 0m50.615s
user 0m8.171s
sys 1m45.101s
@duration_us:
[4K, 8K) 1266 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
[8K, 16K) 1957 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[16K, 32K) 764 |@@@@@@@@@@@@@@@@@@@@ |
[32K, 64K) 6 | |
[64K, 128K) 4 | |
[128K, 256K) 3 | |
After:
# time ./vxlan.sh // without bpftrace
real 0m5.247s
user 0m7.956s
sys 1m47.404s
@duration_us:
[16, 32) 3411 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[32, 64) 383 |@@@@@ |
[64, 128) 107 |@ |
[128, 256) 79 |@ |
[256, 512) 16 | |
[512, 1K) 2 | |
[1K, 2K) 2 | |
Kuniyuki Iwashima (15):
udp_tunnel: Pass struct sock to udp_tunnel_sock_release().
udp_tunnel: Pass struct sock to setup_udp_tunnel_sock().
udp_tunnel: Pass struct sock to udp_tunnel6_dst_lookup().
udp_tunnel: Pass struct sock to udp_tunnel_{push,drop}_rx_port().
udp_tunnel: Pass struct sock to udp_tunnel_notify_{add,del}_rx_port().
vxlan: Fix potential null-ptr-deref in vxlan_gro_prepare_receive().
vxlan: Store struct sock in struct vxlan_sock.
vxlan: Free vxlan_sock with kfree_rcu().
geneve: Store struct sock in struct geneve_sock.
bareudp: Store struct sock in struct bareudp_dev.
fou: Store struct sock in struct fou.
amt: Store struct sock in struct amt_dev.
pfcp: Store struct sock in struct pfcp_dev.
tipc: Store struct sock in struct udp_bearer.
udp_tunnel: Remove synchronize_rcu() in udp_tunnel_sock_release().
drivers/infiniband/sw/rxe/rxe_net.c | 6 +--
drivers/infiniband/sw/rxe/rxe_ns.c | 4 +-
drivers/net/amt.c | 80 ++++++++++++++---------------
drivers/net/bareudp.c | 51 +++++++++---------
drivers/net/geneve.c | 54 +++++++++----------
drivers/net/gtp.c | 10 ++--
drivers/net/ovpn/udp.c | 2 +-
drivers/net/pfcp.c | 17 +++---
drivers/net/vxlan/vxlan_core.c | 60 ++++++++++++----------
drivers/net/vxlan/vxlan_multicast.c | 8 +--
drivers/net/wireguard/socket.c | 8 +--
include/net/amt.h | 2 +-
include/net/udp_tunnel.h | 14 ++---
include/net/vxlan.h | 5 +-
net/ipv4/fou_core.c | 21 ++++----
net/ipv4/udp_tunnel_core.c | 23 ++++-----
net/ipv6/ip6_udp_tunnel.c | 6 +--
net/l2tp/l2tp_core.c | 2 +-
net/rxrpc/local_object.c | 2 +-
net/sctp/protocol.c | 10 ++--
net/tipc/udp_media.c | 32 +++++++-----
21 files changed, 209 insertions(+), 208 deletions(-)
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply
* [PATCH v1 net-next 01/15] udp_tunnel: Pass struct sock to udp_tunnel_sock_release().
From: Kuniyuki Iwashima @ 2026-05-02 3:12 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Lunn
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
In-Reply-To: <20260502031401.3557229-1-kuniyu@google.com>
None of the udp_tunnel users need struct socket in their
fast paths; it is only used for tunnel setup / teardown.
While the UDP tunnel interface accepts struct socket, this
encourages users to store the pointer unnecessarily. This
leads to extra dereferences when accessing struct sock fields
(e.g., sk->sk_user_data instead of sock->sk->sk_user_data).
Furthermore, these dereferences necessitate synchronize_rcu()
in udp_tunnel_sock_release() to protect the fast paths from
sock_orphan() setting sk->sk_socket to NULL.
This overhead can be avoided if users store the struct sock
pointer directly in their private structures.
As a prep, let's change udp_tunnel_sock_release() to take
struct sock instead of struct socket.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
drivers/infiniband/sw/rxe/rxe_net.c | 4 ++--
drivers/infiniband/sw/rxe/rxe_ns.c | 4 ++--
drivers/net/amt.c | 2 +-
drivers/net/bareudp.c | 2 +-
drivers/net/geneve.c | 2 +-
drivers/net/gtp.c | 6 +++---
drivers/net/pfcp.c | 2 +-
drivers/net/vxlan/vxlan_core.c | 4 ++--
drivers/net/wireguard/socket.c | 4 ++--
include/net/udp_tunnel.h | 2 +-
net/ipv4/fou_core.c | 7 ++-----
net/ipv4/udp_tunnel_core.c | 6 ++++--
net/sctp/protocol.c | 6 +++---
net/tipc/udp_media.c | 4 ++--
14 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index 50a2cb5405e2..b454e4a17997 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -288,7 +288,7 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port,
return sock;
}
-static void rxe_release_udp_tunnel(struct socket *sk)
+static void rxe_release_udp_tunnel(struct sock *sk)
{
if (sk)
udp_tunnel_sock_release(sk);
@@ -636,7 +636,7 @@ static void rxe_sock_put(struct sock *sk,
if (refcount_read(&sk->sk_refcnt) > SK_REF_FOR_TUNNEL) {
__sock_put(sk);
} else {
- rxe_release_udp_tunnel(sk->sk_socket);
+ rxe_release_udp_tunnel(sk);
sk = NULL;
set_sk(net, sk);
}
diff --git a/drivers/infiniband/sw/rxe/rxe_ns.c b/drivers/infiniband/sw/rxe/rxe_ns.c
index 8b9d734229b2..64621c89f8bf 100644
--- a/drivers/infiniband/sw/rxe/rxe_ns.c
+++ b/drivers/infiniband/sw/rxe/rxe_ns.c
@@ -47,7 +47,7 @@ static void rxe_ns_exit(struct net *net)
rcu_read_unlock();
if (sk) {
rcu_assign_pointer(ns_sk->rxe_sk4, NULL);
- udp_tunnel_sock_release(sk->sk_socket);
+ udp_tunnel_sock_release(sk);
}
#if IS_ENABLED(CONFIG_IPV6)
@@ -56,7 +56,7 @@ static void rxe_ns_exit(struct net *net)
rcu_read_unlock();
if (sk) {
rcu_assign_pointer(ns_sk->rxe_sk6, NULL);
- udp_tunnel_sock_release(sk->sk_socket);
+ udp_tunnel_sock_release(sk);
}
#endif
}
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index f2f3139e38a5..fc415072864b 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -3032,7 +3032,7 @@ static int amt_dev_stop(struct net_device *dev)
RCU_INIT_POINTER(amt->sock, NULL);
synchronize_net();
if (sock)
- udp_tunnel_sock_release(sock);
+ udp_tunnel_sock_release(sock->sk);
cancel_work_sync(&amt->event_wq);
for (i = 0; i < AMT_MAX_EVENTS; i++) {
diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
index da5866ba0699..f3025a5c5261 100644
--- a/drivers/net/bareudp.c
+++ b/drivers/net/bareudp.c
@@ -290,7 +290,7 @@ static void bareudp_sock_release(struct bareudp_dev *bareudp)
sock = bareudp->sock;
rcu_assign_pointer(bareudp->sock, NULL);
synchronize_net();
- udp_tunnel_sock_release(sock);
+ udp_tunnel_sock_release(sock->sk);
}
static int bareudp_stop(struct net_device *dev)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index c6563367d382..8d55160305ee 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1018,7 +1018,7 @@ static void __geneve_sock_release(struct geneve_sock *gs)
list_del(&gs->list);
udp_tunnel_notify_del_rx_port(gs->sock, UDP_TUNNEL_TYPE_GENEVE);
- udp_tunnel_sock_release(gs->sock);
+ udp_tunnel_sock_release(gs->sock->sk);
kfree_rcu(gs, rcu);
}
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 5150f2e4f66b..064ce1029d33 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -885,8 +885,8 @@ static void gtp_encap_disable_sock(struct sock *sk)
static void gtp_encap_disable(struct gtp_dev *gtp)
{
if (gtp->sk_created) {
- udp_tunnel_sock_release(gtp->sk0->sk_socket);
- udp_tunnel_sock_release(gtp->sk1u->sk_socket);
+ udp_tunnel_sock_release(gtp->sk0);
+ udp_tunnel_sock_release(gtp->sk1u);
gtp->sk_created = false;
gtp->sk0 = NULL;
gtp->sk1u = NULL;
@@ -1451,7 +1451,7 @@ static int gtp_create_sockets(struct gtp_dev *gtp, const struct nlattr *nla,
sk1u = gtp_create_sock(UDP_ENCAP_GTP1U, gtp, nla, family);
if (IS_ERR(sk1u)) {
- udp_tunnel_sock_release(sk0->sk_socket);
+ udp_tunnel_sock_release(sk0);
return PTR_ERR(sk1u);
}
diff --git a/drivers/net/pfcp.c b/drivers/net/pfcp.c
index 28e6bc4a1f14..ce58038cfccb 100644
--- a/drivers/net/pfcp.c
+++ b/drivers/net/pfcp.c
@@ -104,7 +104,7 @@ static int pfcp_encap_recv(struct sock *sk, struct sk_buff *skb)
static void pfcp_del_sock(struct pfcp_dev *pfcp)
{
- udp_tunnel_sock_release(pfcp->sock);
+ udp_tunnel_sock_release(pfcp->sock->sk);
pfcp->sock = NULL;
}
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index e88798497503..1d1aba1c7cfc 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -1519,13 +1519,13 @@ static void vxlan_sock_release(struct vxlan_dev *vxlan)
vxlan_vs_del_dev(vxlan);
if (__vxlan_sock_release_prep(sock4)) {
- udp_tunnel_sock_release(sock4->sock);
+ udp_tunnel_sock_release(sock4->sock->sk);
kfree(sock4);
}
#if IS_ENABLED(CONFIG_IPV6)
if (__vxlan_sock_release_prep(sock6)) {
- udp_tunnel_sock_release(sock6->sock);
+ udp_tunnel_sock_release(sock6->sock->sk);
kfree(sock6);
}
#endif
diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c
index c362c78d908e..4a4c177af170 100644
--- a/drivers/net/wireguard/socket.c
+++ b/drivers/net/wireguard/socket.c
@@ -335,7 +335,7 @@ static void sock_free(struct sock *sock)
if (unlikely(!sock))
return;
sk_clear_memalloc(sock);
- udp_tunnel_sock_release(sock->sk_socket);
+ udp_tunnel_sock_release(sock);
}
static void set_sock_opts(struct socket *sock)
@@ -396,7 +396,7 @@ int wg_socket_init(struct wg_device *wg, u16 port)
port6.local_udp_port = inet_sk(new4->sk)->inet_sport;
ret = udp_sock_create(net, &port6, &new6);
if (ret < 0) {
- udp_tunnel_sock_release(new4);
+ udp_tunnel_sock_release(new4->sk);
if (ret == -EADDRINUSE && !port && retries++ < 100)
goto retry;
pr_err("%s: Could not create IPv6 socket\n",
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 47c23d4a1740..dbbd56280f50 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -176,7 +176,7 @@ static inline void udp_tunnel_set_inner_protocol(struct sk_buff *skb,
skb_set_inner_protocol(skb, inner_proto);
}
-void udp_tunnel_sock_release(struct socket *sock);
+void udp_tunnel_sock_release(struct sock *sk);
struct rtable *udp_tunnel_dst_lookup(struct sk_buff *skb,
struct net_device *dev,
diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c
index 5bae3cf7fe76..422f86291b42 100644
--- a/net/ipv4/fou_core.c
+++ b/net/ipv4/fou_core.c
@@ -558,11 +558,8 @@ static int fou_add_to_port_list(struct net *net, struct fou *fou,
static void fou_release(struct fou *fou)
{
- struct socket *sock = fou->sock;
-
list_del(&fou->list);
- udp_tunnel_sock_release(sock);
-
+ udp_tunnel_sock_release(fou->sock->sk);
kfree_rcu(fou, rcu);
}
@@ -634,7 +631,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
error:
kfree(fou);
if (sock)
- udp_tunnel_sock_release(sock);
+ udp_tunnel_sock_release(sock->sk);
return err;
}
diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
index b1f667c52cb2..1159a6a6fbb2 100644
--- a/net/ipv4/udp_tunnel_core.c
+++ b/net/ipv4/udp_tunnel_core.c
@@ -195,9 +195,11 @@ void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb
}
EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
-void udp_tunnel_sock_release(struct socket *sock)
+void udp_tunnel_sock_release(struct sock *sk)
{
- rcu_assign_sk_user_data(sock->sk, NULL);
+ struct socket *sock = sk->sk_socket;
+
+ rcu_assign_sk_user_data(sk, NULL);
synchronize_rcu();
kernel_sock_shutdown(sock, SHUT_RDWR);
sock_release(sock);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 5800e7ee7ea0..ffe594ad4414 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -878,7 +878,7 @@ int sctp_udp_sock_start(struct net *net)
err = udp_sock_create(net, &udp_conf, &sock);
if (err) {
pr_err("Failed to create the SCTP UDP tunneling v6 sock\n");
- udp_tunnel_sock_release(net->sctp.udp4_sock->sk_socket);
+ udp_tunnel_sock_release(net->sctp.udp4_sock);
net->sctp.udp4_sock = NULL;
return err;
}
@@ -896,11 +896,11 @@ int sctp_udp_sock_start(struct net *net)
void sctp_udp_sock_stop(struct net *net)
{
if (net->sctp.udp4_sock) {
- udp_tunnel_sock_release(net->sctp.udp4_sock->sk_socket);
+ udp_tunnel_sock_release(net->sctp.udp4_sock);
net->sctp.udp4_sock = NULL;
}
if (net->sctp.udp6_sock) {
- udp_tunnel_sock_release(net->sctp.udp6_sock->sk_socket);
+ udp_tunnel_sock_release(net->sctp.udp6_sock);
net->sctp.udp6_sock = NULL;
}
}
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 2c66b356025a..d7c050ff5804 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -793,7 +793,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
free:
dst_cache_destroy(&ub->rcast.dst_cache);
- udp_tunnel_sock_release(ub->ubsock);
+ udp_tunnel_sock_release(ub->ubsock->sk);
err:
kfree(ub);
return err;
@@ -815,7 +815,7 @@ static void cleanup_bearer(struct work_struct *work)
tn = tipc_net(sock_net(ub->ubsock->sk));
dst_cache_destroy(&ub->rcast.dst_cache);
- udp_tunnel_sock_release(ub->ubsock);
+ udp_tunnel_sock_release(ub->ubsock->sk);
/* Note: could use a call_rcu() to avoid another synchronize_net() */
synchronize_net();
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v1 net-next 02/15] udp_tunnel: Pass struct sock to setup_udp_tunnel_sock().
From: Kuniyuki Iwashima @ 2026-05-02 3:12 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Lunn
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
In-Reply-To: <20260502031401.3557229-1-kuniyu@google.com>
None of the udp_tunnel users need struct socket in their
fast paths; it is only used for tunnel setup / teardown.
Even setup_udp_tunnel_sock() does not need struct socket.
Let's change setup_udp_tunnel_sock() to take struct sock
instead of struct socket.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
drivers/infiniband/sw/rxe/rxe_net.c | 2 +-
drivers/net/amt.c | 2 +-
drivers/net/bareudp.c | 2 +-
drivers/net/geneve.c | 2 +-
drivers/net/gtp.c | 4 ++--
drivers/net/ovpn/udp.c | 2 +-
drivers/net/pfcp.c | 2 +-
drivers/net/vxlan/vxlan_core.c | 2 +-
drivers/net/wireguard/socket.c | 4 ++--
include/net/udp_tunnel.h | 2 +-
net/ipv4/fou_core.c | 2 +-
net/ipv4/udp_tunnel_core.c | 4 +---
net/l2tp/l2tp_core.c | 2 +-
net/rxrpc/local_object.c | 2 +-
net/sctp/protocol.c | 4 ++--
net/tipc/udp_media.c | 2 +-
16 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index b454e4a17997..082ff387d081 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -283,7 +283,7 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port,
tnl_cfg.encap_rcv = rxe_udp_encap_recv;
/* Setup UDP tunnel */
- setup_udp_tunnel_sock(net, sock, &tnl_cfg);
+ setup_udp_tunnel_sock(net, sock->sk, &tnl_cfg);
return sock;
}
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index fc415072864b..c03aa7c207e6 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -2979,7 +2979,7 @@ static int amt_socket_create(struct amt_dev *amt)
tunnel_cfg.encap_rcv = amt_rcv;
tunnel_cfg.encap_err_lookup = amt_err_lookup;
tunnel_cfg.encap_destroy = NULL;
- setup_udp_tunnel_sock(amt->net, sock, &tunnel_cfg);
+ setup_udp_tunnel_sock(amt->net, sock->sk, &tunnel_cfg);
rcu_assign_pointer(amt->sock, sock);
return 0;
diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
index f3025a5c5261..169ab90393cc 100644
--- a/drivers/net/bareudp.c
+++ b/drivers/net/bareudp.c
@@ -268,7 +268,7 @@ static int bareudp_socket_create(struct bareudp_dev *bareudp, __be16 port)
tunnel_cfg.encap_rcv = bareudp_udp_encap_recv;
tunnel_cfg.encap_err_lookup = bareudp_err_lookup;
tunnel_cfg.encap_destroy = NULL;
- setup_udp_tunnel_sock(bareudp->net, sock, &tunnel_cfg);
+ setup_udp_tunnel_sock(bareudp->net, sock->sk, &tunnel_cfg);
rcu_assign_pointer(bareudp->sock, sock);
return 0;
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 8d55160305ee..c3a7736cd6fc 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1006,7 +1006,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
tunnel_cfg.encap_rcv = geneve_udp_encap_recv;
tunnel_cfg.encap_err_lookup = geneve_udp_encap_err_lookup;
tunnel_cfg.encap_destroy = NULL;
- setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
+ setup_udp_tunnel_sock(net, sock->sk, &tunnel_cfg);
list_add(&gs->list, &gn->sock_list);
return gs;
}
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 064ce1029d33..a60ef32b35b8 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -1434,7 +1434,7 @@ static struct sock *gtp_create_sock(int type, struct gtp_dev *gtp,
tuncfg.encap_rcv = gtp_encap_recv;
tuncfg.encap_destroy = NULL;
- setup_udp_tunnel_sock(net, sock, &tuncfg);
+ setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
return sock->sk;
}
@@ -1689,7 +1689,7 @@ static struct sock *gtp_encap_enable_socket(int fd, int type,
tuncfg.encap_rcv = gtp_encap_recv;
tuncfg.encap_destroy = gtp_encap_destroy;
- setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg);
+ setup_udp_tunnel_sock(sock_net(sock->sk), sk, &tuncfg);
out_rel_sock:
release_sock(sock->sk);
diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c
index 059e896b4a2f..493a5a0744af 100644
--- a/drivers/net/ovpn/udp.c
+++ b/drivers/net/ovpn/udp.c
@@ -399,7 +399,7 @@ int ovpn_udp_socket_attach(struct ovpn_socket *ovpn_sock, struct socket *sock,
if (!old_data) {
/* socket is currently unused - we can take it */
rcu_read_unlock();
- setup_udp_tunnel_sock(sock_net(ovpn_sock->sk), sock, &cfg);
+ setup_udp_tunnel_sock(sock_net(ovpn_sock->sk), sock->sk, &cfg);
return 0;
}
diff --git a/drivers/net/pfcp.c b/drivers/net/pfcp.c
index ce58038cfccb..870137695e8a 100644
--- a/drivers/net/pfcp.c
+++ b/drivers/net/pfcp.c
@@ -172,7 +172,7 @@ static struct socket *pfcp_create_sock(struct pfcp_dev *pfcp)
tuncfg.encap_rcv = pfcp_encap_recv;
tuncfg.encap_type = 1;
- setup_udp_tunnel_sock(net, sock, &tuncfg);
+ setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
return sock;
}
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 1d1aba1c7cfc..394801c068b3 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -3620,7 +3620,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
tunnel_cfg.gro_complete = vxlan_gro_complete;
}
- setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
+ setup_udp_tunnel_sock(net, sock->sk, &tunnel_cfg);
return vs;
}
diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c
index 4a4c177af170..0028ef17dc71 100644
--- a/drivers/net/wireguard/socket.c
+++ b/drivers/net/wireguard/socket.c
@@ -389,7 +389,7 @@ int wg_socket_init(struct wg_device *wg, u16 port)
goto out;
}
set_sock_opts(new4);
- setup_udp_tunnel_sock(net, new4, &cfg);
+ setup_udp_tunnel_sock(net, new4->sk, &cfg);
#if IS_ENABLED(CONFIG_IPV6)
if (ipv6_mod_enabled()) {
@@ -404,7 +404,7 @@ int wg_socket_init(struct wg_device *wg, u16 port)
goto out;
}
set_sock_opts(new6);
- setup_udp_tunnel_sock(net, new6, &cfg);
+ setup_udp_tunnel_sock(net, new6->sk, &cfg);
}
#endif
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index dbbd56280f50..49324e28ec27 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -94,7 +94,7 @@ struct udp_tunnel_sock_cfg {
};
/* Setup the given (UDP) sock to receive UDP encapsulated packets */
-void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+void setup_udp_tunnel_sock(struct net *net, struct sock *sk,
struct udp_tunnel_sock_cfg *sock_cfg);
/* -- List of parsable UDP tunnel types --
diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c
index 422f86291b42..6bed0e1dbe0e 100644
--- a/net/ipv4/fou_core.c
+++ b/net/ipv4/fou_core.c
@@ -615,7 +615,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
goto error;
}
- setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
+ setup_udp_tunnel_sock(net, sk, &tunnel_cfg);
sk->sk_allocation = GFP_ATOMIC;
diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
index 1159a6a6fbb2..3090b4745d47 100644
--- a/net/ipv4/udp_tunnel_core.c
+++ b/net/ipv4/udp_tunnel_core.c
@@ -68,11 +68,9 @@ static bool sk_saddr_any(struct sock *sk)
#endif
}
-void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+void setup_udp_tunnel_sock(struct net *net, struct sock *sk,
struct udp_tunnel_sock_cfg *cfg)
{
- struct sock *sk = sock->sk;
-
/* Disable multicast loopback */
inet_clear_bit(MC_LOOP, sk);
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 157fc23ce4e1..cbc5a3e57b33 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1683,7 +1683,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
.encap_destroy = l2tp_udp_encap_destroy,
};
- setup_udp_tunnel_sock(net, sock, &udp_cfg);
+ setup_udp_tunnel_sock(net, sock->sk, &udp_cfg);
}
sk->sk_allocation = GFP_ATOMIC;
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 111f574fe667..169f9dfdaa77 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -194,7 +194,7 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
tuncfg.encap_rcv = rxrpc_encap_rcv;
tuncfg.encap_err_rcv = rxrpc_encap_err_rcv;
tuncfg.sk_user_data = local;
- setup_udp_tunnel_sock(net, local->socket, &tuncfg);
+ setup_udp_tunnel_sock(net, local->socket->sk, &tuncfg);
/* set the socket up */
usk = local->socket->sk;
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index ffe594ad4414..5c6fa8e8d34d 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -864,7 +864,7 @@ int sctp_udp_sock_start(struct net *net)
tuncfg.encap_type = 1;
tuncfg.encap_rcv = sctp_udp_rcv;
tuncfg.encap_err_lookup = sctp_udp_v4_err;
- setup_udp_tunnel_sock(net, sock, &tuncfg);
+ setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
net->sctp.udp4_sock = sock->sk;
#if IS_ENABLED(CONFIG_IPV6)
@@ -886,7 +886,7 @@ int sctp_udp_sock_start(struct net *net)
tuncfg.encap_type = 1;
tuncfg.encap_rcv = sctp_udp_rcv;
tuncfg.encap_err_lookup = sctp_udp_v6_err;
- setup_udp_tunnel_sock(net, sock, &tuncfg);
+ setup_udp_tunnel_sock(net, sock->sk, &tuncfg);
net->sctp.udp6_sock = sock->sk;
#endif
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index d7c050ff5804..0db172f1a41a 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -771,7 +771,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
tuncfg.encap_type = 1;
tuncfg.encap_rcv = tipc_udp_recv;
tuncfg.encap_destroy = NULL;
- setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
+ setup_udp_tunnel_sock(net, ub->ubsock->sk, &tuncfg);
err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC);
if (err)
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v1 net-next 03/15] udp_tunnel: Pass struct sock to udp_tunnel6_dst_lookup().
From: Kuniyuki Iwashima @ 2026-05-02 3:12 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Andrew Lunn
Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev
In-Reply-To: <20260502031401.3557229-1-kuniyu@google.com>
None of the udp_tunnel users need struct socket in their
fast paths; it is only used for tunnel setup / teardown.
Even udp_tunnel6_dst_lookup() does not need struct socket.
Let's change udp_tunnel6_dst_lookup() to take struct sock
instead of struct socket.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
drivers/net/bareudp.c | 4 ++--
drivers/net/geneve.c | 4 ++--
drivers/net/vxlan/vxlan_core.c | 4 ++--
include/net/udp_tunnel.h | 2 +-
net/ipv6/ip6_udp_tunnel.c | 6 +++---
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
index 169ab90393cc..073ac8a15354 100644
--- a/drivers/net/bareudp.c
+++ b/drivers/net/bareudp.c
@@ -396,7 +396,7 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
sport = udp_flow_src_port(bareudp->net, skb,
bareudp->sport_min, USHRT_MAX,
true);
- dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock, 0, &saddr,
+ dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock->sk, 0, &saddr,
key, sport, bareudp->port, key->tos,
use_cache ?
(struct dst_cache *) &info->dst_cache : NULL);
@@ -532,7 +532,7 @@ static int bareudp_fill_metadata_dst(struct net_device *dev,
if (!sock)
return -ESHUTDOWN;
- dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock,
+ dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock->sk,
0, &saddr, &info->key,
sport, bareudp->port, info->key.tos,
use_cache ? &info->dst_cache : NULL);
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index c3a7736cd6fc..4b7081b97015 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1424,7 +1424,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
geneve->cfg.port_min,
geneve->cfg.port_max, true);
- dst = udp_tunnel6_dst_lookup(skb, dev, geneve->net, gs6->sock, 0,
+ dst = udp_tunnel6_dst_lookup(skb, dev, geneve->net, gs6->sock->sk, 0,
&saddr, key, sport,
geneve->cfg.info.key.tp_dst, prio,
use_cache ?
@@ -1592,7 +1592,7 @@ static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
geneve->cfg.port_min,
geneve->cfg.port_max, true);
- dst = udp_tunnel6_dst_lookup(skb, dev, geneve->net, gs6->sock, 0,
+ dst = udp_tunnel6_dst_lookup(skb, dev, geneve->net, gs6->sock->sk, 0,
&saddr, &info->key, sport,
geneve->cfg.info.key.tp_dst, prio,
use_cache ? &info->dst_cache : NULL);
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 394801c068b3..a19f951e05f1 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -2559,7 +2559,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
if (!ifindex)
ifindex = sock6->sock->sk->sk_bound_dev_if;
- ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sock,
+ ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sock->sk,
ifindex, &saddr, pkey,
src_port, dst_port, tos,
use_cache ? dst_cache : NULL);
@@ -3254,7 +3254,7 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
if (!sock6)
return -EIO;
- ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sock,
+ ndst = udp_tunnel6_dst_lookup(skb, dev, vxlan->net, sock6->sock->sk,
0, &info->key.u.ipv6.src,
&info->key,
sport, dport, info->key.tos,
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 49324e28ec27..14a9c5155608 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -188,7 +188,7 @@ struct rtable *udp_tunnel_dst_lookup(struct sk_buff *skb,
struct dst_entry *udp_tunnel6_dst_lookup(struct sk_buff *skb,
struct net_device *dev,
struct net *net,
- struct socket *sock, int oif,
+ struct sock *sk, int oif,
struct in6_addr *saddr,
const struct ip_tunnel_key *key,
__be16 sport, __be16 dport, u8 dsfield,
diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c
index 405ef1cb8864..9adb5775487f 100644
--- a/net/ipv6/ip6_udp_tunnel.c
+++ b/net/ipv6/ip6_udp_tunnel.c
@@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
* @skb: Packet for which lookup is done
* @dev: Tunnel device
* @net: Network namespace of tunnel device
- * @sock: Socket which provides route info
+ * @sk: Socket which provides route info
* @oif: Index of the output interface
* @saddr: Memory to store the src ip address
* @key: Tunnel information
@@ -135,7 +135,7 @@ EXPORT_SYMBOL_GPL(udp_tunnel6_xmit_skb);
struct dst_entry *udp_tunnel6_dst_lookup(struct sk_buff *skb,
struct net_device *dev,
struct net *net,
- struct socket *sock,
+ struct sock *sk,
int oif,
struct in6_addr *saddr,
const struct ip_tunnel_key *key,
@@ -162,7 +162,7 @@ struct dst_entry *udp_tunnel6_dst_lookup(struct sk_buff *skb,
fl6.fl6_dport = dport;
fl6.flowlabel = ip6_make_flowinfo(dsfield, key->label);
- dst = ip6_dst_lookup_flow(net, sock->sk, &fl6, NULL);
+ dst = ip6_dst_lookup_flow(net, sk, &fl6, NULL);
if (IS_ERR(dst)) {
netdev_dbg(dev, "no route to %pI6\n", &fl6.daddr);
return ERR_PTR(-ENETUNREACH);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
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