* Re: [PATCH v2 net-next 13/14] ipvlan: Protect ipvl_port.ipvlans with mutex.
From: Kuniyuki Iwashima @ 2026-07-10 16:15 UTC (permalink / raw)
To: Paolo Abeni
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Andrew Lunn,
Simon Horman, Kuniyuki Iwashima, netdev
In-Reply-To: <71f1aba1-78b6-4e7b-8dc9-092b50402e07@redhat.com>
On Fri, Jul 10, 2026 at 4:08 AM Paolo Abeni <pabeni@redhat.com> wrote:
>
> On 7/3/26 2:09 AM, Kuniyuki Iwashima wrote:
> > @@ -800,9 +831,15 @@ static int ipvlan_device_event(struct notifier_block *unused,
> > if (dev->reg_state != NETREG_UNREGISTERING)
> > break;
> >
> > - list_for_each_entry_safe(ipvlan, next, &port->ipvlans, pnode)
> > - ipvlan->dev->rtnl_link_ops->dellink(ipvlan->dev,
> > - &lst_kill);
> > + list_for_each_entry_safe(ipvlan, next, &port->ipvlans, pnode) {
> > +#if IS_ENABLED(CONFIG_IPVTAP)
> > + if (ipvlan->dev->rtnl_link_ops != &ipvlan_link_ops)
> > + __ipvtap_dellink_ptr(ipvlan->dev, &lst_kill);
> > + else
> > +#endif
> > + __ipvlan_link_delete(ipvlan->dev, &lst_kill);
>
> I'm not sure if it's worthy a repost, but what about adding a
> link_delete_unlocked() cb to `struct ipvl_dev *`? IMHO should make this
> code more straight forward.
Since port is allocated in ndo_init(), ipvtap needs to wrap it
and overwrite port->ops everytime for one time (or at ->newlink),
but I don't have strong opinion here.
It would be nicer if I could follow up since this series gets 5-days
penalty on Suie due to too many Sashiko false-positive, get_net(),
and a build warning due to xchg() for veth, and we will likely lose
context next week :)
^ permalink raw reply
* Re: [PATCH v2 net-next] tun: no longer rely on RTNL in tun_fill_info()
From: patchwork-bot+netdevbpf @ 2026-07-10 15:40 UTC (permalink / raw)
To: Eric Dumazet
Cc: davem, kuba, pabeni, horms, andrew+netdev, kuniyu, netdev,
eric.dumazet, willemb
In-Reply-To: <20260706163517.2415530-1-edumazet@google.com>
Hello:
This patch was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Mon, 6 Jul 2026 16:35:17 +0000 you wrote:
> Update tun_fill_info() to read device configuration fields (flags, owner,
> group, numqueues, numdisabled) locklessly using READ_ONCE().
>
> Annotate all writes to these fields in the control paths with WRITE_ONCE()
> to prevent data races, as these fields can be modified concurrently via
> ioctls (TUNSETPERSIST, TUNSETOWNER, TUNSETGROUP, TUNSETIFF) or queue
> attaching/detaching.
>
> [...]
Here is the summary with links:
- [v2,net-next] tun: no longer rely on RTNL in tun_fill_info()
https://git.kernel.org/netdev/net-next/c/23dad2d088df
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 v3] tipc: serialize udp bearer replicast list updates
From: Tung Quang Nguyen @ 2026-07-10 15:39 UTC (permalink / raw)
To: Weiming Shi
Cc: netdev@vger.kernel.org, tipc-discussion@lists.sourceforge.net,
linux-kernel@vger.kernel.org, xmei5@asu.edu, Jon Maloy,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
In-Reply-To: <20260710032901.4099197-2-bestswngs@gmail.com>
>Subject: [PATCH net v3] tipc: serialize udp bearer replicast list updates
>
>tipc_udp_rcast_add() and cleanup_bearer() both update ub->rcast.list with
>list_add_rcu() / list_del_rcu(), but nothing serializes them. The add runs from
>the encap receive softirq (via tipc_udp_rcast_disc()) without rtnl_lock(), so it
>can race the cleanup delete and corrupt the list:
>
> list_del corruption. prev->next should be ffff8880298d7ab8,
> but was ffff88802449ad38. (prev=ffff888027e3ec98)
> kernel BUG at lib/list_debug.c:62!
> RIP: __list_del_entry_valid_or_report+0x17a/0x200
> Workqueue: events cleanup_bearer
> Call Trace:
> cleanup_bearer (net/tipc/udp_media.c:811)
> process_one_work (kernel/workqueue.c:3302)
> worker_thread (kernel/workqueue.c:3466)
>
>The bearer can be enabled from an unprivileged user namespace, as the
>TIPCv2 generic-netlink ops carry no GENL_ADMIN_PERM.
>
>Add a spinlock to struct udp_bearer and take it around the list_add_rcu() in
>tipc_udp_rcast_add() and the list_del_rcu() loop in cleanup_bearer() so the
>two writers can no longer corrupt the list.
>
>Check for a duplicate peer under the same lock before adding, and remove
>tipc_udp_is_known_peer(). The old lockless pre-check in
>tipc_udp_rcast_disc() was racy: two softirqs discovering the same peer could
>both find it absent and add it twice. Doing the check under rcast_lock in
>tipc_udp_rcast_add() makes it the single point of truth for both the discovery
>and the netlink add paths.
>
>Fixes: ef20cd4dd163 ("tipc: introduce UDP replicast")
>Reported-by: Xiang Mei <xmei5@asu.edu>
>Suggested-by: Tung Nguyen <tung.quang.nguyen@est.tech>
>Signed-off-by: Weiming Shi <bestswngs@gmail.com>
>Assisted-by: Claude:claude-opus-4-8
>---
>v3: (per Tung's review)
> - Check for a duplicate peer in tipc_udp_rcast_add() under rcast_lock
> before adding, and remove tipc_udp_is_known_peer().
> - This also drops the list_for_each_entry_rcu() change to
> tipc_udp_is_known_peer() from v2, since the helper is gone.
>v2:
> - Narrow the lock to the list mutation.
>
> net/tipc/udp_media.c | 45 ++++++++++++++++++--------------------------
> 1 file changed, 18 insertions(+), 27 deletions(-)
>
>diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index
>62ae7f5b5..3a7d9b15c 100644
>--- a/net/tipc/udp_media.c
>+++ b/net/tipc/udp_media.c
>@@ -94,6 +94,7 @@ struct udp_replicast {
> * @ifindex: local address scope
> * @work: used to schedule deferred work on a bearer
> * @rcast: associated udp_replicast container
>+ * @rcast_lock: serialize updates to @rcast.list against concurrent
>updaters
> */
> struct udp_bearer {
> struct tipc_bearer __rcu *bearer;
>@@ -101,6 +102,7 @@ struct udp_bearer {
> u32 ifindex;
> struct work_struct work;
> struct udp_replicast rcast;
>+ spinlock_t rcast_lock; /* protects rcast.list */
> };
>
> static int tipc_udp_is_mcast_addr(struct udp_media_addr *addr) @@ -278,30
>+280,10 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
> return err;
> }
>
>-static bool tipc_udp_is_known_peer(struct tipc_bearer *b,
>- struct udp_media_addr *addr)
>-{
>- struct udp_replicast *rcast, *tmp;
>- struct udp_bearer *ub;
>-
>- ub = rcu_dereference_rtnl(b->media_ptr);
>- if (!ub) {
>- pr_err_ratelimited("UDP bearer instance not found\n");
>- return false;
>- }
>-
>- list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
>- if (!memcmp(&rcast->addr, addr, sizeof(struct
>udp_media_addr)))
>- return true;
>- }
>-
>- return false;
>-}
>-
> static int tipc_udp_rcast_add(struct tipc_bearer *b,
> struct udp_media_addr *addr)
> {
>- struct udp_replicast *rcast;
>+ struct udp_replicast *rcast, *tmp;
> struct udp_bearer *ub;
>
> ub = rcu_dereference_rtnl(b->media_ptr);
>@@ -326,7 +308,19 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
> pr_info("New replicast peer: %pI6\n", &rcast->addr.ipv6);
>#endif
> b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
>+
>+ /* serialize with other updaters and drop duplicates under the lock */
>+ spin_lock_bh(&ub->rcast_lock);
>+ list_for_each_entry(tmp, &ub->rcast.list, list) {
>+ if (!memcmp(&tmp->addr, addr, sizeof(*addr))) {
>+ spin_unlock_bh(&ub->rcast_lock);
>+ dst_cache_destroy(&rcast->dst_cache);
>+ kfree(rcast);
>+ return 0;
>+ }
>+ }
> list_add_rcu(&rcast->list, &ub->rcast.list);
>+ spin_unlock_bh(&ub->rcast_lock);
To avoid freeing allocated duplicate 'rcast' and avoid storm of malicious duplicate address attacks that could lead to running out of memory when allocating 'rcast', we should change like this:
@@ -308,16 +308,28 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
if (!ub)
return -ENODEV;
+ spin_lock_bh(&ub->rcast_lock);
+ list_for_each_entry(rcast, &ub->rcast.list, list) {
+ if (!memcmp(&rcast->addr, addr, sizeof(*addr))) {
+ spin_unlock_bh(&ub->rcast_lock);
+ return 0;
+ }
+ }
rcast = kmalloc_obj(*rcast, GFP_ATOMIC);
- if (!rcast)
+ if (!rcast) {
+ spin_unlock_bh(&ub->rcast_lock);
return -ENOMEM;
+ }
if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) {
kfree(rcast);
+ spin_unlock_bh(&ub->rcast_lock);
return -ENOMEM;
}
memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
+ list_add_rcu(&rcast->list, &ub->rcast.list);
+ spin_unlock_bh(&ub->rcast_lock);
if (ntohs(addr->proto) == ETH_P_IP)
pr_info("New replicast peer: %pI4\n", &rcast->addr.ipv4);
@@ -326,7 +338,6 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
pr_info("New replicast peer: %pI6\n", &rcast->addr.ipv6); #endif
b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
- list_add_rcu(&rcast->list, &ub->rcast.list);
return 0;
}
> return 0;
> }
>
>@@ -361,9 +355,6 @@ static int tipc_udp_rcast_disc(struct tipc_bearer *b,
>struct sk_buff *skb)
> return 0;
> }
>
>- if (likely(tipc_udp_is_known_peer(b, &src)))
>- return 0;
>-
> return tipc_udp_rcast_add(b, &src);
> }
>
>@@ -644,9 +635,6 @@ int tipc_udp_nl_bearer_add(struct tipc_bearer *b,
>struct nlattr *attr)
> return -EINVAL;
> }
>
>- if (tipc_udp_is_known_peer(b, &addr))
>- return 0;
>-
> return tipc_udp_rcast_add(b, &addr);
> }
>
>@@ -679,6 +667,7 @@ static int tipc_udp_enable(struct net *net, struct
>tipc_bearer *b,
> return -ENOMEM;
>
> INIT_LIST_HEAD(&ub->rcast.list);
>+ spin_lock_init(&ub->rcast_lock);
>
> if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
> goto err;
>@@ -819,10 +808,12 @@ static void cleanup_bearer(struct work_struct
>*work)
> struct udp_replicast *rcast, *tmp;
> struct tipc_net *tn;
>
>+ spin_lock_bh(&ub->rcast_lock);
> list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
> list_del_rcu(&rcast->list);
> call_rcu_hurry(&rcast->rcu, rcast_free_rcu);
> }
>+ spin_unlock_bh(&ub->rcast_lock);
>
> tn = tipc_net(sock_net(ub->sk));
>
>--
>2.43.0
^ permalink raw reply
* Re: [PATCH net v2] sctp: validate stream count in sctp_process_strreset_inreq()
From: Xin Long @ 2026-07-10 15:34 UTC (permalink / raw)
To: David Laight
Cc: Cen Zhang (Microsoft), marcelo.leitner, davem, edumazet, kuba,
pabeni, horms, linux-sctp, netdev, linux-kernel,
AutonomousCodeSecurity, tgopinath, kys
In-Reply-To: <20260710092559.40f37700@pumpkin>
On Fri, Jul 10, 2026 at 4:26 AM David Laight
<david.laight.linux@gmail.com> wrote:
>
> On Thu, 9 Jul 2026 21:07:18 -0400
> "Cen Zhang (Microsoft)" <blbllhy@gmail.com> wrote:
>
> > When processing a RESET_IN_REQUEST from a peer,
> > sctp_process_strreset_inreq() derives the stream count from the
> > parameter length but does not check whether the resulting
> > RESET_OUT_REQUEST would exceed SCTP_MAX_CHUNK_LEN.
> >
> > The OUT request header (sctp_strreset_outreq, 16 bytes) is 8 bytes
> > larger than the IN request header (sctp_strreset_inreq, 8 bytes).
> > Generally, the IP payload is bounded to 65535 bytes, so the stream
> > list cannot be large enough to trigger the overflow. However, on
> > interfaces with MTU > 65535 (e.g., loopback with IPv6 jumbograms), a
> > stream list that fits within the incoming IN parameter can cause a
> > __u16 overflow in sctp_make_strreset_req() when computing the OUT
> > request size, leading to an undersized skb allocation and a kernel
> > BUG:
> >
> > net/core/skbuff.c:207 skb_panic
> > net/core/skbuff.c:2625 skb_put
> > net/sctp/sm_make_chunk.c:1535 sctp_addto_chunk
> > net/sctp/sm_make_chunk.c:3695 sctp_make_strreset_req
> > net/sctp/stream.c:655 sctp_process_strreset_inreq
> >
> > The local setsockopt path validates the generated reset request size.
> > However, for an incoming-only reset, it accounts for the smaller IN
> > request even though the peer must generate an OUT request with the same
> > stream list. Such a request cannot be completed successfully by the
> > peer.
> >
> > Reject peer IN requests whose corresponding OUT request would exceed
> > SCTP_MAX_CHUNK_LEN. Also tighten the local check so it does not send an
> > IN request that would require an oversized OUT request from the peer.
> >
> > Fixes: 7f9d68ac944e ("sctp: implement sender-side procedures for SSN Reset Request Parameter")
> > Reported-by: AutonomousCodeSecurity@microsoft.com
> > Closes: https://lore.kernel.org/all/20260707203215.2752-1-blbllhy@gmail.com/
> > Suggested-by: Xin Long <lucien.xin@gmail.com>
> > Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
> > ---
> > v2: Add the OUT request length check to the send path, as suggested by Xin Long.
> >
> > net/sctp/stream.c | 6 +++++-
> > 1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/net/sctp/stream.c b/net/sctp/stream.c
> > index 5c2fdedea088..34ffe6c945a4 100644
> > --- a/net/sctp/stream.c
> > +++ b/net/sctp/stream.c
> > @@ -308,7 +308,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
> > goto out;
> >
> > param_len += str_nums * sizeof(__u16) +
> > - sizeof(struct sctp_strreset_inreq);
> > + (out ? sizeof(struct sctp_strreset_inreq)
> > + : sizeof(struct sctp_strreset_outreq));
>
> Does it really make any sense to have a connection with the 32k streams
> that would be needed in order to send a maximal length request?
> (Or more likely a user requesting the same streams be reset multiple times.)
> So an initial check that str_nums < SOME_CONSTANT_JUST_BELOW_32K would do.
>
Yes, that would be a simpler fix.
However, 32K is not a limit defined by the RFC. While 32K streams may seem
excessive in practice, we cannot say that such a configuration is invalid.
If an application legitimately needs more than that, it would be difficult
to argue that it is not using SCTP correctly.
> Looking at the code I'm sure the kmalloc() shouldn't be done in the
> 'str_nums == 0' case either.
> In fact it is probably worth doing the kmalloc() earlier to avoid two
> scans of the array.
> I even wonder if it should be possible to allocate the chunk without filling
> in the data and then put the values in afterwards (freeing the chunk if there
> is an error).
>
> Then there is the code that reverts the state to OPEN if sctp_send_reconf()
> fails - nothing check that is the original state.
>
That would be another issue that we can address separately.
It would be great if you could follow up on this one. :-)
> David
>
>
> > }
> >
> > if (param_len > SCTP_MAX_CHUNK_LEN -
> > @@ -639,6 +640,9 @@ struct sctp_chunk *sctp_process_strreset_inreq(
> >
> > nums = (ntohs(param.p->length) - sizeof(*inreq)) / sizeof(__u16);
> > str_p = inreq->list_of_streams;
> > + if (nums * sizeof(__u16) + sizeof(struct sctp_strreset_outreq) >
> > + SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_reconf_chunk))
> > + goto out;
> > for (i = 0; i < nums; i++) {
> > if (ntohs(str_p[i]) >= stream->outcnt) {
> > result = SCTP_STRRESET_ERR_WRONG_SSN;
>
Acked-by: Xin Long <lucien.xin@gmail.com>
Thanks.
^ permalink raw reply
* Re: [PATCH net-next 6/7] selftests: drv-net: extend so_txtime with hw offload
From: Paolo Abeni @ 2026-07-10 15:26 UTC (permalink / raw)
To: Willem de Bruijn, netdev
Cc: davem, kuba, edumazet, horms, andrew, Willem de Bruijn
In-Reply-To: <20260706133433.3142805-7-willemdebruijn.kernel@gmail.com>
On 7/6/26 3:34 PM, Willem de Bruijn wrote:
> @@ -38,6 +41,34 @@ def test_so_txtime(cfg, clockid, ipver, args_tx, args_rx, expect_success):
> cmd(cmd_tx)
>
>
> +def _dev_setup_pacing_offload(cfg):
> + """Configure pacing-offload-horizon."""
> + ethnl = EthtoolFamily()
> +
> + try:
> + rings = ethnl.rings_get({'header': {'dev-index': cfg.ifindex}})
> + except NlError:
> + raise KsftSkipEx('ring-get not supported by device')
pylint complains:
tools/testing/selftests/drivers/net/so_txtime.py:51:8: W0707: Consider
explicitly re-raising using 'except NlError as exc' and 'raise
KsftSkipEx('ring-get not supported by device') from exc'
(raise-missing-from)
> +
> + if 'pacing-offload-horizon' not in rings or \
> + 'pacing-offload-horizon-max' not in rings:
> + raise KsftSkipEx('pacing offload horizon not supported by device')
> +
> + if rings['pacing-offload-horizon-max'] < 50_000:
> + raise KsftSkipEx('pacing offload max horizon too small')
> +
> + cur_horizon = rings['pacing-offload-horizon']
> + new_horizon = 50_000
> + ethnl.rings_set({
> + 'header': {'dev-index': cfg.ifindex},
> + 'pacing-offload-horizon': new_horizon,
> + })
> + defer(ethnl.rings_set, {
> + 'header': {'dev-index': cfg.ifindex},
> + 'pacing-offload-horizon': cur_horizon
> + })
> +
> +
> def _qdisc_setup(ifname, qdisc, optargs=""):
> """Replace root qdisc. Restore the original after the test.
>
> @@ -56,6 +87,7 @@ def _test_variants_fq():
> ["one_pkt", "a,10", "a,10"],
> ["in_order", "a,10,b,20", "a,10,b,20"],
> ["reverse_order", "a,20,b,10", "b,10,a,20"],
> + ["beyond_hw_horizon", "a,70", "a,70"],
> ]:
> name = f"v{ipver}_{testcase[0]}"
> yield KsftNamedVariant(name, ipver, testcase[1], testcase[2])
> @@ -64,15 +96,42 @@ def _test_variants_fq():
> @ksft_variants(_test_variants_fq())
> def test_so_txtime_fq_mono(cfg, ipver, args_tx, args_rx):
> """Run all variants of monotonic (fq) tests."""
> - cfg.require_ipver(ipver)
> _qdisc_setup(cfg.ifname, "fq")
> test_so_txtime(cfg, "mono", ipver, args_tx, args_rx, True)
>
>
> +@ksft_variants(_test_variants_fq())
> +def test_so_txtime_fq_mono_hw(cfg, ipver, args_tx, args_rx):
> + """Run all variants of monotonic fq tests, with offload horizon."""
> + cfg.require_nsim(nsim_test=False)
> +
> + _dev_setup_pacing_offload(cfg)
> + try:
> + _qdisc_setup(cfg.ifname, "fq", "offload_horizon 50ms")
> + except Exception as e:
> + raise KsftSkipEx("netdev does not support offload. skipping") from e
> +
> + # Expect all tests to use only hw pacing, except beyond_hw_horizon.
> + hw_only = "-h" if args_tx != "a,70" else ""
> + test_so_txtime(cfg, "mono", ipver, f"{hw_only} {args_tx}", args_rx, True)
> +
> +
> +@ksft_variants(_test_variants_fq())
> +def test_so_txtime_pfifofast_mono_hw(cfg, ipver, args_tx, args_rx):
> + """Run all variants of monotonic tests, without fq pacing sw backup."""
> + cfg.require_nsim(nsim_test=False)
> +
> + _dev_setup_pacing_offload(cfg)
> + _qdisc_setup(cfg.ifname, "pfifo_fast")
> +
> + # Expect all tests to pass, except beyond_hw_horizon without sw fallback.
> + expect_pass = False if args_tx == "a,70" else True
pylint says:
tools/testing/selftests/drivers/net/so_txtime.py:128:18: R1719: The if
expression can be replaced with 'not test' (simplifiable-if-expression)
/P
^ permalink raw reply
* Re: [PATCH net-next 2/4] dpll: zl3073x: add PTP clock support
From: Ivan Vecera @ 2026-07-10 15:19 UTC (permalink / raw)
To: Vadim Fedorenko, netdev
Cc: Chris du Quesnay, Arkadiusz Kubalewski, David S. Miller,
Jakub Kicinski, Jiri Pirko, Michal Schmidt, Paolo Abeni,
Pasi Vaananen, Petr Oros, Prathosh Satish, Richard Cochran,
Simon Horman, linux-kernel
In-Reply-To: <8de7e108-3616-4e02-a7be-243e4cb8563c@linux.dev>
On 7/10/26 3:08 PM, Vadim Fedorenko wrote:
> On 08/07/2026 18:05, Ivan Vecera wrote:
>> Add PTP clock support for the ZL3073x DPLL driver. A PTP clock device
>> is registered for each DPLL channel that is in NCO mode, providing
>> gettimex64, settime64, adjtime, adjfine and perout callbacks.
>
> Here we come back to the discussion of NCO mode. Is DPLL channel
> actually a pin (virtual or physical)? If it's not, then it means that
> channel is exposed as independent DPLL device, that shouldn't affect
> other devices, but AFAIU, it can in the current implementation. If it is
> a pin, why do you check device's mode rather then pins?
>
> And another question - what happens when channel changes its mode to
> non-NCO? Do we have ptp device disappearing from the system?
Hi Vadim,
I understand your point. The PTP code was originally developed before
the NCO pin switching was implemented, when it made sense to split PTP
support into two patches - basic PTP for NCO-only channels (patch 2) and
then extending it to all modes via TIE write (patch 4).
Now that NCO mode can be entered and left dynamically via the NCO pin,
this split no longer makes sense. Having patch 2 register PTP only for
NCO-mode channels creates an awkward intermediate state where a dynamic
NCO switch would require dynamic PTP clock registration/unregistration.
I'll squash patches 1&3 and 2&4 in v2, so the PTP clock is always
registered regardless of the initial channel mode, with per-callback
mode checks.
Thanks,
Ivan
^ permalink raw reply
* Re: [PATCH net-next 7/7] net: pktgen: add support for SO_TXTIME
From: Paolo Abeni @ 2026-07-10 15:20 UTC (permalink / raw)
To: Willem de Bruijn, netdev
Cc: davem, kuba, edumazet, horms, andrew, Willem de Bruijn
In-Reply-To: <20260706133433.3142805-8-willemdebruijn.kernel@gmail.com>
On 7/6/26 3:34 PM, Willem de Bruijn wrote:
> @@ -1141,6 +1157,49 @@ static ssize_t pktgen_if_write(struct file *file,
> (unsigned long long) pkt_dev->delay);
> return count;
> }
> + if (!strcmp(name, "txtime_delay")) {
> + max = min(10, count - i);
> + len = num_arg(&user_buffer[i], max, &value);
> + if (len < 0)
> + return len;
> +
> + /* in queue_xmit mode fq may clear tstamp, do not reuse skb */
> + if (value > 0 && pkt_dev->clone_skb > 0)
> + return -EINVAL;
> +
> + pkt_dev->txtime_delay = (u64)value;
It looks like `pkt_dev->txtime_delay` access pattern is the same way as
`pkt_dev->txtime_clockid,`. I think WRITE_ONCE() is needed here, and
READ_ONCE() in pktgen_xmit().
> @@ -3557,6 +3633,14 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
> }
> pkt_dev->last_pkt_size = pkt_dev->skb->len;
> pkt_dev->clone_count = 0; /* reset counter */
> +
> + if (pkt_dev->flags & F_TXTIME && pkt_dev->txtime_delay) {
`pkt_dev->flags` is accessed at the beginning of this function with a
READ_ONCE. I think it should be better to consolidate the two reads.
/P
^ permalink raw reply
* Re: [PATCH v12 nf-next 3/7] netfilter: nf_flow_table_offload: Add nf_flow_rule_bridge()
From: Eric Woudstra @ 2026-07-10 15:16 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Florian Westphal, Phil Sutter,
Nikolay Aleksandrov, Ido Schimmel, Kuniyuki Iwashima,
Stanislav Fomichev, Samiullah Khawaja, Hangbin Liu, Krishna Kumar,
Martin Karsten, netdev, netfilter-devel, bridge
In-Reply-To: <alC64Vg_xihR-huW@chamomile>
On 7/10/26 11:26 AM, Pablo Neira Ayuso wrote:
> Hi Eric,
>
> On Wed, Jul 08, 2026 at 08:36:11PM +0200, Eric Woudstra wrote:
>> On 7/8/26 11:48 AM, Pablo Neira Ayuso wrote:
>>> On Tue, Jul 07, 2026 at 11:10:41AM +0200, Eric Woudstra wrote:
>>>> Add nf_flow_rule_bridge().
>>>>
>>>> It only calls the common rule and adds the redirect.
>>>
>>> I decided to use the new _unsupp() function, so we don't pretend
>>> bridge hw offload is already supported. We will need a driver before
>>> we can add this, this stub does not provide much. I guess your goal
>>> was just to avoid a crash here.
>>
>> No, I am already using hw_offload between bridged interfaces
>> on the mt7986 succesfully for almost 2 years.
>> It works dsa-port to direct interface (lan1 to eth1 on Bananapi R3) and
>> between direct interfaces (eth0 to eth1 on Bananapi-R3-mini)
>
> Do you utilize the existing mt7986 driver in-tree without changes to
> achive this hardware offload? Or you have still have out-of-tree
> patches that need to be merged to achive this?
>
I do not change anything about the mediatek drivers to achieve hardware
offload. No patch needed to fix hardware offload.
However I do have a small fix for the offloading towards the mediatek
wifi interface. This is a fix for the software fastpath already.
Also with hardware offload to wifi interface, once the software fastpath
is setup correctly (needs this patch), then the hardware offload functions
correctly without any further patch. See patch:
https://patchwork.ozlabs.org/project/netfilter-devel/patch/20260317101525.358016-1-ericwouds@gmail.com/
It is not reviewed yet.
>> It can also be tested with my bridge_fastpath.sh selftest script.
>> This script uses veth-device pairs to test the software fastpath.
>> It can also use 2 real interfaces interconnected in a loop of copper,
>> when chosen with commandline arguments. Then it tests software- and
>> hardware-fastpath. It also tests many different scenarios.
>>
>> So this is why I've added it, as it is already functional. If a software
>> fastpath is setup correctly, the hardware fastpath is also functional.
>
> Thanks for explaining.
>
> I am targetting at a minimal subset of the flowtable bridge support at
> this stage. There is a need to make progress with the
> nf_conntrack_bridge counterpart before the flowtable bridge can get
> more features (namely, bridge vlan filtering support).
I did send a newer version of my patch-set for nf_conntrack_bridge,
last version also adding support to defrag/refrag. See:
https://patchwork.ozlabs.org/project/netfilter-devel/cover/20260512103347.102746-1-ericwouds@gmail.com/
I've added testcases for defrag/refrag to the bridge_fastpath.sh selftest
script (v5), so I know it is functional.
For proper vlan filtering support, I do also believe you will need to
introduce DEV_PATH_BR_VLAN_KEEP_HW, or do something similar. See:
https://patchwork.ozlabs.org/project/netfilter-devel/patch/20260317101722.358640-1-ericwouds@gmail.com/
^ permalink raw reply
* Re: [PATCH net-next v6 1/4] dt-bindings: net: pse-pd: add bindings for Realtek PSE MCU
From: Conor Dooley @ 2026-07-10 15:10 UTC (permalink / raw)
To: Jonas Jelonek
Cc: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, netdev, devicetree,
linux-kernel, Daniel Golle, Bjørn Mork
In-Reply-To: <20260709194125.2784507-2-jelonek.jonas@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1442 bytes --]
On Thu, Jul 09, 2026 at 07:41:20PM +0000, Jonas Jelonek wrote:
> ---
> .../bindings/net/pse-pd/realtek,pse-mcu.yaml | 176 ++++++++++++++++++
> 1 file changed, 176 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/pse-pd/realtek,pse-mcu.yaml
Typically, we want filenames that match the compatibles used within. In
this case, probably pick the oldest and simplest one?
>
> +properties:
> + compatible:
> + oneOf:
> + # UART
> + - items:
> + - enum:
> + - zyxel,gs1900-10hp-a1-pse
> + - const: realtek,pse-mcu-gen1
IOW, this. Otherwise,
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: changes-requested
Thanks,
Conor.
> +
> + # I2C, SMBus framing
> + - items:
> + - enum:
> + - zyxel,gs1920-24hp-v2-pse
> + - const: realtek,pse-mcu-gen1-smbus
> +
> + # UART
> + - items:
> + - enum:
> + - zyxel,gs1900-10hp-b1-pse
> + - zyxel,xmg1915-10ep-pse
> + - const: realtek,pse-mcu-gen2
> +
> + # I2C, SMBus framing
> + - items:
> + - enum:
> + - zyxel,xs1930-12hp-pse
> + - const: realtek,pse-mcu-gen2-smbus
> +
> + # I2C, raw framing
> + - items:
> + - enum:
> + - linksys,lgs328mpc-v2-pse
> + - const: realtek,pse-mcu-gen2-i2c
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 3/7] idpf: support pacing offload
From: Paolo Abeni @ 2026-07-10 15:04 UTC (permalink / raw)
To: Tony Nguyen, Przemek Kitszel
Cc: davem, kuba, edumazet, horms, andrew, Willem de Bruijn,
Willem de Bruijn, Joshua A Hay, netdev
In-Reply-To: <20260706133433.3142805-4-willemdebruijn.kernel@gmail.com>
On 7/6/26 3:34 PM, Willem de Bruijn wrote:
> From: Willem de Bruijn <willemb@google.com>
>
> If skb->tstamp is in the future, program this future delivery txtime
> in the transmit descriptor.
>
> TCP pacing offload is only offloaded if SK_PACING_FQ is negotiated and
> the FQ offload_horizon is configured.
>
> But device support for pacing offload must be more robust. It can also
> be reached through SO_TXTIME.
>
> Bound check txtime. Only packets with timestamp between now and the
> horizon (max_pacing_offload_horizon) are offloaded.
>
> Support only in splitq mode, where tx and tx completion queues are
> separate and so completions can be returned out of order.
>
> Assume that the NIC clock is PTP synchronized to CLOCK_TAI. This
> can later be refined, e.g., to a custom CLOCK_AUX.
>
> Disable if in netpoll. It does not need the feature, and the ktime
> functions are not safe to call in this context.
>
> Cc: Tony Nguyen <anthony.l.nguyen@intel.com>
> Cc: Joshua A Hay <joshua.a.hay@intel.com>
> Signed-off-by: Willem de Bruijn <willemb@google.com>
I think this deserves an explicit ack from @intel
Could you please have a look?
/P
^ permalink raw reply
* Re: [PATCH net-next 0/3] vxlan: RCU protect vxlan_config and enable RTNL-less fill_info
From: Eric Dumazet @ 2026-07-10 15:03 UTC (permalink / raw)
To: Paolo Abeni
Cc: David S . Miller, Jakub Kicinski, Simon Horman, Kuniyuki Iwashima,
Ido Schimmel, Andrew Lunn, netdev, eric.dumazet
In-Reply-To: <e806a628-3710-4bab-bbae-b6dffe3513e1@redhat.com>
On Fri, Jul 10, 2026 at 4:22 PM Paolo Abeni <pabeni@redhat.com> wrote:
>
> On 7/10/26 4:20 PM, Paolo Abeni wrote:
> > On 7/8/26 6:04 PM, Eric Dumazet wrote:
> >> This patch series converts VXLAN configuration (`struct vxlan_config`)
> >> to be RCU-protected, allowing lockless readers and enabling RTNL-less
> >> `vxlan_fill_info()` netlink link info dumping.
> >>
> >> Work has been split into three distinct parts:
> >>
> >> 1. Refactor helper functions in RX, TX, MDB, VNIFILTER, and OVS paths to
> >> accept a `const struct vxlan_config *cfg` pointer (or pass specific
> >> fields such as `flags`/`saddr_family`) rather than accessing
> >> `vxlan->cfg` directly.
> >>
> >> 2. Convert `vxlan->cfg` from an embedded struct into an RCU-protected
> >> pointer (`struct vxlan_config __rcu *cfg`), dynamically allocated on
> >> device creation or changelink, and freed via `kfree_rcu()`. Update
> >> offload drivers (`mlxsw`) and OVS (`vport-vxlan.c`) accordingly.
> >>
> >> 3. Update `vxlan_fill_info()` to run under `rcu_read_lock()` instead of
> >> relying on RTNL lock, completing the transition to lockless link info
> >> dumping for VXLAN devices.
> >
> > I *suspect* this is triggering RCU splat in forwarding self-tests:
> >
> > [ 1955.481960][T11074] =============================
> oops, sashiko already spotted it:
>
> https://sashiko.dev/#/patchset/20260708160411.1355008-1-edumazet%40google.com
LOCKDEP inablility to understand rcu_read_lock() and
rcu_read_lock_bh() is quite something.
rcu_bh has disappeared a long time ago (it is kept for historical reasons only).
Perhaps we should finally replace it with standard rcu, to avoid
stacking rcu_read_lock() and rcu_read_lock_bh().
^ permalink raw reply
* [PATCH net] tipc: cap number of nodes per net namespace
From: Ibrahim Hashimov @ 2026-07-10 15:03 UTC (permalink / raw)
To: Jon Maloy, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, netdev, tipc-discussion, linux-kernel, stable
tipc_node_create() allocates a new struct tipc_node (plus a broadcast
receive link, a unicast link slot and a keepalive timer) for every
previously unseen (addr, node_id) pair carried in an inbound TIPC
LINK_CONFIG discovery frame:
n = tipc_node_find(net, addr) ?:
tipc_node_find_by_id(net, peer_id);
if (n) {
...
}
n = kzalloc_obj(*n, GFP_ATOMIC);
...
n->delete_at = jiffies + msecs_to_jiffies(NODE_CLEANUP_AFTER);
Both addr (msg_prevnode) and peer_id (msg_node_id) come straight out
of the discovery frame and are fully attacker controlled, and the
dedup key above is keyed on exactly those two values. There is no cap
on how many distinct nodes a net namespace may hold and no rate limit
on the create path, so an unauthenticated peer on an enabled TIPC
bearer (L2 or UDP) can flood LINK_CONFIG frames with a fresh (addr,
node_id) in each one and force the kernel to keep minting new,
distinct struct tipc_node objects without bound. A link-less spoofed
node is only reclaimed after NODE_CLEANUP_AFTER (300 s), so at typical
discovery rates the live node table, and the memory pinned by it,
grows roughly linearly with attacker-supplied identities for the
duration of the flood. This is (uncontrolled resource
consumption), reachable by any unauthenticated network-adjacent host
once tipc.ko is loaded and a bearer is enabled.
Bound this the same way net/core/neighbour.c bounds the ARP/ND
neighbour table against unauthenticated on-link input: reject new
entries once a hard ceiling is hit instead of letting the table grow
without limit. struct tipc_net already carries a num_nodes counter
that is declared but never read or written anywhere in net/tipc/; wire
it up on the create and delete paths and add a single bounds check on
it in tipc_node_create(), guarded by the same tn->node_list_lock
spinlock that already serializes every call site of
tipc_node_create(), tipc_node_delete_from_list(), tipc_node_delete()
and tipc_node_stop(). No new locking, no new data structures, and no
change to the node table's data layout or lookup semantics; legitimate
peers are still admitted exactly as before, up to the cap.
TIPC_MAX_NODES is set to 8192, well above any realistic TIPC cluster
size, bounding worst-case pinned memory to a fixed multiple of one
node's footprint instead of unbounded growth. It is intentionally not
tuned tight; exposing it as a sysctl (mirroring
net.ipv4.neigh.default.gc_thresh3) would be a reasonable follow-up but
is left out to keep this fix minimal.
Verified on a v6.19 KASAN build: flooding spoofed (addr, node_id)
peers past the cap makes the patched kernel log "Too many TIPC
nodes (8192)" and drop further peers, where the same flood grew
the live node table without bound before this patch.
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
---
net/tipc/node.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 8e4ef2630ae4..bb41f3231ce1 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -49,6 +49,16 @@
#define INVALID_NODE_SIG 0x10000
#define NODE_CLEANUP_AFTER 300000
+/* Hard cap on the number of live struct tipc_node entries a single net
+ * namespace will hold. Every entry (preliminary or not) also pins a
+ * broadcast-receive link, a unicast link slot and a keepalive timer, so
+ * this bounds worst-case memory from unauthenticated LINK_CONFIG discovery
+ * traffic the same way neigh_alloc()'s gc_thresh3 bounds the ARP/ND table
+ * (see net/core/neighbour.c). 8192 is far above any realistic TIPC cluster
+ * size and is not meant to be tight -- it only stops unbounded growth.
+ */
+#define TIPC_MAX_NODES 8192
+
/* Flags used to take different actions according to flag type
* TIPC_NOTIFY_NODE_DOWN: notify node is down
* TIPC_NOTIFY_NODE_UP: notify node is up
@@ -535,6 +545,11 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id,
goto exit;
}
+ if (tn->num_nodes >= TIPC_MAX_NODES) {
+ pr_warn_ratelimited("Too many TIPC nodes (%u), dropping new peer %x\n",
+ tn->num_nodes, addr);
+ goto exit;
+ }
n = kzalloc_obj(*n, GFP_ATOMIC);
if (!n) {
pr_warn("Node creation failed, no memory\n");
@@ -598,6 +613,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id,
break;
}
list_add_tail_rcu(&n->list, &temp_node->list);
+ tn->num_nodes++;
/* Calculate cluster capabilities */
tn->capabilities = TIPC_NODE_CAPABILITIES;
list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
@@ -630,6 +646,7 @@ static void tipc_node_delete_from_list(struct tipc_node *node)
#endif
list_del_rcu(&node->list);
hlist_del_rcu(&node->hash);
+ tipc_net(node->net)->num_nodes--;
tipc_node_put(node);
}
--
2.50.1 (Apple Git-155)
^ permalink raw reply related
* Re: [PATCH net-next 1/4] dpll: zl3073x: add channel ToD and phase step operations
From: Ivan Vecera @ 2026-07-10 15:02 UTC (permalink / raw)
To: Vadim Fedorenko, netdev
Cc: Chris du Quesnay, Arkadiusz Kubalewski, David S. Miller,
Jakub Kicinski, Jiri Pirko, Michal Schmidt, Paolo Abeni,
Pasi Vaananen, Petr Oros, Prathosh Satish, Richard Cochran,
Simon Horman, linux-kernel
In-Reply-To: <c66e433b-654d-4c14-ad73-e3a93314d8d8@linux.dev>
On 7/10/26 2:56 PM, Vadim Fedorenko wrote:
> On 08/07/2026 18:05, Ivan Vecera wrote:
>> Add low-level DPLL channel operations for ToD read/write/adjust,
>> delta frequency offset write and output phase step. ToD operations
>> use a wait-before-write pattern to avoid blocking after each
>> operation. tod_adjust additionally waits for completion since callers
>> may follow with phase step operations.
>>
>> The tod_ready_wait helper selects the poll timeout based on the
>> current ToD command - write operations use a longer timeout (1000 ms)
>> than reads (30 ms).
>>
>> The ToD read captures system timestamps (ptp_system_timestamp) around
>> the HW command and completion poll to support cross-timestamping.
>>
>> Add output step-time mask invariant to zl3073x_chan and
>> zl3073x_chan_is_out_stepped() helper to check if an output
>> participates in step-time operations.
>>
>
> [...]
>
>> +/**
>> + * zl3073x_chan_tod_read - read ToD registers after issuing a command
>> + * @zldev: pointer to zl3073x device
>> + * @ch: DPLL channel index
>> + * @next_hz: if true, read predicted ToD at next 1 Hz; otherwise read
>> current
>> + * @ts: timespec to store the result
>> + * @sts: optional system timestamp pair for cross-timestamping
>> + *
>> + * Context: Caller must serialize all zl3073x_chan_tod_* calls
>> externally.
>> + * Return: 0 on success, <0 on error
>> + */
>> +int zl3073x_chan_tod_read(struct zl3073x_dev *zldev, u8 ch,
>> + bool next_hz, struct timespec64 *ts,
>> + struct ptp_system_timestamp *sts)
>> +{
>> + u32 nsec;
>> + u64 sec;
>> + u8 cmd;
>> + int rc;
>> +
>> + if (next_hz)
>> + cmd = ZL_DPLL_TOD_CTRL_CMD_RD_NEXT_1HZ;
>> + else
>> + cmd = ZL_DPLL_TOD_CTRL_CMD_RD_CURRENT;
>> +
>> + /* Wait for any previous ToD operation to complete */
>> + rc = zl3073x_chan_tod_ready_wait(zldev, ch);
>> + if (rc)
>> + return rc;
>> +
>> + ptp_read_system_prets(sts);
>> + rc = zl3073x_chan_tod_ctrl(zldev, ch, cmd);
>> + if (rc)
>> + return rc;
>> +
>> + rc = zl3073x_chan_tod_ready_wait(zldev, ch);
>> + if (rc)
>> + return rc;
>> + ptp_read_system_postts(sts);
>
> AFAIU, this code means that the ToD value was somewhere between tod_ctrl
> command and tod_ready read value 0 of the register. How does it work
> with "predicted ToD at next 1 Hz"?
The ptp_system_timestamp is only used by the gettimex64 callback which
always calls tod_read with next_hz=false (current ToD). The next_hz=true
path is only used internally by tod_adjust() which passes sts=NULL.
So in practice, system timestamps are never captured around a predicted
ToD read. The function accepts both options through the same interface
for simplicity, but the sts parameter is only meaningful with
next_hz=false.
Thanks,
Ivan
^ permalink raw reply
* Re: [PATCH net] sctp: validate STALE_COOKIE cause length before reading staleness
From: patchwork-bot+netdevbpf @ 2026-07-10 15:00 UTC (permalink / raw)
To: Weiming Shi
Cc: linux-sctp, marcelo.leitner, lucien.xin, davem, edumazet, kuba,
pabeni, netdev, xmei5, stable
In-Reply-To: <20260704033545.2438373-2-bestswngs@gmail.com>
Hello:
This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Fri, 3 Jul 2026 20:35:46 -0700 you wrote:
> When an ERROR chunk with a STALE_COOKIE cause is received in the
> COOKIE_ECHOED state, sctp_sf_do_5_2_6_stale() reads the 4-byte Measure
> of Staleness that follows the cause header:
>
> err = (struct sctp_errhdr *)(chunk->skb->data);
> stale = ntohl(*(__be32 *)((u8 *)err + sizeof(*err)));
>
> [...]
Here is the summary with links:
- [net] sctp: validate STALE_COOKIE cause length before reading staleness
https://git.kernel.org/netdev/net/c/1cd23ca80784
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: dpaa: fix mode setting
From: Michael Walle @ 2026-07-10 14:47 UTC (permalink / raw)
To: Sean Anderson, Madalin Bucur, Andrew Lunn, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Russell King
Cc: netdev, linux-kernel
In-Reply-To: <a5c5b8a6-85a8-7830-e19b-ffd5de750e3c@linux.dev>
On Fri Jul 10, 2026 at 4:39 PM CEST, Sean Anderson wrote:
> On 7/10/26 10:22, Michael Walle wrote:
>> Before converting to the phylink interface, the init function would have
>> set the correct I/F mode depending on the maximum link speed of an
>> interface. After converting to phylink, the established link speed
>> is used to determine this setting and is set in the .link_up()
>> callback. The callback isn't called because the link is never
>> established between the PCS and a connected SGMII PHY.
>> To fix it, don't use the current speed, but set the mode depending on
>> the interface (which implies the maximum speed) in .mac_config().
>>
>> Fixes: 5d93cfcf7360 ("net: dpaa: Convert to phylink")
>> Suggested-by: Sean Anderson <sean.anderson@linux.dev>
>> Signed-off-by: Michael Walle <mwalle@kernel.org>
>> ---
>> FWIW, I dropped setting a non-reserved mode in init(). The hardware
>> default is 0 and the mac_config() will set a valid mode anyway.
>>
>> Changes in v2:
>> - the setting is/was based on the maximum speed, not the current
>> speed. thus, move the setting into mac_config().
>> - Link to v1: https://lore.kernel.org/r/20260706121011.1948906-1-mwalle@kernel.org/
>>
>> .../net/ethernet/freescale/fman/fman_dtsec.c | 26 ++++++++++---------
>> 1 file changed, 14 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
>> index fe35703c509e..7075f93bab49 100644
>> --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
>> +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
>> @@ -900,22 +900,28 @@ static void dtsec_mac_config(struct phylink_config *config, unsigned int mode,
>> {
>> struct mac_device *mac_dev = fman_config_to_mac(config);
>> struct dtsec_regs __iomem *regs = mac_dev->fman_mac->regs;
>> - u32 tmp;
>> + u32 ecntrl, maccfg2;
>> +
>> + maccfg2 = ioread32be(®s->maccfg2);
>> + maccfg2 &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
>>
>> switch (state->interface) {
>> case PHY_INTERFACE_MODE_RMII:
>> - tmp = DTSEC_ECNTRL_RMM;
>> + ecntrl = DTSEC_ECNTRL_RMM;
>> + maccfg2 |= MACCFG2_NIBBLE_MODE;
>> break;
>> case PHY_INTERFACE_MODE_RGMII:
>> case PHY_INTERFACE_MODE_RGMII_ID:
>> case PHY_INTERFACE_MODE_RGMII_RXID:
>> case PHY_INTERFACE_MODE_RGMII_TXID:
>> - tmp = DTSEC_ECNTRL_GMIIM | DTSEC_ECNTRL_RPM;
>> + ecntrl = DTSEC_ECNTRL_GMIIM | DTSEC_ECNTRL_RPM;
>> + maccfg2 |= MACCFG2_BYTE_MODE;
>> break;
>> case PHY_INTERFACE_MODE_SGMII:
>> case PHY_INTERFACE_MODE_1000BASEX:
>> case PHY_INTERFACE_MODE_2500BASEX:
>> - tmp = DTSEC_ECNTRL_TBIM | DTSEC_ECNTRL_SGMIIM;
>> + ecntrl = DTSEC_ECNTRL_TBIM | DTSEC_ECNTRL_SGMIIM;
>> + maccfg2 |= MACCFG2_BYTE_MODE;
>> break;
>> default:
>> dev_warn(mac_dev->dev, "cannot configure dTSEC for %s\n",
>> @@ -923,7 +929,8 @@ static void dtsec_mac_config(struct phylink_config *config, unsigned int mode,
>> return;
>> }
>>
>> - iowrite32be(tmp, ®s->ecntrl);
>> + iowrite32be(ecntrl, ®s->ecntrl);
>> + iowrite32be(maccfg2, ®s->maccfg2);
>> }
>>
>> static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy,
>> @@ -948,15 +955,10 @@ static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy,
>> iowrite32be(tmp, ®s->ecntrl);
>>
>> tmp = ioread32be(®s->maccfg2);
>> - tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE | MACCFG2_FULL_DUPLEX);
>> - if (speed >= SPEED_1000)
>> - tmp |= MACCFG2_BYTE_MODE;
>> - else
>> - tmp |= MACCFG2_NIBBLE_MODE;
>> -
>> if (duplex == DUPLEX_FULL)
>> tmp |= MACCFG2_FULL_DUPLEX;
>> -
>> + else
>> + tmp &= ~MACCFG2_FULL_DUPLEX;
>
> Did you test this when forcing 10/100 speed?
No I didn't. Well I can't. I have a very weird board which only
supports 1000base-X (and copper SFPs in 1000basex autoneg mode). On
top of that there is a Marvell 88E1112 in between the SFP and the
MAC, for which the PHY driver is completely broken. Long story
short, I'm not able to test that (yet/at all? Not sure).
-michael
>
>> iowrite32be(tmp, ®s->maccfg2);
>>
>> mac_dev->update_speed(mac_dev, speed);
>
> If so,
>
> Reviewed-by: Sean Anderson <sean.anderson@linux.dev>
^ permalink raw reply
* Re: [GIT PULL] wireless-2026-07-09
From: patchwork-bot+netdevbpf @ 2026-07-10 14:40 UTC (permalink / raw)
To: Johannes Berg; +Cc: netdev, linux-wireless
In-Reply-To: <20260709115038.243870-3-johannes@sipsolutions.net>
Hello:
This pull request was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Thu, 9 Jul 2026 13:49:05 +0200 you wrote:
> Hi,
>
> Sorry, I meant to send this yesterday, hoping it'd get
> in/out before netdevconf and all that, because it's
> actually really big. Mostly I've now collected many
> random LLM-induced robustness fixes (I can't really
> call most of them security fixes, though there likely
> are a few).
>
> [...]
Here is the summary with links:
- [GIT,PULL] wireless-2026-07-09
https://git.kernel.org/netdev/net/c/a0d82fb85053
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: dpaa: fix mode setting
From: Sean Anderson @ 2026-07-10 14:39 UTC (permalink / raw)
To: Michael Walle, Madalin Bucur, Andrew Lunn, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Russell King
Cc: netdev, linux-kernel
In-Reply-To: <20260710143430.2276141-1-mwalle@kernel.org>
On 7/10/26 10:22, Michael Walle wrote:
> Before converting to the phylink interface, the init function would have
> set the correct I/F mode depending on the maximum link speed of an
> interface. After converting to phylink, the established link speed
> is used to determine this setting and is set in the .link_up()
> callback. The callback isn't called because the link is never
> established between the PCS and a connected SGMII PHY.
> To fix it, don't use the current speed, but set the mode depending on
> the interface (which implies the maximum speed) in .mac_config().
>
> Fixes: 5d93cfcf7360 ("net: dpaa: Convert to phylink")
> Suggested-by: Sean Anderson <sean.anderson@linux.dev>
> Signed-off-by: Michael Walle <mwalle@kernel.org>
> ---
> FWIW, I dropped setting a non-reserved mode in init(). The hardware
> default is 0 and the mac_config() will set a valid mode anyway.
>
> Changes in v2:
> - the setting is/was based on the maximum speed, not the current
> speed. thus, move the setting into mac_config().
> - Link to v1: https://lore.kernel.org/r/20260706121011.1948906-1-mwalle@kernel.org/
>
> .../net/ethernet/freescale/fman/fman_dtsec.c | 26 ++++++++++---------
> 1 file changed, 14 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
> index fe35703c509e..7075f93bab49 100644
> --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
> +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
> @@ -900,22 +900,28 @@ static void dtsec_mac_config(struct phylink_config *config, unsigned int mode,
> {
> struct mac_device *mac_dev = fman_config_to_mac(config);
> struct dtsec_regs __iomem *regs = mac_dev->fman_mac->regs;
> - u32 tmp;
> + u32 ecntrl, maccfg2;
> +
> + maccfg2 = ioread32be(®s->maccfg2);
> + maccfg2 &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
>
> switch (state->interface) {
> case PHY_INTERFACE_MODE_RMII:
> - tmp = DTSEC_ECNTRL_RMM;
> + ecntrl = DTSEC_ECNTRL_RMM;
> + maccfg2 |= MACCFG2_NIBBLE_MODE;
> break;
> case PHY_INTERFACE_MODE_RGMII:
> case PHY_INTERFACE_MODE_RGMII_ID:
> case PHY_INTERFACE_MODE_RGMII_RXID:
> case PHY_INTERFACE_MODE_RGMII_TXID:
> - tmp = DTSEC_ECNTRL_GMIIM | DTSEC_ECNTRL_RPM;
> + ecntrl = DTSEC_ECNTRL_GMIIM | DTSEC_ECNTRL_RPM;
> + maccfg2 |= MACCFG2_BYTE_MODE;
> break;
> case PHY_INTERFACE_MODE_SGMII:
> case PHY_INTERFACE_MODE_1000BASEX:
> case PHY_INTERFACE_MODE_2500BASEX:
> - tmp = DTSEC_ECNTRL_TBIM | DTSEC_ECNTRL_SGMIIM;
> + ecntrl = DTSEC_ECNTRL_TBIM | DTSEC_ECNTRL_SGMIIM;
> + maccfg2 |= MACCFG2_BYTE_MODE;
> break;
> default:
> dev_warn(mac_dev->dev, "cannot configure dTSEC for %s\n",
> @@ -923,7 +929,8 @@ static void dtsec_mac_config(struct phylink_config *config, unsigned int mode,
> return;
> }
>
> - iowrite32be(tmp, ®s->ecntrl);
> + iowrite32be(ecntrl, ®s->ecntrl);
> + iowrite32be(maccfg2, ®s->maccfg2);
> }
>
> static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy,
> @@ -948,15 +955,10 @@ static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy,
> iowrite32be(tmp, ®s->ecntrl);
>
> tmp = ioread32be(®s->maccfg2);
> - tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE | MACCFG2_FULL_DUPLEX);
> - if (speed >= SPEED_1000)
> - tmp |= MACCFG2_BYTE_MODE;
> - else
> - tmp |= MACCFG2_NIBBLE_MODE;
> -
> if (duplex == DUPLEX_FULL)
> tmp |= MACCFG2_FULL_DUPLEX;
> -
> + else
> + tmp &= ~MACCFG2_FULL_DUPLEX;
Did you test this when forcing 10/100 speed?
> iowrite32be(tmp, ®s->maccfg2);
>
> mac_dev->update_speed(mac_dev, speed);
If so,
Reviewed-by: Sean Anderson <sean.anderson@linux.dev>
^ permalink raw reply
* [PATCH net 9/9] netfilter: xt_physdev: masks are not c-strings
From: Florian Westphal @ 2026-07-10 14:37 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260710143733.29741-1-fw@strlen.de>
... and must not be subjected to the 'nul terminated' constraint.
If the interface name is 15 characters long, the mask is 16-bytes
'0xff' (to cover for \0) and the valid device name is rejected.
Fixes: 8df772afc9d0 ("netfilter: x_physdev: reject empty or not-nul terminated device names")
Closes: https://bugs.launchpad.net/neutron/+bug/2159935
Cc: stable@vger.kernel.org
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/xt_physdev.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index dd98f758176c..a388881c68d4 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -130,11 +130,6 @@ static int physdev_mt_check(const struct xt_mtchk_param *par)
if (X(physoutdev))
return -ENAMETOOLONG;
}
-
- if (X(in_mask))
- return -ENAMETOOLONG;
- if (X(out_mask))
- return -ENAMETOOLONG;
#undef X
if (!brnf_probed) {
--
2.54.0
^ permalink raw reply related
* [PATCH net 8/9] ipvs: fix more places with wrong ipv6 transport offsets
From: Florian Westphal @ 2026-07-10 14:37 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260710143733.29741-1-fw@strlen.de>
From: Julian Anastasov <ja@ssi.bg>
Sashiko reports for more incorrect IPv6 transport offsets.
The app code for TCP was assuming IPv4 network header
even after the ipvsh argument was provided. This can
cause problems with apps over IPv6. As for the only
official app in the kernel tree (FTP) this problem is
harmless because we use Netfilter to mangle the FTP
ports and we do not adjust the TCP seq numbers.
Also, provide correct offset of the ICMPV6 header in
ip_vs_out_icmp_v6() for correct checksum checks when
the IPv6 packet has extension headers.
Fixes: d12e12299a69 ("ipvs: add ipv6 support to ftp")
Fixes: 2a3b791e6e11 ("IPVS: Add/adjust Netfilter hook functions and helpers for v6")
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260706101624.69471-1-zhaoyz24%40mails.tsinghua.edu.cn
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/ipvs/ip_vs_app.c | 10 ++++------
net/netfilter/ipvs/ip_vs_core.c | 3 +--
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index d54d7da58334..b0e00be85cb1 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -361,14 +361,13 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff *skb,
struct ip_vs_iphdr *ipvsh)
{
int diff;
- const unsigned int tcp_offset = ip_hdrlen(skb);
struct tcphdr *th;
__u32 seq;
- if (skb_ensure_writable(skb, tcp_offset + sizeof(*th)))
+ if (skb_ensure_writable(skb, ipvsh->len + sizeof(*th)))
return 0;
- th = (struct tcphdr *)(skb_network_header(skb) + tcp_offset);
+ th = (struct tcphdr *)(skb_network_header(skb) + ipvsh->len);
/*
* Remember seq number in case this pkt gets resized
@@ -438,14 +437,13 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb,
struct ip_vs_iphdr *ipvsh)
{
int diff;
- const unsigned int tcp_offset = ip_hdrlen(skb);
struct tcphdr *th;
__u32 seq;
- if (skb_ensure_writable(skb, tcp_offset + sizeof(*th)))
+ if (skb_ensure_writable(skb, ipvsh->len + sizeof(*th)))
return 0;
- th = (struct tcphdr *)(skb_network_header(skb) + tcp_offset);
+ th = (struct tcphdr *)(skb_network_header(skb) + ipvsh->len);
/*
* Remember seq number in case this pkt gets resized
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 35cbe821c259..bafab93451d0 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1219,8 +1219,7 @@ static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
snet.in6 = ciph.saddr.in6;
offset = ciph.len;
return handle_response_icmp(AF_INET6, skb, &snet, ciph.protocol, cp,
- pp, offset, sizeof(struct ipv6hdr),
- hooknum);
+ pp, offset, ipvsh->len, hooknum);
}
#endif
--
2.54.0
^ permalink raw reply related
* [PATCH net 7/9] ipvs: reload ip header after head reallocation
From: Florian Westphal @ 2026-07-10 14:37 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260710143733.29741-1-fw@strlen.de>
__ip_vs_get_out_rt() calls skb_ensure_writable() which may
reallocate skb->head.
Fixes: 8d8e20e2d7bb ("ipvs: Decrement ttl")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/ipvs/ip_vs_xmit.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index ce542ed4b013..9fef4335da13 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -736,13 +736,11 @@ int
ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
struct ip_vs_protocol *pp, struct ip_vs_iphdr *ipvsh)
{
- struct iphdr *iph = ip_hdr(skb);
-
- if (__ip_vs_get_out_rt(cp->ipvs, cp->af, skb, NULL, iph->daddr,
+ if (__ip_vs_get_out_rt(cp->ipvs, cp->af, skb, NULL, ip_hdr(skb)->daddr,
IP_VS_RT_MODE_NON_LOCAL, NULL, ipvsh) < 0)
goto tx_error;
- ip_send_check(iph);
+ ip_send_check(ip_hdr(skb));
/* Another hack: avoid icmp_send in ip_fragment */
skb->ignore_df = 1;
--
2.54.0
^ permalink raw reply related
* [PATCH net 6/9] netfilter: flowtable: use correct direction to set up tunnel route
From: Florian Westphal @ 2026-07-10 14:37 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260710143733.29741-1-fw@strlen.de>
From: Pablo Neira Ayuso <pablo@netfilter.org>
The layer 2 encapsulation and layer 3 tunnel information in the xmit
path is taken from the other tuple, because the tunnel information that
is included in the tuple for hashtable lookups is also used to perform
the egress encapsulation in the transmit path.
This patch uses the correct direction when setting up the tunnel, the
original proposed patch to address this fix uses the reversed direction.
While at it, remove the redundant check to call dst_release() to drop
the reference on the dst that was obtained from the forward path, which
is not useful in the direct xmit path unless tunneling is performed.
Fixes: fa7395c02d95 ("netfilter: flowtable: support IPIP tunnel with direct xmit")
Cc: stable@vger.kernel.org
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/nf_flow_table_core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index 2a829b5e8240..b66e65439341 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -127,18 +127,18 @@ static int flow_offload_fill_route(struct flow_offload *flow,
switch (route->tuple[dir].xmit_type) {
case FLOW_OFFLOAD_XMIT_DIRECT:
- if (flow_tuple->tun_num) {
+ if (route->tuple[!dir].in.num_tuns) {
flow_tuple->dst_cache = dst;
flow_tuple->dst_cookie =
flow_offload_dst_cookie(flow_tuple);
+ } else {
+ dst_release(dst);
}
memcpy(flow_tuple->out.h_dest, route->tuple[dir].out.h_dest,
ETH_ALEN);
memcpy(flow_tuple->out.h_source, route->tuple[dir].out.h_source,
ETH_ALEN);
flow_tuple->out.ifidx = route->tuple[dir].out.ifindex;
- if (!flow_tuple->tun_num)
- dst_release(dst);
break;
case FLOW_OFFLOAD_XMIT_XFRM:
case FLOW_OFFLOAD_XMIT_NEIGH:
--
2.54.0
^ permalink raw reply related
* [PATCH net 5/9] selftests: netfilter: add bridge tunnel flowtable regression
From: Florian Westphal @ 2026-07-10 14:37 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260710143733.29741-1-fw@strlen.de>
From: Zhengyang Chen <chzhengyang2023@lzu.edu.cn>
Add a nft_flowtable.sh regression test for the bridge direct-xmit plus
IPIP/IP6IP6 underlay configuration that reproduces the reachable
DIRECT+tunnel tuple combination exercised by the flowtable fix.
The test reuses the existing bridge and tunnel topology, installs flow
rules for the tunnel egress and bridge reply path, verifies IPv4 and
IPv6 forwarding, and checks the flowtable counters after the transfer.
Signed-off-by: Zhengyang Chen <chzhengyang2023@lzu.edu.cn>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
.../selftests/net/netfilter/nft_flowtable.sh | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/tools/testing/selftests/net/netfilter/nft_flowtable.sh b/tools/testing/selftests/net/netfilter/nft_flowtable.sh
index 08ad07500e8a..fb1c59d45567 100755
--- a/tools/testing/selftests/net/netfilter/nft_flowtable.sh
+++ b/tools/testing/selftests/net/netfilter/nft_flowtable.sh
@@ -736,6 +736,61 @@ if ! test_tcp_forwarding_nat "$ns1" "$ns2" 1 "on bridge"; then
ret=1
fi
+if ip -net "$nsr1" link show tun0 > /dev/null 2>&1 &&
+ ip -net "$nsr2" link show tun0 > /dev/null 2>&1; then
+ ip -net "$nsr1" route change default via 192.168.100.2
+ ip -net "$nsr2" route change default via 192.168.100.1
+ ip -6 -net "$nsr1" route delete default
+ ip -6 -net "$nsr1" route add default via fee1:3::2
+ ip -6 -net "$nsr2" route delete default
+ ip -6 -net "$nsr2" route add default via fee1:3::1
+ ip -net "$ns2" route add default via 10.0.2.1
+ ip -6 -net "$ns2" route add default via dead:2::1
+
+ ip netns exec "$nsr1" nft -a insert rule inet filter forward \
+ 'meta oif "tun0" tcp dport 12345 ct mark set 1 flow add @f1 counter name routed_orig accept'
+ ip netns exec "$nsr1" nft -a insert rule inet filter forward \
+ 'meta oif "tun6" tcp dport 12345 ct mark set 1 flow add @f1 counter name routed_orig accept'
+ ip netns exec "$nsr1" nft -a insert rule inet filter forward \
+ 'meta oif "veth0" tcp sport 12345 ct mark set 1 flow add @f1 counter name routed_repl accept'
+ ip netns exec "$nsr1" nft -a insert rule inet filter forward \
+ 'meta oif "br0" tcp sport 12345 ct mark set 1 flow add @f1 counter name routed_repl accept'
+ ip netns exec "$nsr1" nft -a insert rule inet filter forward \
+ 'meta oif "tun0" accept'
+ ip netns exec "$nsr1" nft -a insert rule inet filter forward \
+ 'meta oif "tun6" accept'
+
+ ip netns exec "$nsr1" nft reset counters table inet filter >/dev/null
+
+ if test_tcp_forwarding "$ns1" "$ns2" 1 4 10.0.2.99 12345; then
+ check_counters "bridge + IPIP tunnel"
+ else
+ echo "FAIL: flow offload for ns1/ns2 with bridge + IPIP tunnel" 1>&2
+ ip netns exec "$nsr1" nft list ruleset
+ ret=1
+ fi
+
+ if test_tcp_forwarding "$ns1" "$ns2" 1 6 "[dead:2::99]" 12345; then
+ check_counters "bridge + IP6IP6 tunnel"
+ else
+ echo "FAIL: flow offload for ns1/ns2 with bridge + IP6IP6 tunnel" 1>&2
+ ip netns exec "$nsr1" nft list ruleset
+ ret=1
+ fi
+
+ ip -net "$nsr1" route change default via 192.168.10.2
+ ip -net "$nsr2" route change default via 192.168.10.1
+ ip -net "$ns2" route del default via 10.0.2.1
+ ip -6 -net "$nsr1" route delete default
+ ip -6 -net "$nsr1" route add default via fee1:2::2
+ ip -6 -net "$nsr2" route delete default
+ ip -6 -net "$nsr2" route add default via fee1:2::1
+ ip -6 -net "$ns2" route del default via dead:2::1
+else
+ echo "SKIP: bridge + tunnel flowtable regression (tun0 missing)"
+ [ "$ret" -eq 0 ] && ret=$ksft_skip
+fi
+
# Another test:
# Add bridge interface br0 to Router1, with NAT and VLAN.
--
2.54.0
^ permalink raw reply related
* [PATCH net 4/9] netfilter: nf_conncount: fix zone comparison in tuple dedup
From: Florian Westphal @ 2026-07-10 14:37 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260710143733.29741-1-fw@strlen.de>
From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
The "already exists" dedup logic in __nf_conncount_add() decides
whether a connection has already been counted and can be skipped instead
of incrementing the connlimit count. It compares the conntrack zone of a
list entry with the zone of the connection being added using
nf_ct_zone_id() and nf_ct_zone_equal(), passing conn->zone.dir or
zone->dir as the direction argument.
Those helpers take enum ip_conntrack_dir values: IP_CT_DIR_ORIGINAL is 0
and IP_CT_DIR_REPLY is 1. However, zone->dir is a u8 bitmask:
NF_CT_ZONE_DIR_ORIG is 1, NF_CT_ZONE_DIR_REPL is 2 and
NF_CT_DEFAULT_ZONE_DIR is 3. Passing that bitmask as the enum direction
shifts the meaning of every non-zero value. An ORIG-only zone passes 1
and is tested as REPLY, while REPL-only and default zones pass 2 or 3 and
test bits beyond the valid direction range. In those cases
nf_ct_zone_id() can fall back to NF_CT_DEFAULT_ZONE_ID instead of using
the real zone id, so different zones can be treated as equal and dedup
collapses to tuple equality alone.
nf_conncount stores and compares the original-direction tuple for a
connection. If an skb already has an attached conntrack entry,
get_ct_or_tuple_from_skb() explicitly copies
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, regardless of the packet's
ctinfo. Therefore the zone comparison in the tuple dedup path must use
IP_CT_DIR_ORIGINAL as well; the zone direction bitmask describes where a
zone id applies, not which direction this conncount tuple represents.
Fix the two dedup comparisons by passing IP_CT_DIR_ORIGINAL directly.
Do not special-case NF_CT_DEFAULT_ZONE_DIR and do not compare raw zone
ids: using the existing helpers with IP_CT_DIR_ORIGINAL preserves the
direction-aware NF_CT_DEFAULT_ZONE_ID fallback. A default bidirectional
zone contains the ORIG bit, so it naturally returns the real zone id;
reply-only zones continue to fall back for original-direction tuple
comparisons.
Fixes: 21ba8847f857 ("netfilter: nf_conncount: Fix garbage collection with zones")
Fixes: b36e4523d4d5 ("netfilter: nf_conncount: fix garbage collection confirm race")
Cc: stable@vger.kernel.org
Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
Reported-by: Ao Wang <wangao@seu.edu.cn>
Reported-by: Xuewei Feng <fengxw06@126.com>
Reported-by: Qi Li <qli01@tsinghua.edu.cn>
Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
Assisted-by: Claude-Code:GLM-5.2
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/nf_conncount.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
index 91582069f6d2..e9ea6d9466e7 100644
--- a/net/netfilter/nf_conncount.c
+++ b/net/netfilter/nf_conncount.c
@@ -211,8 +211,8 @@ static int __nf_conncount_add(struct net *net,
/* Not found, but might be about to be confirmed */
if (PTR_ERR(found) == -EAGAIN) {
if (nf_ct_tuple_equal(&conn->tuple, &tuple) &&
- nf_ct_zone_id(&conn->zone, conn->zone.dir) ==
- nf_ct_zone_id(zone, zone->dir))
+ nf_ct_zone_id(&conn->zone, IP_CT_DIR_ORIGINAL) ==
+ nf_ct_zone_id(zone, IP_CT_DIR_ORIGINAL))
goto out_put; /* already exists */
} else {
collect++;
@@ -223,7 +223,7 @@ static int __nf_conncount_add(struct net *net,
found_ct = nf_ct_tuplehash_to_ctrack(found);
if (nf_ct_tuple_equal(&conn->tuple, &tuple) &&
- nf_ct_zone_equal(found_ct, zone, zone->dir)) {
+ nf_ct_zone_equal(found_ct, zone, IP_CT_DIR_ORIGINAL)) {
/*
* We should not see tuples twice unless someone hooks
* this into a table without "-p tcp --syn".
--
2.54.0
^ permalink raw reply related
* [PATCH net 3/9] netfilter: bridge: fix stale prevhdr pointer in br_ip6_fragment()
From: Florian Westphal @ 2026-07-10 14:37 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260710143733.29741-1-fw@strlen.de>
From: "Xiang Mei (Microsoft)" <xmei5@asu.edu>
br_ip6_fragment() gets prevhdr, a pointer into the skb head, from
ip6_find_1stfragopt(), then calls skb_checksum_help(). For a cloned skb
skb_checksum_help() reallocates the head via pskb_expand_head(), leaving
prevhdr dangling. It is later dereferenced in ip6_frag_next(), causing a
use-after-free write.
Save prevhdr's offset before skb_checksum_help() and recompute it after,
like commit ef0efcd3bd3f ("ipv6: Fix dangling pointer when ipv6
fragment").
BUG: KASAN: slab-use-after-free in ip6_frag_next (net/ipv6/ip6_output.c:857)
Write of size 1 at addr ffff888013ff5016 by task exploit/141
Call Trace:
...
kasan_report (mm/kasan/report.c:595)
ip6_frag_next (net/ipv6/ip6_output.c:857)
br_ip6_fragment (net/ipv6/netfilter.c:212)
nf_ct_bridge_post (net/bridge/netfilter/nf_conntrack_bridge.c:407)
nf_hook_slow (net/netfilter/core.c:619)
br_forward_finish (net/bridge/br_forward.c:66)
__br_forward (net/bridge/br_forward.c:115)
maybe_deliver (net/bridge/br_forward.c:191)
br_flood (net/bridge/br_forward.c:245)
br_handle_frame_finish (net/bridge/br_input.c:229)
br_handle_frame (net/bridge/br_input.c:442)
...
packet_sendmsg (net/packet/af_packet.c:3114)
...
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
Kernel panic - not syncing: Fatal exception in interrupt
Fixes: 764dd163ac92 ("netfilter: nf_conntrack_bridge: add support for IPv6")
Cc: stable@vger.kernel.org
Reported-by: AutonomousCodeSecurity@microsoft.com
Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/ipv6/netfilter.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 6d80f85e55fa..a7025ec87035 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -120,7 +120,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
ktime_t tstamp = skb->tstamp;
struct ip6_frag_state state;
u8 *prevhdr, nexthdr = 0;
- unsigned int mtu, hlen;
+ unsigned int mtu, hlen, nexthdr_offset;
int hroom, err = 0;
__be32 frag_id;
@@ -129,6 +129,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
goto blackhole;
hlen = err;
nexthdr = *prevhdr;
+ nexthdr_offset = prevhdr - skb_network_header(skb);
mtu = skb->dev->mtu;
if (frag_max_size > mtu ||
@@ -147,6 +148,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
(err = skb_checksum_help(skb)))
goto blackhole;
+ prevhdr = skb_network_header(skb) + nexthdr_offset;
hroom = LL_RESERVED_SPACE(skb->dev);
if (skb_has_frag_list(skb)) {
unsigned int first_len = skb_pagelen(skb);
--
2.54.0
^ permalink raw reply related
* [PATCH net 1/9] netfilter: xt_nat: reject unsupported target families
From: Florian Westphal @ 2026-07-10 14:37 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260710143733.29741-1-fw@strlen.de>
From: Wyatt Feng <bronzed_45_vested@icloud.com>
xt_nat SNAT and DNAT target handlers assume IP-family conntrack state
is present and can dereference a NULL pointer when instantiated from an
unsupported family through nft_compat. A bridge-family compat rule can
therefore trigger a NULL-dereference in nf_nat_setup_info().
Reject non-IP families in xt_nat_checkentry() so unsupported targets
cannot be installed. Keep NFPROTO_INET allowed for valid inet NAT
compat users and leave the runtime fast path unchanged.
[ The crash was fixed via
9dbba7e694ec ("netfilter: nft_compat: ebtables emulation must reject non-bridge targets"),
so this patch is no longer critical.
Nevertheless, NAT is only relevant for ipv4/ipv6, so this extra
family check is a good idea in any case. ]
Fixes: c7232c9979cb ("netfilter: add protocol independent NAT core")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Wyatt Feng <bronzed_45_vested@icloud.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/xt_nat.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/netfilter/xt_nat.c b/net/netfilter/xt_nat.c
index b4f7bbc3f3ca..51c7f7ce88d9 100644
--- a/net/netfilter/xt_nat.c
+++ b/net/netfilter/xt_nat.c
@@ -26,6 +26,15 @@ static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
static int xt_nat_checkentry(const struct xt_tgchk_param *par)
{
+ switch (par->family) {
+ case NFPROTO_IPV4:
+ case NFPROTO_IPV6:
+ case NFPROTO_INET:
+ break;
+ default:
+ return -EINVAL;
+ }
+
return nf_ct_netns_get(par->net, par->family);
}
--
2.54.0
^ 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