* [PATCH] netfilter: nf_conntrack_helper: pass helper to expect cleanup
From: Qi Tang @ 2026-03-29 16:50 UTC (permalink / raw)
To: Pablo Neira Ayuso, Florian Westphal
Cc: Phil Sutter, netfilter-devel, coreteam, netdev, Qi Tang
nf_conntrack_helper_unregister() calls nf_ct_expect_iterate_destroy()
to remove expectations belonging to the helper being unregistered.
However, it passes NULL instead of the helper pointer as the data
argument, so expect_iter_me() never matches any expectation and all
of them survive the cleanup.
After unregister returns, nfnl_cthelper_del() frees the helper
object immediately. Subsequent expectation dumps or packet-driven
init_conntrack() calls then dereference the freed exp->helper,
causing a use-after-free.
Pass the actual helper pointer so expectations referencing it are
properly destroyed before the helper object is freed.
BUG: KASAN: slab-use-after-free in string+0x38f/0x430
Read of size 1 at addr ffff888003b14d20 by task poc/103
Call Trace:
string+0x38f/0x430
vsnprintf+0x3cc/0x1170
seq_printf+0x17a/0x240
exp_seq_show+0x2e5/0x560
seq_read_iter+0x419/0x1280
proc_reg_read+0x1ac/0x270
vfs_read+0x179/0x930
ksys_read+0xef/0x1c0
Freed by task 103:
The buggy address is located 32 bytes inside of
freed 192-byte region [ffff888003b14d00, ffff888003b14dc0)
Fixes: ac7b84839003 ("netfilter: expect: add and use nf_ct_expect_iterate helpers")
Signed-off-by: Qi Tang <tpluszz77@gmail.com>
---
net/netfilter/nf_conntrack_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 1b330ba6613b..a715304a53d8 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -415,7 +415,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
*/
synchronize_rcu();
- nf_ct_expect_iterate_destroy(expect_iter_me, NULL);
+ nf_ct_expect_iterate_destroy(expect_iter_me, me);
nf_ct_iterate_destroy(unhelp, me);
/* nf_ct_iterate_destroy() does an unconditional synchronize_rcu() as
--
2.43.0
^ permalink raw reply related
* [PATCH] netfilter: ctnetlink: validate expect class against master helper
From: Qi Tang @ 2026-03-29 16:51 UTC (permalink / raw)
To: Pablo Neira Ayuso, Florian Westphal
Cc: Phil Sutter, netfilter-devel, coreteam, netdev, Qi Tang
ctnetlink_alloc_expect() validates CTA_EXPECT_CLASS against the
helper specified by CTA_EXPECT_HELP_NAME. However,
__nf_ct_expect_check() and nf_ct_expect_insert() later index the
expect_policy array using the master conntrack's actual helper.
When the supplied helper has a larger expect_class_max than the
master's helper, the class passes validation but produces an
out-of-bounds read on the master helper's heap-allocated policy
array during expectation insertion.
Validate the class against the master conntrack's own helper
instead, since that is the helper whose policy array will actually
be indexed.
BUG: KASAN: slab-out-of-bounds in nf_ct_expect_related_report+0x2479/0x27c0
Read of size 4 at addr ffff8880043fe408 by task poc/102
Call Trace:
nf_ct_expect_related_report+0x2479/0x27c0
ctnetlink_create_expect+0x22b/0x3b0
ctnetlink_new_expect+0x4bd/0x5c0
nfnetlink_rcv_msg+0x67a/0x950
netlink_rcv_skb+0x120/0x350
Fixes: b8c5e52c13ed ("netfilter: ctnetlink: allow to set expectation class")
Signed-off-by: Qi Tang <tpluszz77@gmail.com>
---
net/netfilter/nf_conntrack_netlink.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 3f408f3713bb..c57c665363e0 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3542,9 +3542,14 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
if (!help)
return ERR_PTR(-EOPNOTSUPP);
- if (cda[CTA_EXPECT_CLASS] && helper) {
+ if (cda[CTA_EXPECT_CLASS]) {
+ struct nf_conntrack_helper *master_helper;
+
+ master_helper = rcu_dereference(help->helper);
+ if (!master_helper)
+ return ERR_PTR(-EOPNOTSUPP);
class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS]));
- if (class > helper->expect_class_max)
+ if (class > master_helper->expect_class_max)
return ERR_PTR(-EINVAL);
}
exp = nf_ct_expect_alloc(ct);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2] selftests/bpf: Reject malformed IPv4/IPv6 skb test input
From: bot+bpf-ci @ 2026-03-29 16:52 UTC (permalink / raw)
To: sun.jian.kdev, ast, daniel, andrii
Cc: martin.lau, eddyz87, song, yonghong.song, john.fastabend, kpsingh,
sdf, haoluo, jolsa, davem, edumazet, kuba, pabeni, horms, bpf,
netdev, linux-kernel, sun.jian.kdev, syzbot+619b9ef527f510a57cfc,
ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
In-Reply-To: <20260329161751.1914272-1-sun.jian.kdev@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 654 bytes --]
> Reported-by: syzbot+619b9ef527f510a57cfc@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=619b9ef527f510a57cfc
> Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com>
This patch fixes a bug that has existed since bpf_prog_test_run_skb()
was first introduced. Should it carry a Fixes: tag pointing at the
original commit?
Fixes: 1cf1cae963c2 ("bpf: introduce BPF_PROG_TEST_RUN command")
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/23713682616
^ permalink raw reply
* [PATCH] netfilter: ctnetlink: zero expect NAT fields when CTA_EXPECT_NAT absent
From: Qi Tang @ 2026-03-29 16:52 UTC (permalink / raw)
To: Pablo Neira Ayuso, Florian Westphal
Cc: Phil Sutter, netfilter-devel, coreteam, netdev, Qi Tang
ctnetlink_alloc_expect() allocates expectations from a non-zeroing
slab cache via nf_ct_expect_alloc(). When CTA_EXPECT_NAT is not
present in the netlink message, saved_addr and saved_proto are
never initialized. Stale data from a previous slab occupant can
then be dumped to userspace by ctnetlink_exp_dump_expect(), which
checks these fields to decide whether to emit CTA_EXPECT_NAT.
The safe sibling nf_ct_expect_init(), used by the packet path,
explicitly zeroes these fields.
Zero saved_addr and saved_proto in the else branch so that
expectations created without NAT metadata cannot leak kernel heap
contents to userspace.
Confirmed by priming the expect slab with NAT-bearing expectations,
freeing them, creating a new expectation without CTA_EXPECT_NAT,
and observing that the ctnetlink dump emits a spurious
CTA_EXPECT_NAT containing stale data from the prior allocation.
Fixes: 076a0ca02644 ("netfilter: ctnetlink: add NAT support for expectations")
Signed-off-by: Qi Tang <tpluszz77@gmail.com>
---
net/netfilter/nf_conntrack_netlink.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index c57c665363e0..c152079f5ac7 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3593,6 +3593,10 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
exp, nf_ct_l3num(ct));
if (err < 0)
goto err_out;
+ } else {
+ memset(&exp->saved_addr, 0, sizeof(exp->saved_addr));
+ memset(&exp->saved_proto, 0, sizeof(exp->saved_proto));
+ exp->dir = 0;
}
return exp;
err_out:
--
2.43.0
^ permalink raw reply related
* [PATCH] net/sched: skip reverse bind walk after failed class delete
From: Qi Tang @ 2026-03-29 16:53 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko
Cc: Cong Wang, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, netdev, Qi Tang
__tc_ctl_tclass() unconditionally calls tc_bind_tclass() after
RTM_DELTCLASS even when tclass_del_notify() fails. On
ingress/clsact qdiscs with shared blocks, the delete always fails
with -EOPNOTSUPP, but the subsequent bind walk still runs.
tc_bind_tclass() reaches tcf_node_bind() which calls tcf_block_q()
on the shared block and dereferences the NULL qdisc pointer.
Only perform the reverse bind walk when the class delete succeeds.
Triggered by issuing RTM_DELTCLASS on an ingress/clsact pseudo-class
that carries a shared block with a classifier using bind_class:
$ tc qdisc add dev veth0 egress_block 22 clsact
$ tc filter add block 22 pref 1 protocol ip handle 0x1 \
fw classid ffff:fff3 action drop
$ tc class del dev veth0 classid ffff:fff3
RTNETLINK answers: Operation not supported
Kernel panic - not syncing: Attempted to kill init!
exitcode=0x00000700
The NULL dereference occurs in tcf_node_bind() when sch_tree_lock()
is called with the NULL return from tcf_block_q() on a shared block.
Fixes: 07d79fc7d94e ("net_sched: add reverse binding for tc class")
Signed-off-by: Qi Tang <tpluszz77@gmail.com>
---
net/sched/sch_api.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index cc43e3f7574f..50d311ff1f2d 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -2251,7 +2251,8 @@ static int __tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
case RTM_DELTCLASS:
err = tclass_del_notify(net, cops, skb, n, q, cl, extack);
/* Unbind the class with flilters with 0 */
- tc_bind_tclass(q, portid, clid, 0);
+ if (!err)
+ tc_bind_tclass(q, portid, clid, 0);
goto out;
case RTM_GETTCLASS:
err = tclass_get_notify(net, skb, n, q, cl, extack);
--
2.43.0
^ permalink raw reply related
* [PATCH] net/sched: cls_flow: reject baseclass resolution on shared blocks
From: Qi Tang @ 2026-03-29 16:53 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, netdev, Qi Tang
flow_change() calls tcf_block_q() and immediately dereferences the
returned qdisc pointer to resolve a zero-major baseclass handle.
On shared blocks, tcf_block_q() returns NULL because no qdisc owns
the block, causing a NULL pointer dereference.
Check for NULL before dereferencing and return -EOPNOTSUPP, since
shared blocks have no qdisc handle to derive the major number from.
Triggered by creating a cls_flow filter on a shared block without
a non-zero-major TCA_FLOW_BASECLASS:
Kernel panic - not syncing: kernel: panic_on_warn set ...
Call Trace:
<TASK>
check_panic_on_warn+0x5d/0x80
__warn+0xe7/0x300
flow_change+0x1422/0x1900
report_bug+0x9a/0x1e0
handle_bug+0x14c/0x360
exc_invalid_op+0x13/0x40
asm_exc_invalid_op+0x16/0x20
RIP: 0010:flow_change+0x1422/0x1900
tc_new_tfilter+0x92b/0x2060
rtnetlink_rcv_msg+0x758/0xab0
netlink_rcv_skb+0x120/0x350
netlink_unicast+0x755/0xaa0
netlink_sendmsg+0x787/0xc30
____sys_sendmsg+0x8b6/0xb00
___sys_sendmsg+0xed/0x170
__sys_sendmsg+0x107/0x1a0
do_syscall_64+0xe0/0x1290
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Fixes: 1abf272022cf ("net: sched: tcindex, fw, flow: use tcf_block_q helper to get struct Qdisc")
Signed-off-by: Qi Tang <tpluszz77@gmail.com>
---
net/sched/cls_flow.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 339c664beff6..ad8b4c375d1c 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -505,6 +505,10 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
if (TC_H_MAJ(baseclass) == 0) {
struct Qdisc *q = tcf_block_q(tp->chain->block);
+ if (!q) {
+ err = -EOPNOTSUPP;
+ goto err2;
+ }
baseclass = TC_H_MAKE(q->handle, baseclass);
}
if (TC_H_MIN(baseclass) == 0)
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v3 net-next] net: hsr: sync hw addr of slave2 according to slave1 hw addr on PRP
From: Fernando Fernandez Mancera @ 2026-03-29 16:58 UTC (permalink / raw)
To: Luka Gejak, Fernando Fernandez Mancera, netdev
Cc: edumazet, pabeni, shannon.nelson, horms, lukma, kuba
In-Reply-To: <DHFCZEM93FTT.1RWFBIE32K7OT@linux.dev>
On 3/29/26 5:07 PM, Luka Gejak wrote:
> On Wed Apr 9, 2025 at 12:19 PM CEST, Fernando Fernandez Mancera wrote:
>> In order to work properly PRP requires slave1 and slave2 to share the
>> same MAC address. To ease the configuration process on userspace tools,
>> sync the slave2 MAC address with slave1. In addition, when deleting the
>> port from the list, restore the original MAC address.
>>
>> Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
>> ---
>> v3: restore the original MAC address on slave removal.
>> ---
>> net/hsr/hsr_device.c | 5 +++++
>> net/hsr/hsr_main.c | 9 +++++++++
>> net/hsr/hsr_main.h | 1 +
>> net/hsr/hsr_slave.c | 2 ++
>> 4 files changed, 17 insertions(+)
>>
>> diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
>> index 439cfb7ad5d1..e8922e8d9398 100644
>> --- a/net/hsr/hsr_device.c
>> +++ b/net/hsr/hsr_device.c
>> @@ -761,6 +761,11 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
>> if (res)
>> goto err_unregister;
>>
>> + if (protocol_version == PRP_V1) {
>> + eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>> + call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>> + }
>> +
>> if (interlink) {
>> res = hsr_add_port(hsr, interlink, HSR_PT_INTERLINK, extack);
>> if (res)
>> diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c
>> index d7ae32473c41..192893c3f2ec 100644
>> --- a/net/hsr/hsr_main.c
>> +++ b/net/hsr/hsr_main.c
>> @@ -78,6 +78,15 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
>> eth_hw_addr_set(master->dev, dev->dev_addr);
>> call_netdevice_notifiers(NETDEV_CHANGEADDR,
>> master->dev);
>> +
>> + if (hsr->prot_version == PRP_V1) {
>> + port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
>> + if (port) {
>> + eth_hw_addr_set(port->dev, dev->dev_addr);
>> + call_netdevice_notifiers(NETDEV_CHANGEADDR,
>> + port->dev);
>> + }
>> + }
>> }
>>
>> /* Make sure we recognize frames from ourselves in hsr_rcv() */
>> diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
>> index 1bc47b17a296..135ec5fce019 100644
>> --- a/net/hsr/hsr_main.h
>> +++ b/net/hsr/hsr_main.h
>> @@ -155,6 +155,7 @@ struct hsr_port {
>> struct hsr_priv *hsr;
>> enum hsr_port_type type;
>> struct rcu_head rcu;
>> + unsigned char original_macaddress[ETH_ALEN];
>> };
>>
>> struct hsr_frame_info;
>> diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
>> index 2a802a5de2ac..b87b6a6fe070 100644
>> --- a/net/hsr/hsr_slave.c
>> +++ b/net/hsr/hsr_slave.c
>> @@ -196,6 +196,7 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev,
>> port->hsr = hsr;
>> port->dev = dev;
>> port->type = type;
>> + ether_addr_copy(port->original_macaddress, dev->dev_addr);
>>
>> if (type != HSR_PT_MASTER) {
>> res = hsr_portdev_setup(hsr, dev, port, extack);
>> @@ -232,6 +233,7 @@ void hsr_del_port(struct hsr_port *port)
>> if (!port->hsr->fwd_offloaded)
>> dev_set_promiscuity(port->dev, -1);
>> netdev_upper_dev_unlink(port->dev, master->dev);
>> + eth_hw_addr_set(port->dev, port->original_macaddress);
>> }
>>
>> kfree_rcu(port, rcu);
>
> Hi Fernando,
>
> Thanks for the patch. The logic to sync the slave2 MAC address with
> slave1 for PRP is sound, but there are a few implementation issues here
> that will cause hardware filtering problems and style violations.
>
> 1. Hardware MAC Filtering
> In your current implementation:
>
> if (protocol_version == PRP_V1) {
>
> eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>
> call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>
> }
>
> eth_hw_addr_set() is appropriate for virtual devices (like the hsr_dev
> itself), but slave[1] is a physical net_device. By using this helper,
> you are bypassing dev->netdev_ops->ndo_set_mac_address. This means the
> physical NIC's hardware MAC filter will not be programmed, and it will
> silently drop unicast traffic destined for the new PRP MAC address
> unless the interface happens to be in promiscuous mode. You should use
> dev_set_mac_address() here instead. Note that unlike eth_hw_addr_set(),
> dev_set_mac_address() can fail and returns an error code, so you will
> need to check its return value and handle the error path accordingly.
>
> 2. Teardown Notifiers
> In hsr_del_port():
>
> netdev_upper_dev_unlink(port->dev, master->dev);
> eth_hw_addr_set(port->dev, port->original_macaddress);
>
> You have the same issue with eth_hw_addr_set() here. Additionally,
> unlike the setup paths, this version omits call_netdevice_notifiers
> (NETDEV_CHANGEADDR, port->dev). Switching to dev_set_mac_address() for
> the restoration will handle both the hardware programming and the
> notifier chain automatically.
>
These points makes sense. I guess I didn't notice the that
eth_hw_addr_set() due to my interface being set to promiscuous mode at
hsr_slave.c.
Let me research a bit more about the impact here and will get back to
you either with a new patch or an reply here.
> 3. Coding Style
> In hsr_main.h:
>
> unsigned char original_macaddress[ETH_ALEN];
>
> Please use u8 instead of unsigned char for byte arrays to align with
> standard netdev coding styles.
>
I used `unsigned char` because it was already used around HSR code
already, so I chose consistency. If there is a preference for u8 over
unsigned char I could change it.
> Please address these points and submit a v4.
>
Well, this is almost a year old so I am sending a fix instead. Is this
some kind of automated bot going through all the patches in netdev
mailing list? I am a bit confused about receiving a patch review a year
later.
> Best regards,
> Luka Gejak
>
^ permalink raw reply
* Re: [PATCH v3 net-next] net: hsr: sync hw addr of slave2 according to slave1 hw addr on PRP
From: Luka Gejak @ 2026-03-29 17:19 UTC (permalink / raw)
To: Fernando Fernandez Mancera, Fernando Fernandez Mancera, netdev
Cc: edumazet, pabeni, shannon.nelson, horms, lukma, kuba, luka.gejak
In-Reply-To: <856eb43a-d4d0-4e1e-895f-75fca4eec51d@suse.de>
On March 29, 2026 6:58:38 PM GMT+02:00, Fernando Fernandez Mancera <fmancera@suse.de> wrote:
>On 3/29/26 5:07 PM, Luka Gejak wrote:
>> On Wed Apr 9, 2025 at 12:19 PM CEST, Fernando Fernandez Mancera wrote:
>>> In order to work properly PRP requires slave1 and slave2 to share the
>>> same MAC address. To ease the configuration process on userspace tools,
>>> sync the slave2 MAC address with slave1. In addition, when deleting the
>>> port from the list, restore the original MAC address.
>>>
>>> Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
>>> ---
>>> v3: restore the original MAC address on slave removal.
>>> ---
>>> net/hsr/hsr_device.c | 5 +++++
>>> net/hsr/hsr_main.c | 9 +++++++++
>>> net/hsr/hsr_main.h | 1 +
>>> net/hsr/hsr_slave.c | 2 ++
>>> 4 files changed, 17 insertions(+)
>>>
>>> diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
>>> index 439cfb7ad5d1..e8922e8d9398 100644
>>> --- a/net/hsr/hsr_device.c
>>> +++ b/net/hsr/hsr_device.c
>>> @@ -761,6 +761,11 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
>>> if (res)
>>> goto err_unregister;
>>> + if (protocol_version == PRP_V1) {
>>> + eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>>> + }
>>> +
>>> if (interlink) {
>>> res = hsr_add_port(hsr, interlink, HSR_PT_INTERLINK, extack);
>>> if (res)
>>> diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c
>>> index d7ae32473c41..192893c3f2ec 100644
>>> --- a/net/hsr/hsr_main.c
>>> +++ b/net/hsr/hsr_main.c
>>> @@ -78,6 +78,15 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
>>> eth_hw_addr_set(master->dev, dev->dev_addr);
>>> call_netdevice_notifiers(NETDEV_CHANGEADDR,
>>> master->dev);
>>> +
>>> + if (hsr->prot_version == PRP_V1) {
>>> + port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
>>> + if (port) {
>>> + eth_hw_addr_set(port->dev, dev->dev_addr);
>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR,
>>> + port->dev);
>>> + }
>>> + }
>>> }
>>> /* Make sure we recognize frames from ourselves in hsr_rcv() */
>>> diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
>>> index 1bc47b17a296..135ec5fce019 100644
>>> --- a/net/hsr/hsr_main.h
>>> +++ b/net/hsr/hsr_main.h
>>> @@ -155,6 +155,7 @@ struct hsr_port {
>>> struct hsr_priv *hsr;
>>> enum hsr_port_type type;
>>> struct rcu_head rcu;
>>> + unsigned char original_macaddress[ETH_ALEN];
>>> };
>>> struct hsr_frame_info;
>>> diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
>>> index 2a802a5de2ac..b87b6a6fe070 100644
>>> --- a/net/hsr/hsr_slave.c
>>> +++ b/net/hsr/hsr_slave.c
>>> @@ -196,6 +196,7 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev,
>>> port->hsr = hsr;
>>> port->dev = dev;
>>> port->type = type;
>>> + ether_addr_copy(port->original_macaddress, dev->dev_addr);
>>> if (type != HSR_PT_MASTER) {
>>> res = hsr_portdev_setup(hsr, dev, port, extack);
>>> @@ -232,6 +233,7 @@ void hsr_del_port(struct hsr_port *port)
>>> if (!port->hsr->fwd_offloaded)
>>> dev_set_promiscuity(port->dev, -1);
>>> netdev_upper_dev_unlink(port->dev, master->dev);
>>> + eth_hw_addr_set(port->dev, port->original_macaddress);
>>> }
>>> kfree_rcu(port, rcu);
>>
>> Hi Fernando,
>>
>> Thanks for the patch. The logic to sync the slave2 MAC address with
>> slave1 for PRP is sound, but there are a few implementation issues here
>> that will cause hardware filtering problems and style violations.
>>
>> 1. Hardware MAC Filtering
>> In your current implementation:
>>
>> if (protocol_version == PRP_V1) {
>>
>> eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>>
>> call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>>
>> }
>>
>> eth_hw_addr_set() is appropriate for virtual devices (like the hsr_dev
>> itself), but slave[1] is a physical net_device. By using this helper,
>> you are bypassing dev->netdev_ops->ndo_set_mac_address. This means the
>> physical NIC's hardware MAC filter will not be programmed, and it will
>> silently drop unicast traffic destined for the new PRP MAC address
>> unless the interface happens to be in promiscuous mode. You should use
>> dev_set_mac_address() here instead. Note that unlike eth_hw_addr_set(),
>> dev_set_mac_address() can fail and returns an error code, so you will
>> need to check its return value and handle the error path accordingly.
>>
>> 2. Teardown Notifiers
>> In hsr_del_port():
>>
>> netdev_upper_dev_unlink(port->dev, master->dev);
>> eth_hw_addr_set(port->dev, port->original_macaddress);
>>
>> You have the same issue with eth_hw_addr_set() here. Additionally,
>> unlike the setup paths, this version omits call_netdevice_notifiers
>> (NETDEV_CHANGEADDR, port->dev). Switching to dev_set_mac_address() for
>> the restoration will handle both the hardware programming and the
>> notifier chain automatically.
>>
>
>These points makes sense. I guess I didn't notice the that eth_hw_addr_set() due to my interface being set to promiscuous mode at hsr_slave.c.
>
>Let me research a bit more about the impact here and will get back to you either with a new patch or an reply here.
>
>> 3. Coding Style
>> In hsr_main.h:
>>
>> unsigned char original_macaddress[ETH_ALEN];
>>
>> Please use u8 instead of unsigned char for byte arrays to align with
>> standard netdev coding styles.
>>
>
>I used `unsigned char` because it was already used around HSR code already, so I chose consistency. If there is a preference for u8 over unsigned char I could change it.
>
>> Please address these points and submit a v4.
>>
>
>Well, this is almost a year old so I am sending a fix instead. Is this some kind of automated bot going through all the patches in netdev mailing list? I am a bit confused about receiving a patch review a year later.
>
>> Best regards,
>> Luka Gejak
>>
>
Hi Fernando,
I was setting up lei for the mailing list and because I didn't set it
up correctly, patches that were filtered and downloaded by lei were
older and I noticed it only later after carefully checking why patch
count was low.
Best regards,
Luka Gejak
^ permalink raw reply
* Re: [PATCH v3 net-next] net: hsr: sync hw addr of slave2 according to slave1 hw addr on PRP
From: Fernando Fernandez Mancera @ 2026-03-29 17:22 UTC (permalink / raw)
To: Luka Gejak, Fernando Fernandez Mancera, netdev
Cc: edumazet, pabeni, shannon.nelson, horms, lukma, kuba
In-Reply-To: <856eb43a-d4d0-4e1e-895f-75fca4eec51d@suse.de>
On 3/29/26 6:58 PM, Fernando Fernandez Mancera wrote:
> On 3/29/26 5:07 PM, Luka Gejak wrote:
>> On Wed Apr 9, 2025 at 12:19 PM CEST, Fernando Fernandez Mancera wrote:
>>> In order to work properly PRP requires slave1 and slave2 to share the
>>> same MAC address. To ease the configuration process on userspace tools,
>>> sync the slave2 MAC address with slave1. In addition, when deleting the
>>> port from the list, restore the original MAC address.
>>>
>>> Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
>>> ---
>>> v3: restore the original MAC address on slave removal.
>>> ---
>>> net/hsr/hsr_device.c | 5 +++++
>>> net/hsr/hsr_main.c | 9 +++++++++
>>> net/hsr/hsr_main.h | 1 +
>>> net/hsr/hsr_slave.c | 2 ++
>>> 4 files changed, 17 insertions(+)
>>>
>>> diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
>>> index 439cfb7ad5d1..e8922e8d9398 100644
>>> --- a/net/hsr/hsr_device.c
>>> +++ b/net/hsr/hsr_device.c
>>> @@ -761,6 +761,11 @@ int hsr_dev_finalize(struct net_device *hsr_dev,
>>> struct net_device *slave[2],
>>> if (res)
>>> goto err_unregister;
>>> + if (protocol_version == PRP_V1) {
>>> + eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>>> + }
>>> +
>>> if (interlink) {
>>> res = hsr_add_port(hsr, interlink, HSR_PT_INTERLINK, extack);
>>> if (res)
>>> diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c
>>> index d7ae32473c41..192893c3f2ec 100644
>>> --- a/net/hsr/hsr_main.c
>>> +++ b/net/hsr/hsr_main.c
>>> @@ -78,6 +78,15 @@ static int hsr_netdev_notify(struct notifier_block
>>> *nb, unsigned long event,
>>> eth_hw_addr_set(master->dev, dev->dev_addr);
>>> call_netdevice_notifiers(NETDEV_CHANGEADDR,
>>> master->dev);
>>> +
>>> + if (hsr->prot_version == PRP_V1) {
>>> + port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
>>> + if (port) {
>>> + eth_hw_addr_set(port->dev, dev->dev_addr);
>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR,
>>> + port->dev);
>>> + }
>>> + }
>>> }
>>> /* Make sure we recognize frames from ourselves in
>>> hsr_rcv() */
>>> diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
>>> index 1bc47b17a296..135ec5fce019 100644
>>> --- a/net/hsr/hsr_main.h
>>> +++ b/net/hsr/hsr_main.h
>>> @@ -155,6 +155,7 @@ struct hsr_port {
>>> struct hsr_priv *hsr;
>>> enum hsr_port_type type;
>>> struct rcu_head rcu;
>>> + unsigned char original_macaddress[ETH_ALEN];
>>> };
>>> struct hsr_frame_info;
>>> diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
>>> index 2a802a5de2ac..b87b6a6fe070 100644
>>> --- a/net/hsr/hsr_slave.c
>>> +++ b/net/hsr/hsr_slave.c
>>> @@ -196,6 +196,7 @@ int hsr_add_port(struct hsr_priv *hsr, struct
>>> net_device *dev,
>>> port->hsr = hsr;
>>> port->dev = dev;
>>> port->type = type;
>>> + ether_addr_copy(port->original_macaddress, dev->dev_addr);
>>> if (type != HSR_PT_MASTER) {
>>> res = hsr_portdev_setup(hsr, dev, port, extack);
>>> @@ -232,6 +233,7 @@ void hsr_del_port(struct hsr_port *port)
>>> if (!port->hsr->fwd_offloaded)
>>> dev_set_promiscuity(port->dev, -1);
>>> netdev_upper_dev_unlink(port->dev, master->dev);
>>> + eth_hw_addr_set(port->dev, port->original_macaddress);
>>> }
>>> kfree_rcu(port, rcu);
>>
>> Hi Fernando,
>>
>> Thanks for the patch. The logic to sync the slave2 MAC address with
>> slave1 for PRP is sound, but there are a few implementation issues here
>> that will cause hardware filtering problems and style violations.
>>
>> 1. Hardware MAC Filtering
>> In your current implementation:
>>
>> if (protocol_version == PRP_V1) {
>>
>> eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>>
>> call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>>
>> }
>>
>> eth_hw_addr_set() is appropriate for virtual devices (like the hsr_dev
>> itself), but slave[1] is a physical net_device. By using this helper,
>> you are bypassing dev->netdev_ops->ndo_set_mac_address. This means the
>> physical NIC's hardware MAC filter will not be programmed, and it will
>> silently drop unicast traffic destined for the new PRP MAC address
>> unless the interface happens to be in promiscuous mode. You should use
>> dev_set_mac_address() here instead. Note that unlike eth_hw_addr_set(),
>> dev_set_mac_address() can fail and returns an error code, so you will
>> need to check its return value and handle the error path accordingly.
>>
>> 2. Teardown Notifiers
>> In hsr_del_port():
>>
>> netdev_upper_dev_unlink(port->dev, master->dev);
>> eth_hw_addr_set(port->dev, port->original_macaddress);
>>
>> You have the same issue with eth_hw_addr_set() here. Additionally,
>> unlike the setup paths, this version omits call_netdevice_notifiers
>> (NETDEV_CHANGEADDR, port->dev). Switching to dev_set_mac_address() for
>> the restoration will handle both the hardware programming and the
>> notifier chain automatically.
>>
>
> These points makes sense. I guess I didn't notice the that
> eth_hw_addr_set() due to my interface being set to promiscuous mode at
> hsr_slave.c.
>
> Let me research a bit more about the impact here and will get back to
> you either with a new patch or an reply here.
>
Does this actually makes sense? I am not an expert on how hardware is
handling offloading here. But if I am not wrong, as the interface is set
on promiscuous or offload enabled. For promiscuous this does not matter
and for the offloaded scenario shouldn't the decision be handled by
hardware and not depend on ndo_set_mac_address()?
Let me know if I am missing something here.
Anyway, the missing notification makes sense and should be fixed for
SLAVE_B.
Thanks,
Fernando.
^ permalink raw reply
* Re: [PATCH] arch/arc: bpf_jit: fix missing newline in pr_err messages
From: Alexei Starovoitov @ 2026-03-29 17:23 UTC (permalink / raw)
To: Haoyu Lu; +Cc: arc, bpf, LKML, Network Development, linux-snps-arc
In-Reply-To: <20260324122703.641-1-hechushiguitu666@gmail.com>
On Tue, Mar 24, 2026 at 5:28 AM Haoyu Lu <hechushiguitu666@gmail.com> wrote:
>
> From: haoyu.lu <hechushiguitu666@gmail.com>
>
> Add missing newline to pr_err messages in arch/arc/net/bpf_jit_arcv2.c.
>
> Fixes: f122668ddcce ("ARC: Add eBPF JIT support")
> Signed-off-by: haoyu.lu <hechushiguitu666@gmail.com>
Applied to bpf-next
^ permalink raw reply
* Re: [PATCH net-next v2 1/3] net: bridge: add stp_mode attribute for STP mode selection
From: kernel test robot @ 2026-03-29 17:26 UTC (permalink / raw)
To: Andy Roulin, netdev
Cc: oe-kbuild-all, bridge, Nikolay Aleksandrov, Ido Schimmel,
Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan,
Petr Machata, Donald Hunter, Jonas Gorski, linux-doc,
linux-kselftest, linux-kernel, Andy Roulin
In-Reply-To: <20260329025858.330620-2-aroulin@nvidia.com>
Hi Andy,
kernel test robot noticed the following build errors:
[auto build test ERROR on net-next/main]
url: https://github.com/intel-lab-lkp/linux/commits/Andy-Roulin/net-bridge-add-stp_mode-attribute-for-STP-mode-selection/20260329-191152
base: net-next/main
patch link: https://lore.kernel.org/r/20260329025858.330620-2-aroulin%40nvidia.com
patch subject: [PATCH net-next v2 1/3] net: bridge: add stp_mode attribute for STP mode selection
config: s390-allnoconfig-bpf (https://download.01.org/0day-ci/archive/20260329/202603291905.TUiTIocs-lkp@intel.com/config)
compiler: s390x-linux-gnu-gcc (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260329/202603291905.TUiTIocs-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603291905.TUiTIocs-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
In file included from rt-link-user.c:9:
>> rt-link-user.h:38:42: warning: 'enum rt_link_br_stp_mode' declared inside parameter list will not be visible outside of this definition or declaration
38 | const char *rt_link_br_stp_mode_str(enum rt_link_br_stp_mode value);
| ^~~~~~~~~~~~~~~~~~~
>> rt-link-user.h:245:34: error: field 'stp_mode' has incomplete type
245 | enum rt_link_br_stp_mode stp_mode;
| ^~~~~~~~
>> rt-link-user.h:2164:80: error: parameter 2 ('stp_mode') has incomplete type
2164 | enum rt_link_br_stp_mode stp_mode)
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
rt-link-user.h:6234:85: error: parameter 2 ('stp_mode') has incomplete type
6234 | enum rt_link_br_stp_mode stp_mode)
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
rt-link-user.h:10089:80: error: parameter 2 ('stp_mode') has incomplete type
10089 | enum rt_link_br_stp_mode stp_mode)
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
>> rt-link-user.c:352:62: error: parameter 1 ('value') has incomplete type
352 | const char *rt_link_br_stp_mode_str(enum rt_link_br_stp_mode value)
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
rt-link-user.c: In function 'rt_link_br_stp_mode_str':
>> rt-link-user.c:357:1: warning: control reaches end of non-void function [-Wreturn-type]
357 | }
| ^
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH net-next v2 0/3] net: bridge: add stp_mode attribute for STP mode selection
From: Jakub Kicinski @ 2026-03-29 17:28 UTC (permalink / raw)
To: Andy Roulin
Cc: netdev, bridge, Nikolay Aleksandrov, Ido Schimmel, Andrew Lunn,
David S . Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
Jonathan Corbet, Shuah Khan, Petr Machata, Donald Hunter,
Jonas Gorski, linux-doc, linux-kselftest, linux-kernel
In-Reply-To: <20260329025858.330620-1-aroulin@nvidia.com>
On Sat, 28 Mar 2026 19:58:55 -0700 Andy Roulin wrote:
> The bridge-stp usermode helper is currently restricted to the initial
> network namespace, preventing userspace STP daemons like mstpd from
> operating on bridges in other namespaces. Since commit ff62198553e4
> ("bridge: Only call /sbin/bridge-stp for the initial network
> namespace"), bridges in non-init namespaces silently fall back to
> kernel STP with no way to request userspace STP.
Does not build, try:
make -C tools/net/ynl/
^ permalink raw reply
* Re: [PATCH v3 net-next] net: hsr: sync hw addr of slave2 according to slave1 hw addr on PRP
From: Luka Gejak @ 2026-03-29 17:32 UTC (permalink / raw)
To: Fernando Fernandez Mancera, Luka Gejak,
Fernando Fernandez Mancera, netdev
Cc: edumazet, pabeni, shannon.nelson, horms, lukma, kuba
In-Reply-To: <d3935fd1-b990-405b-8428-219730d68a89@suse.de>
On Sun Mar 29, 2026 at 7:22 PM CEST, Fernando Fernandez Mancera wrote:
> On 3/29/26 6:58 PM, Fernando Fernandez Mancera wrote:
>> On 3/29/26 5:07 PM, Luka Gejak wrote:
>>> On Wed Apr 9, 2025 at 12:19 PM CEST, Fernando Fernandez Mancera wrote:
>>>> In order to work properly PRP requires slave1 and slave2 to share the
>>>> same MAC address. To ease the configuration process on userspace tools,
>>>> sync the slave2 MAC address with slave1. In addition, when deleting the
>>>> port from the list, restore the original MAC address.
>>>>
>>>> Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
>>>> ---
>>>> v3: restore the original MAC address on slave removal.
>>>> ---
>>>> net/hsr/hsr_device.c | 5 +++++
>>>> net/hsr/hsr_main.c | 9 +++++++++
>>>> net/hsr/hsr_main.h | 1 +
>>>> net/hsr/hsr_slave.c | 2 ++
>>>> 4 files changed, 17 insertions(+)
>>>>
>>>> diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
>>>> index 439cfb7ad5d1..e8922e8d9398 100644
>>>> --- a/net/hsr/hsr_device.c
>>>> +++ b/net/hsr/hsr_device.c
>>>> @@ -761,6 +761,11 @@ int hsr_dev_finalize(struct net_device *hsr_dev,
>>>> struct net_device *slave[2],
>>>> if (res)
>>>> goto err_unregister;
>>>> + if (protocol_version == PRP_V1) {
>>>> + eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>>>> + }
>>>> +
>>>> if (interlink) {
>>>> res = hsr_add_port(hsr, interlink, HSR_PT_INTERLINK, extack);
>>>> if (res)
>>>> diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c
>>>> index d7ae32473c41..192893c3f2ec 100644
>>>> --- a/net/hsr/hsr_main.c
>>>> +++ b/net/hsr/hsr_main.c
>>>> @@ -78,6 +78,15 @@ static int hsr_netdev_notify(struct notifier_block
>>>> *nb, unsigned long event,
>>>> eth_hw_addr_set(master->dev, dev->dev_addr);
>>>> call_netdevice_notifiers(NETDEV_CHANGEADDR,
>>>> master->dev);
>>>> +
>>>> + if (hsr->prot_version == PRP_V1) {
>>>> + port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
>>>> + if (port) {
>>>> + eth_hw_addr_set(port->dev, dev->dev_addr);
>>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR,
>>>> + port->dev);
>>>> + }
>>>> + }
>>>> }
>>>> /* Make sure we recognize frames from ourselves in
>>>> hsr_rcv() */
>>>> diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
>>>> index 1bc47b17a296..135ec5fce019 100644
>>>> --- a/net/hsr/hsr_main.h
>>>> +++ b/net/hsr/hsr_main.h
>>>> @@ -155,6 +155,7 @@ struct hsr_port {
>>>> struct hsr_priv *hsr;
>>>> enum hsr_port_type type;
>>>> struct rcu_head rcu;
>>>> + unsigned char original_macaddress[ETH_ALEN];
>>>> };
>>>> struct hsr_frame_info;
>>>> diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
>>>> index 2a802a5de2ac..b87b6a6fe070 100644
>>>> --- a/net/hsr/hsr_slave.c
>>>> +++ b/net/hsr/hsr_slave.c
>>>> @@ -196,6 +196,7 @@ int hsr_add_port(struct hsr_priv *hsr, struct
>>>> net_device *dev,
>>>> port->hsr = hsr;
>>>> port->dev = dev;
>>>> port->type = type;
>>>> + ether_addr_copy(port->original_macaddress, dev->dev_addr);
>>>> if (type != HSR_PT_MASTER) {
>>>> res = hsr_portdev_setup(hsr, dev, port, extack);
>>>> @@ -232,6 +233,7 @@ void hsr_del_port(struct hsr_port *port)
>>>> if (!port->hsr->fwd_offloaded)
>>>> dev_set_promiscuity(port->dev, -1);
>>>> netdev_upper_dev_unlink(port->dev, master->dev);
>>>> + eth_hw_addr_set(port->dev, port->original_macaddress);
>>>> }
>>>> kfree_rcu(port, rcu);
>>>
>>> Hi Fernando,
>>>
>>> Thanks for the patch. The logic to sync the slave2 MAC address with
>>> slave1 for PRP is sound, but there are a few implementation issues here
>>> that will cause hardware filtering problems and style violations.
>>>
>>> 1. Hardware MAC Filtering
>>> In your current implementation:
>>>
>>> if (protocol_version == PRP_V1) {
>>>
>>> eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>>>
>>> call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>>>
>>> }
>>>
>>> eth_hw_addr_set() is appropriate for virtual devices (like the hsr_dev
>>> itself), but slave[1] is a physical net_device. By using this helper,
>>> you are bypassing dev->netdev_ops->ndo_set_mac_address. This means the
>>> physical NIC's hardware MAC filter will not be programmed, and it will
>>> silently drop unicast traffic destined for the new PRP MAC address
>>> unless the interface happens to be in promiscuous mode. You should use
>>> dev_set_mac_address() here instead. Note that unlike eth_hw_addr_set(),
>>> dev_set_mac_address() can fail and returns an error code, so you will
>>> need to check its return value and handle the error path accordingly.
>>>
>>> 2. Teardown Notifiers
>>> In hsr_del_port():
>>>
>>> netdev_upper_dev_unlink(port->dev, master->dev);
>>> eth_hw_addr_set(port->dev, port->original_macaddress);
>>>
>>> You have the same issue with eth_hw_addr_set() here. Additionally,
>>> unlike the setup paths, this version omits call_netdevice_notifiers
>>> (NETDEV_CHANGEADDR, port->dev). Switching to dev_set_mac_address() for
>>> the restoration will handle both the hardware programming and the
>>> notifier chain automatically.
>>>
>>
>> These points makes sense. I guess I didn't notice the that
>> eth_hw_addr_set() due to my interface being set to promiscuous mode at
>> hsr_slave.c.
>>
>> Let me research a bit more about the impact here and will get back to
>> you either with a new patch or an reply here.
>>
>
> Does this actually makes sense? I am not an expert on how hardware is
> handling offloading here. But if I am not wrong, as the interface is set
> on promiscuous or offload enabled. For promiscuous this does not matter
> and for the offloaded scenario shouldn't the decision be handled by
> hardware and not depend on ndo_set_mac_address()?
>
> Let me know if I am missing something here.
>
>
> Anyway, the missing notification makes sense and should be fixed for
> SLAVE_B.
>
> Thanks,
> Fernando.
Hi Fernando,
You raise a fair point, and I should have looked more carefully at the
existing code paths.
You are correct that in the non-offloaded case, hsr_slave.c already
sets promiscuous mode via dev_set_promiscuity(dev, 1), so the hardware
MAC filter is bypassed and eth_hw_addr_set() is sufficient for frame
reception.
For the offloaded case, the comment in hsr_portdev_setup() notes that
"L2 frame forward happens at the offloaded hardware" — so the hardware
is configured through its own HSR/PRP offload mechanisms, not through
ndo_set_mac_address().
So the practical impact of my original concern is limited to edge cases
where promiscuous mode might be disabled or fail. The more important
issue, which you've already acknowledged, is the missing notifier in
hsr_del_port(). That should definitely be fixed for correctness.
One additional consideration: even though promiscuous mode handles the
receive path, dev->dev_addr is still used as the source MAC for
outgoing frames. Using dev_set_mac_address() would ensure the software
state (dev->dev_addr) and any driver-level state remain consistent. But
I agree this is less critical than I initially suggested. Thanks for
pushing back on this — it's a good clarification.
Best regards,
Luka
^ permalink raw reply
* Re: [PATCH 0/5] hamradio: mkiss: modernize and clean up mkiss driver
From: Jakub Kicinski @ 2026-03-29 17:35 UTC (permalink / raw)
To: Mashiro Chen
Cc: andrew+netdev, davem, edumazet, pabeni, netdev, linux-hams,
linux-kernel
In-Reply-To: <20260329143408.747197-1-mashiro.chen@mailbox.org>
On Sun, 29 Mar 2026 22:34:03 +0800 Mashiro Chen wrote:
> This patch series modernizes the mkiss driver, which is used for
> AX.25 communication over serial lines.
Quoting documentation:
Clean-up patches
~~~~~~~~~~~~~~~~
Netdev discourages patches which perform simple clean-ups, which are not in
the context of other work. For example:
* Addressing ``checkpatch.pl``, and other trivial coding style warnings
* Addressing :ref:`Local variable ordering<rcs>` issues
* Conversions to device-managed APIs (``devm_`` helpers)
This is because it is felt that the churn that such changes produce comes
at a greater cost than the value of such clean-ups.
Conversely, spelling and grammar fixes are not discouraged.
See: https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#clean-up-patches
--
pw-bot: reject
^ permalink raw reply
* Re: [PATCH net-next 00/10] net: airoha: Support multiple net_devices connected to the same GDM port
From: Jakub Kicinski @ 2026-03-29 17:36 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Christian Marangi,
linux-arm-kernel, linux-mediatek, netdev, devicetree, Xuegang Lu
In-Reply-To: <20260329-airoha-eth-multi-serdes-v1-0-00f52dc360ca@kernel.org>
On Sun, 29 Mar 2026 15:07:50 +0200 Lorenzo Bianconi wrote:
> EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
> Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw multiplexer that
> manages the traffic in a TDM manner. As a result multiple net_devices can
> connect to the same GDM{3,4} port and there is a theoretical "1:n"
> relation between GDM ports and net_devices.
Does not apply.
^ permalink raw reply
* Re: [PATCH net-next 01/10] net: stmmac: fix TSO support when some channels have TBS available
From: Jakub Kicinski @ 2026-03-29 17:42 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller,
Eric Dumazet, linux-arm-kernel, linux-stm32, netdev,
Ong Boon Leong, Paolo Abeni
In-Reply-To: <acjzmxY9xmBInSwm@shell.armlinux.org.uk>
On Sun, 29 Mar 2026 10:40:43 +0100 Russell King (Oracle) wrote:
> On Sat, Mar 28, 2026 at 09:36:41PM +0000, Russell King (Oracle) wrote:
> > According to the STM32MP25xx manual, which is dwmac v5.3, TBS (time
> > based scheduling) is not permitted for channels which have hardware
> > TSO enabled. Intel's commit 5e6038b88a57 ("net: stmmac: fix TSO and
> > TBS feature enabling during driver open") concurs with this, but it
> > is incomplete.
> >
> > This commit avoids enabling TSO support on the channels which have
> > TBS available, which, as far as the hardware is concerned, means we
> > do not set the TSE bit in the DMA channel's transmit control register.
> >
> > However, the net device's features apply to all queues(channels), which
> > means these channels may still be handed TSO skbs to transmit, and the
> > driver will pass them to stmmac_tso_xmit(). This will generate the
> > descriptors for TSO, even though the channel has the TSE bit clear.
> >
> > Fix this by checking whether the queue(channel) has TBS available,
> > and if it does, fall back to software GSO support.
>
> This is sufficient for the immediate issue of fixing the patch below,
> but I think there's another issue that also needs fixing here.
>
> TSO requires the hardware to support checksum offload, and there is
> a comment in the driver:
>
> /* DWMAC IPs can be synthesized to support tx coe only for a few tx
> * queues. In that case, checksum offloading for those queues that don't
> * support tx coe needs to fallback to software checksum calculation.
> *
> * Packets that won't trigger the COE e.g. most DSA-tagged packets will
> * also have to be checksummed in software.
> */
>
> So, it seems at the very least we need to add a check (in a subsequent
> patch) for priv->plat->tx_queues_cfg[queue].coe_unsupported to
> stmmac_channel_tso_permitted().
>
> I'm also wondering about the stmmac_has_ip_ethertype() thing, which
> checks whether the skb can be checksummed by the hardware, and how that
> interacts with TSO, and whether that's yet another hole that needs
> plugging.
If the driver "un-advertises" checksum offload accordingly the core
should automatically clear TSO feature.
^ permalink raw reply
* Re: [PATCH v3 net-next] net: hsr: sync hw addr of slave2 according to slave1 hw addr on PRP
From: Fernando Fernandez Mancera @ 2026-03-29 17:46 UTC (permalink / raw)
To: Luka Gejak, Fernando Fernandez Mancera, netdev
Cc: edumazet, pabeni, shannon.nelson, horms, lukma, kuba
In-Reply-To: <DHFG26KI6L23.1YCOVQ5SSYMO5@linux.dev>
On 3/29/26 7:32 PM, Luka Gejak wrote:
> On Sun Mar 29, 2026 at 7:22 PM CEST, Fernando Fernandez Mancera wrote:
>> On 3/29/26 6:58 PM, Fernando Fernandez Mancera wrote:
>>> On 3/29/26 5:07 PM, Luka Gejak wrote:
>>>> On Wed Apr 9, 2025 at 12:19 PM CEST, Fernando Fernandez Mancera wrote:
>>>>> In order to work properly PRP requires slave1 and slave2 to share the
>>>>> same MAC address. To ease the configuration process on userspace tools,
>>>>> sync the slave2 MAC address with slave1. In addition, when deleting the
>>>>> port from the list, restore the original MAC address.
>>>>>
>>>>> Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
>>>>> ---
>>>>> v3: restore the original MAC address on slave removal.
>>>>> ---
>>>>> net/hsr/hsr_device.c | 5 +++++
>>>>> net/hsr/hsr_main.c | 9 +++++++++
>>>>> net/hsr/hsr_main.h | 1 +
>>>>> net/hsr/hsr_slave.c | 2 ++
>>>>> 4 files changed, 17 insertions(+)
>>>>>
>>>>> diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
>>>>> index 439cfb7ad5d1..e8922e8d9398 100644
>>>>> --- a/net/hsr/hsr_device.c
>>>>> +++ b/net/hsr/hsr_device.c
>>>>> @@ -761,6 +761,11 @@ int hsr_dev_finalize(struct net_device *hsr_dev,
>>>>> struct net_device *slave[2],
>>>>> if (res)
>>>>> goto err_unregister;
>>>>> + if (protocol_version == PRP_V1) {
>>>>> + eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>>>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>>>>> + }
>>>>> +
>>>>> if (interlink) {
>>>>> res = hsr_add_port(hsr, interlink, HSR_PT_INTERLINK, extack);
>>>>> if (res)
>>>>> diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c
>>>>> index d7ae32473c41..192893c3f2ec 100644
>>>>> --- a/net/hsr/hsr_main.c
>>>>> +++ b/net/hsr/hsr_main.c
>>>>> @@ -78,6 +78,15 @@ static int hsr_netdev_notify(struct notifier_block
>>>>> *nb, unsigned long event,
>>>>> eth_hw_addr_set(master->dev, dev->dev_addr);
>>>>> call_netdevice_notifiers(NETDEV_CHANGEADDR,
>>>>> master->dev);
>>>>> +
>>>>> + if (hsr->prot_version == PRP_V1) {
>>>>> + port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
>>>>> + if (port) {
>>>>> + eth_hw_addr_set(port->dev, dev->dev_addr);
>>>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR,
>>>>> + port->dev);
>>>>> + }
>>>>> + }
>>>>> }
>>>>> /* Make sure we recognize frames from ourselves in
>>>>> hsr_rcv() */
>>>>> diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
>>>>> index 1bc47b17a296..135ec5fce019 100644
>>>>> --- a/net/hsr/hsr_main.h
>>>>> +++ b/net/hsr/hsr_main.h
>>>>> @@ -155,6 +155,7 @@ struct hsr_port {
>>>>> struct hsr_priv *hsr;
>>>>> enum hsr_port_type type;
>>>>> struct rcu_head rcu;
>>>>> + unsigned char original_macaddress[ETH_ALEN];
>>>>> };
>>>>> struct hsr_frame_info;
>>>>> diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
>>>>> index 2a802a5de2ac..b87b6a6fe070 100644
>>>>> --- a/net/hsr/hsr_slave.c
>>>>> +++ b/net/hsr/hsr_slave.c
>>>>> @@ -196,6 +196,7 @@ int hsr_add_port(struct hsr_priv *hsr, struct
>>>>> net_device *dev,
>>>>> port->hsr = hsr;
>>>>> port->dev = dev;
>>>>> port->type = type;
>>>>> + ether_addr_copy(port->original_macaddress, dev->dev_addr);
>>>>> if (type != HSR_PT_MASTER) {
>>>>> res = hsr_portdev_setup(hsr, dev, port, extack);
>>>>> @@ -232,6 +233,7 @@ void hsr_del_port(struct hsr_port *port)
>>>>> if (!port->hsr->fwd_offloaded)
>>>>> dev_set_promiscuity(port->dev, -1);
>>>>> netdev_upper_dev_unlink(port->dev, master->dev);
>>>>> + eth_hw_addr_set(port->dev, port->original_macaddress);
>>>>> }
>>>>> kfree_rcu(port, rcu);
>>>>
>>>> Hi Fernando,
>>>>
>>>> Thanks for the patch. The logic to sync the slave2 MAC address with
>>>> slave1 for PRP is sound, but there are a few implementation issues here
>>>> that will cause hardware filtering problems and style violations.
>>>>
>>>> 1. Hardware MAC Filtering
>>>> In your current implementation:
>>>>
>>>> if (protocol_version == PRP_V1) {
>>>>
>>>> eth_hw_addr_set(slave[1], slave[0]->dev_addr);
>>>>
>>>> call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
>>>>
>>>> }
>>>>
>>>> eth_hw_addr_set() is appropriate for virtual devices (like the hsr_dev
>>>> itself), but slave[1] is a physical net_device. By using this helper,
>>>> you are bypassing dev->netdev_ops->ndo_set_mac_address. This means the
>>>> physical NIC's hardware MAC filter will not be programmed, and it will
>>>> silently drop unicast traffic destined for the new PRP MAC address
>>>> unless the interface happens to be in promiscuous mode. You should use
>>>> dev_set_mac_address() here instead. Note that unlike eth_hw_addr_set(),
>>>> dev_set_mac_address() can fail and returns an error code, so you will
>>>> need to check its return value and handle the error path accordingly.
>>>>
>>>> 2. Teardown Notifiers
>>>> In hsr_del_port():
>>>>
>>>> netdev_upper_dev_unlink(port->dev, master->dev);
>>>> eth_hw_addr_set(port->dev, port->original_macaddress);
>>>>
>>>> You have the same issue with eth_hw_addr_set() here. Additionally,
>>>> unlike the setup paths, this version omits call_netdevice_notifiers
>>>> (NETDEV_CHANGEADDR, port->dev). Switching to dev_set_mac_address() for
>>>> the restoration will handle both the hardware programming and the
>>>> notifier chain automatically.
>>>>
>>>
>>> These points makes sense. I guess I didn't notice the that
>>> eth_hw_addr_set() due to my interface being set to promiscuous mode at
>>> hsr_slave.c.
>>>
>>> Let me research a bit more about the impact here and will get back to
>>> you either with a new patch or an reply here.
>>>
>>
>> Does this actually makes sense? I am not an expert on how hardware is
>> handling offloading here. But if I am not wrong, as the interface is set
>> on promiscuous or offload enabled. For promiscuous this does not matter
>> and for the offloaded scenario shouldn't the decision be handled by
>> hardware and not depend on ndo_set_mac_address()?
>>
>> Let me know if I am missing something here.
>>
>>
>> Anyway, the missing notification makes sense and should be fixed for
>> SLAVE_B.
>>
>> Thanks,
>> Fernando.
>
> Hi Fernando,
> You raise a fair point, and I should have looked more carefully at the
> existing code paths.
>
> You are correct that in the non-offloaded case, hsr_slave.c already
> sets promiscuous mode via dev_set_promiscuity(dev, 1), so the hardware
> MAC filter is bypassed and eth_hw_addr_set() is sufficient for frame
> reception.
>
> For the offloaded case, the comment in hsr_portdev_setup() notes that
> "L2 frame forward happens at the offloaded hardware" — so the hardware
> is configured through its own HSR/PRP offload mechanisms, not through
> ndo_set_mac_address().
>
> So the practical impact of my original concern is limited to edge cases
> where promiscuous mode might be disabled or fail. The more important
> issue, which you've already acknowledged, is the missing notifier in
> hsr_del_port(). That should definitely be fixed for correctness.
>
> One additional consideration: even though promiscuous mode handles the
> receive path, dev->dev_addr is still used as the source MAC for
> outgoing frames. Using dev_set_mac_address() would ensure the software
> state (dev->dev_addr)
I am sorry I do not follow here. eth_hw_addr_set() path ends up calling
dev_addr_mod() which modifies dev->dev_addr indeed.
Thanks,
Fernando.
and any driver-level state remain consistent. But
> I agree this is less critical than I initially suggested. Thanks for
> pushing back on this — it's a good clarification.
>
> Best regards,
> Luka
>
^ permalink raw reply
* Re: [PATCH] ethtool: don't touch the parent device of a net device being unregistered
From: Jakub Kicinski @ 2026-03-29 17:54 UTC (permalink / raw)
To: Alexander Popov
Cc: Andrew Lunn, David Miller, Eric Dumazet, Paolo Abeni,
Simon Horman, Maxime Chevallier, Michal Kubecek, Gal Pressman,
Kory Maincent, Oleksij Rempel, Ido Schimmel, Heiner Kallweit,
Greg KH, netdev, linux-kernel, security, notify
In-Reply-To: <676733D7-814A-4B66-9E49-93DD1259ED48@linux.com>
On Sun, 29 Mar 2026 17:47:30 +0900 Alexander Popov wrote:
> >I've provided additional details about the reproducer of this vulnerability to Jakub and to security@kernel.org.
>
> Hello! May I ask about the decision on this patch?
>
> At patchwork.kernel.org, it is marked as "Changes Requested":
> <https://patchwork.kernel.org/project/netdevbpf/patch/20260322075917.254874-1-alex.popov@linux.com/>
>
> However, I don't have any instructions on what to change in it.
The change was to fix the wifi driver.
Please try not to waste more maintainer time than necessary.
^ permalink raw reply
* Re: [PATCH net-next v2 3/5] ice: migrate to netdev ops lock
From: Kohei Enju @ 2026-03-29 18:01 UTC (permalink / raw)
To: Tony Nguyen
Cc: davem, kuba, pabeni, edumazet, andrew+netdev, netdev,
Alexander Lobakin, jacob.e.keller, nxne.cnse.osdt.itp.upstreaming,
horms, maciej.fijalkowski, magnus.karlsson, ast, daniel, hawk,
john.fastabend, sdf, bpf, Aleksandr Loktionov
In-Reply-To: <20260325200644.2528726-4-anthony.l.nguyen@intel.com>
On 03/25 13:06, Tony Nguyen wrote:
> From: Alexander Lobakin <aleksander.lobakin@intel.com>
>
> Queue management ops unconditionally enable netdev locking. The same
> lock is taken by default by several NAPI configuration functions,
> such as napi_enable() and netif_napi_set_irq().
> Request ops locking in advance and make sure we use the _locked
> counterparts of those functions to avoid deadlocks, taking the lock
> manually where needed (suspend/resume, queue rebuild and resets).
>
I've been testing this series and found that attaching XDP program
hangs:
ip/1033 is trying to acquire lock:
ffff888103d8ec30 (&dev->lock){+.+.}-{4:4}, at: xdp_features_set_redirect_target+0x1f/0x80
but task is already holding lock:
ffff888103d8ec30 (&dev->lock){+.+.}-{4:4}, at: do_setlink.isra.0+0x261/0x39a0
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(&dev->lock);
lock(&dev->lock);
*** DEADLOCK ***
May be due to missing lock nesting notation
3 locks held by ip/1033:
#0: ffffffff86d8b548 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x6c4/0x22a0
#1: ffff888103d8ec30 (&dev->lock){+.+.}-{4:4}, at: do_setlink.isra.0+0x261/0x39a0
#2: ffff888104e1c5b8 (&vsi->xdp_state_lock){+.+.}-{4:4}, at: ice_xdp+0x96/0xef0
stack backtrace:
CPU: 1 UID: 0 PID: 1033 Comm: ip Not tainted 7.0.0-rc4-enjuk-tnguy-00940-gadae968a1b0a #316 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x6f/0xb0
print_deadlock_bug.cold+0xc0/0xce
__lock_acquire+0x123d/0x1b90
lock_acquire+0x192/0x310
__mutex_lock+0x193/0x2860
xdp_features_set_redirect_target+0x1f/0x80
ice_xdp+0x64d/0xef0
dev_xdp_install+0x3c4/0x840
dev_xdp_attach+0x50a/0x10a0
dev_change_xdp_fd+0x175/0x210
do_setlink.isra.0+0x1c1b/0x39a0
[...]
I think we should use locked versions for both
xdp_features_{set,clear}_redirect_target(), and this fixed that for me.
---
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 3477c53316ba..0be225ab9372 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -3015,9 +3015,9 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
goto resume_if;
}
}
- xdp_features_set_redirect_target(vsi->netdev, true);
+ xdp_features_set_redirect_target_locked(vsi->netdev, true);
} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
- xdp_features_clear_redirect_target(vsi->netdev);
+ xdp_features_clear_redirect_target_locked(vsi->netdev);
xdp_ring_err = ice_destroy_xdp_rings(vsi, ICE_XDP_CFG_FULL);
if (xdp_ring_err)
NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
^ permalink raw reply related
* [PATCH bpf-next v2 1/2] net: clear the dst when performing encap / decap
From: Jakub Kicinski @ 2026-03-29 18:04 UTC (permalink / raw)
To: bpf
Cc: netdev, davem, edumazet, pabeni, andrew+netdev, horms,
Jakub Kicinski, maze, willemdebruijn.kernel, ast, daniel, andrii,
martin.lau, eddyz87, song, yonghong.song, john.fastabend, kpsingh,
sdf, haoluo, jolsa
Commit ba9db6f907ac ("net: clear the dst when changing skb protocol")
added dst clearing when a BPF program changes the skb protocol
(e.g. IPv4 to IPv6). Since that was a fix we only cleared the dst when
the L3 protocol actually changes to keep it minimal. As suggested during
the discussion (see Link) encap or decap operation which wraps or unwraps
a same-protocol header may also render the existing dst incorrect - even
if that doesn't result in a crash, just the wrong route for the now-outermost
IP dst.
Make dropping dst unconditional for bpf_skb_change_proto() and all
L3 encap / decap ops.
Link: https://lore.kernel.org/CANP3RGfRaYwve_xgxH6Tp2zenzKn2-DjZ9tg023WVzfdJF3p_w@mail.gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v2:
- move the pointer recalc
v1: https://lore.kernel.org/20260319234531.3022634-1-kuba@kernel.org
CC: maze@google.com
CC: willemdebruijn.kernel@gmail.com
CC: ast@kernel.org
CC: daniel@iogearbox.net
CC: andrii@kernel.org
CC: martin.lau@linux.dev
CC: eddyz87@gmail.com
CC: song@kernel.org
CC: yonghong.song@linux.dev
CC: john.fastabend@gmail.com
CC: kpsingh@kernel.org
CC: sdf@fomichev.me
CC: haoluo@google.com
CC: jolsa@kernel.org
CC: bpf@vger.kernel.org
---
net/core/filter.c | 50 +++++++++++++++++++++++++----------------------
1 file changed, 27 insertions(+), 23 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index 78b548158fb0..8a352257656e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3257,13 +3257,6 @@ static const struct bpf_func_proto bpf_skb_vlan_pop_proto = {
.arg1_type = ARG_PTR_TO_CTX,
};
-static void bpf_skb_change_protocol(struct sk_buff *skb, u16 proto)
-{
- skb->protocol = htons(proto);
- if (skb_valid_dst(skb))
- skb_dst_drop(skb);
-}
-
static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
{
/* Caller already did skb_cow() with meta_len+len as headroom,
@@ -3362,7 +3355,7 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
shinfo->gso_type |= SKB_GSO_DODGY;
}
- bpf_skb_change_protocol(skb, ETH_P_IPV6);
+ skb->protocol = htons(ETH_P_IPV6);
skb_clear_hash(skb);
return 0;
@@ -3393,7 +3386,7 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
shinfo->gso_type |= SKB_GSO_DODGY;
}
- bpf_skb_change_protocol(skb, ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
skb_clear_hash(skb);
return 0;
@@ -3441,7 +3434,13 @@ BPF_CALL_3(bpf_skb_change_proto, struct sk_buff *, skb, __be16, proto,
*/
ret = bpf_skb_proto_xlat(skb, proto);
bpf_compute_data_pointers(skb);
- return ret;
+ if (ret)
+ return ret;
+
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
+
+ return 0;
}
static const struct bpf_func_proto bpf_skb_change_proto_proto = {
@@ -3583,12 +3582,13 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff,
}
/* Match skb->protocol to new outer l3 protocol */
- if (skb->protocol == htons(ETH_P_IP) &&
- flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV6)
- bpf_skb_change_protocol(skb, ETH_P_IPV6);
- else if (skb->protocol == htons(ETH_P_IPV6) &&
- flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV4)
- bpf_skb_change_protocol(skb, ETH_P_IP);
+ if (flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV6)
+ skb->protocol = htons(ETH_P_IPV6);
+ else if (flags & BPF_F_ADJ_ROOM_ENCAP_L3_IPV4)
+ skb->protocol = htons(ETH_P_IP);
+
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
}
if (skb_is_gso(skb)) {
@@ -3616,6 +3616,7 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff,
static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff,
u64 flags)
{
+ bool decap = flags & BPF_F_ADJ_ROOM_DECAP_L3_MASK;
int ret;
if (unlikely(flags & ~(BPF_F_ADJ_ROOM_FIXED_GSO |
@@ -3638,13 +3639,16 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff,
if (unlikely(ret < 0))
return ret;
- /* Match skb->protocol to new outer l3 protocol */
- if (skb->protocol == htons(ETH_P_IP) &&
- flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV6)
- bpf_skb_change_protocol(skb, ETH_P_IPV6);
- else if (skb->protocol == htons(ETH_P_IPV6) &&
- flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV4)
- bpf_skb_change_protocol(skb, ETH_P_IP);
+ if (decap) {
+ /* Match skb->protocol to new outer l3 protocol */
+ if (flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV6)
+ skb->protocol = htons(ETH_P_IPV6);
+ else if (flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV4)
+ skb->protocol = htons(ETH_P_IP);
+
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
+ }
if (skb_is_gso(skb)) {
struct skb_shared_info *shinfo = skb_shinfo(skb);
--
2.53.0
^ permalink raw reply related
* [PATCH bpf-next v2 2/2] selftests/bpf: test that dst is cleared on same-protocol encap
From: Jakub Kicinski @ 2026-03-29 18:04 UTC (permalink / raw)
To: bpf
Cc: netdev, davem, edumazet, pabeni, andrew+netdev, horms,
Jakub Kicinski, andrii, eddyz87, ast, daniel, martin.lau, song,
yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa, shuah,
linux-kselftest
In-Reply-To: <20260329180428.2657785-1-kuba@kernel.org>
Verify that bpf_skb_adjust_room() clears the routing dst even when
the encap L3 protocol matches the original packet (e.g. IPIP).
The dst selected for the inner packet is not valid for the
encapsulated result; a stale dst could lead to misrouting.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: andrii@kernel.org
CC: eddyz87@gmail.com
CC: ast@kernel.org
CC: daniel@iogearbox.net
CC: martin.lau@linux.dev
CC: song@kernel.org
CC: yonghong.song@linux.dev
CC: john.fastabend@gmail.com
CC: kpsingh@kernel.org
CC: sdf@fomichev.me
CC: haoluo@google.com
CC: jolsa@kernel.org
CC: shuah@kernel.org
CC: bpf@vger.kernel.org
CC: linux-kselftest@vger.kernel.org
---
.../selftests/bpf/prog_tests/test_dst_clear.c | 75 +++++++++++++++++++
.../selftests/bpf/progs/test_dst_clear.c | 57 ++++++++++++++
2 files changed, 132 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/test_dst_clear.c
create mode 100644 tools/testing/selftests/bpf/progs/test_dst_clear.c
diff --git a/tools/testing/selftests/bpf/prog_tests/test_dst_clear.c b/tools/testing/selftests/bpf/prog_tests/test_dst_clear.c
new file mode 100644
index 000000000000..8190c56556fb
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/test_dst_clear.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include "test_progs.h"
+#include "network_helpers.h"
+#include "test_dst_clear.skel.h"
+
+#define NS_TEST "dst_clear_ns"
+#define IPV4_IFACE_ADDR "1.0.0.1"
+#define UDP_TEST_PORT 7777
+
+void test_dst_clear(void)
+{
+ LIBBPF_OPTS(bpf_tc_hook, qdisc_hook, .attach_point = BPF_TC_EGRESS);
+ LIBBPF_OPTS(bpf_tc_opts, tc_attach);
+ struct nstoken *nstoken = NULL;
+ struct test_dst_clear *skel;
+ struct sockaddr_in addr;
+ socklen_t addrlen;
+ char buf[128] = {};
+ int sockfd, err;
+
+ skel = test_dst_clear__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "skel open_and_load"))
+ return;
+
+ SYS(fail, "ip netns add %s", NS_TEST);
+ SYS(fail, "ip -net %s addr add %s/8 dev lo", NS_TEST, IPV4_IFACE_ADDR);
+ SYS(fail, "ip -net %s link set dev lo up", NS_TEST);
+
+ nstoken = open_netns(NS_TEST);
+ if (!ASSERT_OK_PTR(nstoken, "open_netns"))
+ goto fail;
+
+ qdisc_hook.ifindex = if_nametoindex("lo");
+ if (!ASSERT_GT(qdisc_hook.ifindex, 0, "if_nametoindex lo"))
+ goto fail;
+
+ err = bpf_tc_hook_create(&qdisc_hook);
+ if (!ASSERT_OK(err, "create qdisc hook"))
+ goto fail;
+
+ tc_attach.prog_fd = bpf_program__fd(skel->progs.dst_clear);
+ err = bpf_tc_attach(&qdisc_hook, &tc_attach);
+ if (!ASSERT_OK(err, "attach filter"))
+ goto fail;
+
+ addrlen = sizeof(addr);
+ err = make_sockaddr(AF_INET, IPV4_IFACE_ADDR, UDP_TEST_PORT,
+ (void *)&addr, &addrlen);
+ if (!ASSERT_OK(err, "make_sockaddr"))
+ goto fail;
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (!ASSERT_NEQ(sockfd, -1, "socket"))
+ goto fail;
+ err = sendto(sockfd, buf, sizeof(buf), 0, (void *)&addr, addrlen);
+ close(sockfd);
+ if (!ASSERT_EQ(err, sizeof(buf), "send"))
+ goto fail;
+
+ ASSERT_TRUE(skel->bss->had_dst, "had_dst");
+ ASSERT_TRUE(skel->bss->dst_cleared, "dst_cleared");
+
+fail:
+ if (nstoken) {
+ bpf_tc_hook_destroy(&qdisc_hook);
+ close_netns(nstoken);
+ }
+ SYS_NOFAIL("ip netns del " NS_TEST);
+ test_dst_clear__destroy(skel);
+}
diff --git a/tools/testing/selftests/bpf/progs/test_dst_clear.c b/tools/testing/selftests/bpf/progs/test_dst_clear.c
new file mode 100644
index 000000000000..7ac9604fd99c
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_dst_clear.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
+
+#include "vmlinux.h"
+#include "bpf_tracing_net.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+#define UDP_TEST_PORT 7777
+
+void *bpf_cast_to_kern_ctx(void *) __ksym;
+
+bool had_dst = false;
+bool dst_cleared = false;
+
+SEC("tc")
+int dst_clear(struct __sk_buff *skb)
+{
+ struct sk_buff *kskb;
+ struct iphdr iph;
+ struct udphdr udph;
+ int err;
+
+ if (skb->protocol != __bpf_constant_htons(ETH_P_IP))
+ return TC_ACT_OK;
+
+ if (bpf_skb_load_bytes(skb, ETH_HLEN, &iph, sizeof(iph)))
+ return TC_ACT_OK;
+
+ if (iph.protocol != IPPROTO_UDP)
+ return TC_ACT_OK;
+
+ if (bpf_skb_load_bytes(skb, ETH_HLEN + sizeof(iph), &udph, sizeof(udph)))
+ return TC_ACT_OK;
+
+ if (udph.dest != __bpf_constant_htons(UDP_TEST_PORT))
+ return TC_ACT_OK;
+
+ kskb = bpf_cast_to_kern_ctx(skb);
+ had_dst = (kskb->_skb_refdst != 0);
+
+ /* Same-protocol encap (IPIP): protocol stays IPv4, but the dst
+ * from the original routing is no longer valid for the outer hdr.
+ */
+ err = bpf_skb_adjust_room(skb, (s32)sizeof(struct iphdr),
+ BPF_ADJ_ROOM_MAC,
+ BPF_F_ADJ_ROOM_FIXED_GSO |
+ BPF_F_ADJ_ROOM_ENCAP_L3_IPV4);
+ if (err)
+ return TC_ACT_SHOT;
+
+ dst_cleared = (kskb->_skb_refdst == 0);
+
+ return TC_ACT_SHOT;
+}
+
+char __license[] SEC("license") = "GPL";
--
2.53.0
^ permalink raw reply related
* [PATCH net-next v2 0/2] declance: Improve DMA error reporting
From: Maciej W. Rozycki @ 2026-03-29 18:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: netdev, linux-kernel
Hi,
D'oh, this v2 fixes a silly thinko in the commit description of 2/2.
Inspired by a recent discussion[1] I have come up with this pair of
small improvements to DMA error reporting with declance. Please apply.
References:
[1] Sebastian Andrzej Siewior, "declance: Remove IRQF_ONESHOT",
<https://lore.kernel.org/r/20260127135334.qUEaYP9G@linutronix.de/>
Maciej
^ permalink raw reply
* [PATCH net-next v2 1/2] declance: Rate-limit DMA errors
From: Maciej W. Rozycki @ 2026-03-29 18:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: netdev, linux-kernel
In-Reply-To: <alpine.DEB.2.21.2603291835550.60268@angie.orcam.me.uk>
Prevent the system from becoming unusable due to a flood of DMA error
messages.
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
---
No change from v1.
---
drivers/net/ethernet/amd/declance.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
linux-declance-ratelimit.diff
Index: linux-macro/drivers/net/ethernet/amd/declance.c
===================================================================
--- linux-macro.orig/drivers/net/ethernet/amd/declance.c
+++ linux-macro/drivers/net/ethernet/amd/declance.c
@@ -727,7 +727,7 @@ static irqreturn_t lance_dma_merr_int(in
{
struct net_device *dev = dev_id;
- printk(KERN_ERR "%s: DMA error\n", dev->name);
+ pr_err_ratelimited("%s: DMA error\n", dev->name);
return IRQ_HANDLED;
}
^ permalink raw reply
* [PATCH net-next v2 2/2] declance: Include the offending address with DMA errors
From: Maciej W. Rozycki @ 2026-03-29 18:07 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: netdev, linux-kernel
In-Reply-To: <alpine.DEB.2.21.2603291835550.60268@angie.orcam.me.uk>
The address latched in the I/O ASIC LANCE DMA Pointer Register uses the
TURBOchannel bus address encoding and therefore bits 33:29 of location
referred occupy bits 4:0, bits 28:2 are left-shifted by 3, and bits 1:0
are hardwired to zero. In reality no TURBOchannel system exceeds 1GiB
of RAM though, so the address reported will always fit in 8 hex digits.
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
---
Changes from v1:
- s/16/8/ in the change description for the printed address width.
---
drivers/net/ethernet/amd/declance.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
linux-declance-dma-merr-addr.diff
Index: linux-macro/drivers/net/ethernet/amd/declance.c
===================================================================
--- linux-macro.orig/drivers/net/ethernet/amd/declance.c
+++ linux-macro/drivers/net/ethernet/amd/declance.c
@@ -726,8 +726,10 @@ static void lance_tx(struct net_device *
static irqreturn_t lance_dma_merr_int(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
+ u64 ldp = ioasic_read(IO_REG_LANCE_DMA_P);
- pr_err_ratelimited("%s: DMA error\n", dev->name);
+ pr_err_ratelimited("%s: DMA error at %#010llx\n", dev->name,
+ (ldp & 0x1f) << 29 | (ldp & 0xffffffe0) >> 3);
return IRQ_HANDLED;
}
^ permalink raw reply
* Re: [PATCH net-next 00/10] net: stmmac: TSO fixes/cleanups
From: Jakub Kicinski @ 2026-03-29 18:11 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller,
Eric Dumazet, linux-arm-kernel, linux-stm32, netdev,
Ong Boon Leong, Paolo Abeni
In-Reply-To: <achJ1dfeT6Q8rBuX@shell.armlinux.org.uk>
On Sat, 28 Mar 2026 21:36:21 +0000 Russell King (Oracle) wrote:
> Hot off the press from reading various sources of dwmac information,
> this series attempts to fix the buggy hacks that were previously
> merged, and clean up the code handling this.
We have a limit of 15 outstanding patches per tree.
Please follow the community guidelines.
While I have you - you have a significantly negative "reviewer score".
You post much more than you review. Which should earn you extra 24h
of delay in our system. I've been trying to ignore that and prioritize
applying your patches but it'd be great if you could review a bit more.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox