* [PATCH net-next v2 0/3] rtnetlink: dump link-layer multicast addresses
@ 2026-09-09 1:33 Yuyang Huang
2026-09-09 1:33 ` [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps Yuyang Huang
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Yuyang Huang @ 2026-09-09 1:33 UTC (permalink / raw)
To: Yuyang Huang
Cc: David S. Miller, David Ahern, Donald Hunter, Eric Dumazet,
Ido Schimmel, Jakub Kicinski, Kuniyuki Iwashima, Nicolas Dichtel,
Nikolaos Gkarlis, Paolo Abeni, Sabrina Dubroca, Shuah Khan,
Simon Horman, Stanislav Fomichev, linux-kernel, linux-kselftest,
netdev
"ip maddr show" prints three kinds of entries: link-layer, IPv4 and
IPv6. The IPv4 and IPv6 ones can be read over netlink today: IPv6 has
had RTM_GETMULTICAST for a long time and IPv4 got it in eb4e17a1d915
("netlink: support dumping IPv4 multicast addresses"), with IFA_MC_USERS
added later so the user count no longer has to come from procfs.
The link-layer list is the missing piece. dev->mc, the addresses
programmed into the device filter, is only exported via
/proc/net/dev_mcast, so iproute2 still carries a procfs parser just for
that. This series closes the gap so that "ip maddr show" can be served
from rtnetlink alone.
Patch 1 handles RTM_GETMULTICAST dumps with ifa_family set to AF_PACKET
and walks dev->mc under netif_addr_lock_bh(), no RTNL. The reply reuses
the ifaddrmsg format of the IPv4 and IPv6 dumps: IFA_MULTICAST carries
the raw link-layer address, IFA_MC_USERS the reference count, and
IFA_F_PERMANENT is set for entries added with SIOCADDMULTI, which is the
"static" column /proc/net/dev_mcast has and "ip maddr" prints. A
non-zero ifa_index limits the dump to one device.
Patch 2 updates the rt-addr spec and patch 3 adds a selftest that
checks the filter, the user count and the permanent flag on a dummy
device.
Nothing changes for other families. AF_PACKET dumps returned
-EOPNOTSUPP before, so iproute2 can keep the procfs fallback for older
kernels. I have the iproute2 side ready and will post it once this is
in; with it, "ip maddr show" does not open /proc/net at all.
Changes in v2:
- Always validate the request header, not only with strict checking
- Use a single "with" statement in the selftest (ruff)
Yuyang Huang (3):
rtnetlink: add AF_PACKET multicast dumps
netlink: specs: rt-addr: document AF_PACKET multicast dumps
selftests: net: test AF_PACKET multicast dumps
Documentation/netlink/specs/rt-addr.yaml | 7 +-
net/core/rtnetlink.c | 129 +++++++++++++++++++++++
tools/testing/selftests/net/rtnetlink.py | 57 +++++++++-
3 files changed, 189 insertions(+), 4 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps
2026-09-09 1:33 [PATCH net-next v2 0/3] rtnetlink: dump link-layer multicast addresses Yuyang Huang
@ 2026-09-09 1:33 ` Yuyang Huang
2026-09-09 8:44 ` Nicolas Dichtel
2026-09-10 1:48 ` netdev-bot+sashiko
2026-09-09 1:34 ` [PATCH net-next v2 2/3] netlink: specs: rt-addr: document " Yuyang Huang
2026-09-09 1:34 ` [PATCH net-next v2 3/3] selftests: net: test " Yuyang Huang
2 siblings, 2 replies; 12+ messages in thread
From: Yuyang Huang @ 2026-09-09 1:33 UTC (permalink / raw)
To: Yuyang Huang
Cc: David S. Miller, David Ahern, Donald Hunter, Eric Dumazet,
Ido Schimmel, Jakub Kicinski, Kuniyuki Iwashima, Nicolas Dichtel,
Nikolaos Gkarlis, Paolo Abeni, Sabrina Dubroca, Shuah Khan,
Simon Horman, Stanislav Fomichev, linux-kernel, linux-kselftest,
netdev
RTM_GETMULTICAST dumps IPv4 and IPv6 multicast group memberships, but
the device multicast list (dev->mc) is only available through
/proc/net/dev_mcast, so "ip maddr show" still has to parse procfs for
its link-layer entries.
Handle RTM_GETMULTICAST dumps with ifa_family set to AF_PACKET and
report every entry of dev->mc in the existing ifaddrmsg format:
- IFA_MULTICAST carries the raw link-layer address
- IFA_MC_USERS carries the entry reference count
- IFA_F_PERMANENT marks entries added with SIOCADDMULTI
(netdev_hw_addr::global_use, "static" in "ip maddr")
- ifa_scope is RT_SCOPE_LINK
This covers every column of /proc/net/dev_mcast. AF_PACKET is the
family iproute2 already uses for link-layer addresses ("ip -0"), and
AF_UNSPEC keeps its "all families" meaning from RTM_GETADDR.
The default FDB dump also walks dev->mc, but only for Ethernet devices
without an ndo_fdb_dump of their own, so bridge, vxlan or macvlan
devices never show their multicast filter there, and it has no users
count or SIOCADDMULTI bit. Extending it would change "bridge fdb show"
output and add NDA_* attributes, while this dump needs no new uAPI.
There are no legacy users of AF_PACKET requests, so they are always
validated: prefixlen, flags and scope must be zero, no attributes are
accepted, and a non-zero ifa_index restricts the dump to that device.
The dump runs under RCU and netif_addr_lock_bh() and does not need
RTNL.
Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
---
net/core/rtnetlink.c | 129 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 81c5a6104dea..b2febdb6915e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -4566,6 +4566,133 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len ? : ret;
}
+static int rtnl_fill_mcaddr(struct sk_buff *skb, const struct net_device *dev,
+ const struct netdev_hw_addr *ha, u32 portid,
+ u32 seq, unsigned int flags)
+{
+ struct ifaddrmsg *ifm;
+ struct nlmsghdr *nlh;
+
+ nlh = nlmsg_put(skb, portid, seq, RTM_GETMULTICAST, sizeof(*ifm),
+ flags);
+ if (!nlh)
+ return -EMSGSIZE;
+
+ ifm = nlmsg_data(nlh);
+ ifm->ifa_family = AF_PACKET;
+ ifm->ifa_prefixlen = 0;
+ ifm->ifa_flags = ha->global_use ? IFA_F_PERMANENT : 0;
+ ifm->ifa_scope = RT_SCOPE_LINK;
+ ifm->ifa_index = dev->ifindex;
+
+ if (nla_put(skb, IFA_MULTICAST, dev->addr_len, ha->addr) ||
+ nla_put_u32(skb, IFA_MC_USERS, ha->refcount)) {
+ nlmsg_cancel(skb, nlh);
+ return -EMSGSIZE;
+ }
+
+ nlmsg_end(skb, nlh);
+ return 0;
+}
+
+static int rtnl_dump_mcaddr_dev(struct net_device *dev, struct sk_buff *skb,
+ struct netlink_callback *cb, int *s_addr_idx,
+ unsigned int flags)
+{
+ struct netdev_hw_addr *ha;
+ int addr_idx = 0;
+ int err = 0;
+
+ netif_addr_lock_bh(dev);
+ netdev_for_each_mc_addr(ha, dev) {
+ if (addr_idx < *s_addr_idx) {
+ addr_idx++;
+ continue;
+ }
+ err = rtnl_fill_mcaddr(skb, dev, ha, NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, flags);
+ if (err < 0)
+ break;
+ addr_idx++;
+ }
+ netif_addr_unlock_bh(dev);
+
+ *s_addr_idx = err < 0 ? addr_idx : 0;
+
+ return err;
+}
+
+static int rtnl_valid_dump_mcaddr_req(const struct nlmsghdr *nlh,
+ struct netlink_ext_ack *extack,
+ int *pifindex)
+{
+ struct ifaddrmsg *ifm;
+
+ ifm = nlmsg_payload(nlh, sizeof(*ifm));
+ if (!ifm) {
+ NL_SET_ERR_MSG(extack,
+ "Invalid header for multicast dump request");
+ return -EINVAL;
+ }
+
+ if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) {
+ NL_SET_ERR_MSG(extack,
+ "Invalid values in multicast dump header");
+ return -EINVAL;
+ }
+
+ if (nlmsg_attrlen(nlh, sizeof(*ifm))) {
+ NL_SET_ERR_MSG(extack,
+ "Invalid data after multicast dump header");
+ return -EINVAL;
+ }
+
+ *pifindex = ifm->ifa_index;
+
+ return 0;
+}
+
+static int rtnl_dump_mcaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct net *net = sock_net(skb->sk);
+ unsigned int flags = NLM_F_MULTI;
+ struct {
+ unsigned long ifindex;
+ int addr_idx;
+ } *ctx = (void *)cb->ctx;
+ struct net_device *dev;
+ int ifindex;
+ int err;
+
+ err = rtnl_valid_dump_mcaddr_req(cb->nlh, cb->extack, &ifindex);
+ if (err < 0)
+ return err;
+
+ rcu_read_lock();
+
+ if (ifindex) {
+ cb->answer_flags |= NLM_F_DUMP_FILTERED;
+ flags |= NLM_F_DUMP_FILTERED;
+ dev = dev_get_by_index_rcu(net, ifindex);
+ if (!dev) {
+ err = -ENODEV;
+ goto out;
+ }
+ err = rtnl_dump_mcaddr_dev(dev, skb, cb, &ctx->addr_idx, flags);
+ goto out;
+ }
+
+ for_each_netdev_dump(net, dev, ctx->ifindex) {
+ err = rtnl_dump_mcaddr_dev(dev, skb, cb, &ctx->addr_idx,
+ flags);
+ if (err < 0)
+ break;
+ }
+out:
+ rcu_read_unlock();
+ return err;
+}
+
struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
unsigned int change,
u32 event, gfp_t flags, int *new_nsid,
@@ -7251,6 +7378,8 @@ static const struct rtnl_msg_handler rtnetlink_rtnl_msg_handlers[] __initconst =
{.msgtype = RTM_SETSTATS, .doit = rtnl_stats_set},
{.msgtype = RTM_NEWLINKPROP, .doit = rtnl_newlinkprop},
{.msgtype = RTM_DELLINKPROP, .doit = rtnl_dellinkprop},
+ {.protocol = PF_PACKET, .msgtype = RTM_GETMULTICAST,
+ .dumpit = rtnl_dump_mcaddr, .flags = RTNL_FLAG_DUMP_UNLOCKED},
{.protocol = PF_BRIDGE, .msgtype = RTM_GETLINK,
.dumpit = rtnl_bridge_getlink},
{.protocol = PF_BRIDGE, .msgtype = RTM_DELLINK,
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v2 2/3] netlink: specs: rt-addr: document AF_PACKET multicast dumps
2026-09-09 1:33 [PATCH net-next v2 0/3] rtnetlink: dump link-layer multicast addresses Yuyang Huang
2026-09-09 1:33 ` [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps Yuyang Huang
@ 2026-09-09 1:34 ` Yuyang Huang
2026-09-10 1:48 ` netdev-bot+sashiko
2026-09-09 1:34 ` [PATCH net-next v2 3/3] selftests: net: test " Yuyang Huang
2 siblings, 1 reply; 12+ messages in thread
From: Yuyang Huang @ 2026-09-09 1:34 UTC (permalink / raw)
To: Yuyang Huang
Cc: David S. Miller, David Ahern, Donald Hunter, Eric Dumazet,
Ido Schimmel, Jakub Kicinski, Kuniyuki Iwashima, Nicolas Dichtel,
Nikolaos Gkarlis, Paolo Abeni, Sabrina Dubroca, Shuah Khan,
Simon Horman, Stanislav Fomichev, linux-kernel, linux-kselftest,
netdev
Mention that ifa-family AF_PACKET dumps link-layer multicast addresses
and what the permanent flag means for them.
Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
---
Documentation/netlink/specs/rt-addr.yaml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Documentation/netlink/specs/rt-addr.yaml b/Documentation/netlink/specs/rt-addr.yaml
index 0ecbd24c890c..2a2310cb0df0 100644
--- a/Documentation/netlink/specs/rt-addr.yaml
+++ b/Documentation/netlink/specs/rt-addr.yaml
@@ -168,7 +168,12 @@ operations:
attributes: *ifaddr-all
-
name: getmulticast
- doc: Get / dump IPv4/IPv6 multicast addresses.
+ doc: |
+ Get / dump multicast addresses. ifa-family selects the address
+ family: AF_INET or AF_INET6 for the IP multicast groups joined on
+ a device, AF_PACKET for the link-layer multicast addresses in the
+ device filter. Link-layer entries added with SIOCADDMULTI are
+ reported with the permanent flag set.
attribute-set: addr-attrs
fixed-header: ifaddrmsg
do:
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v2 3/3] selftests: net: test AF_PACKET multicast dumps
2026-09-09 1:33 [PATCH net-next v2 0/3] rtnetlink: dump link-layer multicast addresses Yuyang Huang
2026-09-09 1:33 ` [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps Yuyang Huang
2026-09-09 1:34 ` [PATCH net-next v2 2/3] netlink: specs: rt-addr: document " Yuyang Huang
@ 2026-09-09 1:34 ` Yuyang Huang
2026-09-10 1:48 ` netdev-bot+sashiko
2 siblings, 1 reply; 12+ messages in thread
From: Yuyang Huang @ 2026-09-09 1:34 UTC (permalink / raw)
To: Yuyang Huang
Cc: David S. Miller, David Ahern, Donald Hunter, Eric Dumazet,
Ido Schimmel, Jakub Kicinski, Kuniyuki Iwashima, Nicolas Dichtel,
Nikolaos Gkarlis, Paolo Abeni, Sabrina Dubroca, Shuah Khan,
Simon Horman, Stanislav Fomichev, linux-kernel, linux-kselftest,
netdev
Dump the link-layer multicast addresses of a dummy device and verify
that ifa_index restricts the dump to that device, that the all-hosts
address joined on link up is listed without IFA_F_PERMANENT and that an
address added with SIOCADDMULTI is listed with IFA_F_PERMANENT and
IFA_MC_USERS. Skip when the kernel does not support AF_PACKET dumps.
Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
---
tools/testing/selftests/net/rtnetlink.py | 57 ++++++++++++++++++++++--
1 file changed, 54 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/net/rtnetlink.py b/tools/testing/selftests/net/rtnetlink.py
index 5cc3ebdcf08d..cea636f10aeb 100755
--- a/tools/testing/selftests/net/rtnetlink.py
+++ b/tools/testing/selftests/net/rtnetlink.py
@@ -1,17 +1,21 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
+import errno
import socket
import struct
import time
from lib.py import bkg, ip, ksft_exit, ksft_run, ksft_eq, ksft_ge, ksft_true, KsftSkipEx
-from lib.py import ksft_not_in, ksft_not_none
-from lib.py import CmdExitFailure, NetNS, NetNSEnter, RtnlAddrFamily, RtnlRouteFamily
+from lib.py import ksft_in, ksft_not_in, ksft_not_none
+from lib.py import CmdExitFailure, NetNS, NetNSEnter, NlError, RtnlAddrFamily, RtnlRouteFamily
from lib.py import defer
IPV4_ALL_HOSTS_MULTICAST = b'\xe0\x00\x00\x01'
IPV4_TEST_MULTICAST = b'\xef\x01\x01\x01'
IPV6_TEST_MULTICAST = bytes.fromhex('ff020000000000000000000000000123')
+ETH_ALL_HOSTS_MULTICAST = bytes.fromhex('01005e000001')
+ETH_TEST_MULTICAST_STR = '01:00:5e:01:01:01'
+ETH_TEST_MULTICAST = bytes.fromhex(ETH_TEST_MULTICAST_STR.replace(':', ''))
def _users_for(rtnl: RtnlAddrFamily, family: int, grp: bytes, ifindex: int):
@@ -105,6 +109,52 @@ def dump_mcaddr6_check() -> None:
s2.close()
+def dump_mcaddr_l2_check() -> None:
+ """
+ Verify link-layer multicast addresses in an AF_PACKET RTM_GETMULTICAST
+ dump: the ifa-index filter, mc-users and the permanent flag.
+ """
+
+ with NetNS() as ns, NetNSEnter(str(ns)):
+ for ifname in ("dummy1", "dummy2"):
+ ip(f"link add name {ifname} type dummy")
+ ip(f"link set {ifname} up")
+ dev_idx = socket.if_nametoindex("dummy1")
+ ip(f"maddr add {ETH_TEST_MULTICAST_STR} dev dummy1")
+
+ rtnl = RtnlAddrFamily()
+ try:
+ addresses = rtnl.getmulticast(
+ {"ifa-family": socket.AF_PACKET, "ifa-index": dev_idx},
+ dump=True)
+ except NlError as e:
+ if e.error == errno.EOPNOTSUPP:
+ raise KsftSkipEx(
+ "kernel does not support AF_PACKET multicast dump")
+ raise
+
+ # dummy2 has entries as well, only dummy1 may be listed
+ ksft_eq({addr['ifa-index'] for addr in addresses}, {dev_idx},
+ "AF_PACKET multicast dump ignored ifa-index filter")
+
+ entries = {addr['multicast']: addr for addr in addresses}
+
+ # Bringing an Ethernet device up joins 224.0.0.1, which maps
+ # to 01:00:5e:00:00:01 in the device multicast list.
+ ksft_in(ETH_ALL_HOSTS_MULTICAST, entries,
+ "dummy1 does not have the all-hosts link-layer address")
+ ksft_not_in('permanent',
+ entries[ETH_ALL_HOSTS_MULTICAST]['ifa-flags'],
+ "protocol entry is permanent")
+
+ ksft_in(ETH_TEST_MULTICAST, entries,
+ "dummy1 does not have the SIOCADDMULTI address")
+ ksft_eq(entries[ETH_TEST_MULTICAST]['mc-users'], 1,
+ "unexpected mc-users for the SIOCADDMULTI address")
+ ksft_in('permanent', entries[ETH_TEST_MULTICAST]['ifa-flags'],
+ "SIOCADDMULTI entry is not permanent")
+
+
def ipv4_devconf_notify() -> None:
"""
Configure an interface and set ipv4-devconf values through netlink
@@ -315,7 +365,8 @@ def ipv6_route_del_reason_absent() -> None:
def main() -> None:
- ksft_run([dump_mcaddr_check, dump_mcaddr6_check, ipv4_devconf_notify,
+ ksft_run([dump_mcaddr_check, dump_mcaddr6_check, dump_mcaddr_l2_check,
+ ipv4_devconf_notify,
ipv6_route_del_reason_expired,
ipv6_route_del_reason_ra_withdrawn,
ipv6_route_del_reason_absent])
--
2.43.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps
2026-09-09 1:33 ` [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps Yuyang Huang
@ 2026-09-09 8:44 ` Nicolas Dichtel
2026-09-09 11:15 ` Yuyang Huang
2026-09-10 1:48 ` netdev-bot+sashiko
1 sibling, 1 reply; 12+ messages in thread
From: Nicolas Dichtel @ 2026-09-09 8:44 UTC (permalink / raw)
To: Yuyang Huang
Cc: David S. Miller, David Ahern, Donald Hunter, Eric Dumazet,
Ido Schimmel, Jakub Kicinski, Kuniyuki Iwashima, Nikolaos Gkarlis,
Paolo Abeni, Sabrina Dubroca, Shuah Khan, Simon Horman,
Stanislav Fomichev, linux-kernel, linux-kselftest, netdev
Le 09/09/2026 à 03:33, Yuyang Huang a écrit :
> RTM_GETMULTICAST dumps IPv4 and IPv6 multicast group memberships, but
> the device multicast list (dev->mc) is only available through
> /proc/net/dev_mcast, so "ip maddr show" still has to parse procfs for
> its link-layer entries.
>
> Handle RTM_GETMULTICAST dumps with ifa_family set to AF_PACKET and
> report every entry of dev->mc in the existing ifaddrmsg format:
>
> - IFA_MULTICAST carries the raw link-layer address
> - IFA_MC_USERS carries the entry reference count
> - IFA_F_PERMANENT marks entries added with SIOCADDMULTI
> (netdev_hw_addr::global_use, "static" in "ip maddr")
The global flag is also set for addresses added via dev_mc_add_excl(), ie by
some drivers.
> - ifa_scope is RT_SCOPE_LINK
>
> This covers every column of /proc/net/dev_mcast. AF_PACKET is the
> family iproute2 already uses for link-layer addresses ("ip -0"), and
> AF_UNSPEC keeps its "all families" meaning from RTM_GETADDR.
>
> The default FDB dump also walks dev->mc, but only for Ethernet devices
> without an ndo_fdb_dump of their own, so bridge, vxlan or macvlan
> devices never show their multicast filter there, and it has no users
> count or SIOCADDMULTI bit. Extending it would change "bridge fdb show"
> output and add NDA_* attributes, while this dump needs no new uAPI.
>
> There are no legacy users of AF_PACKET requests, so they are always
> validated: prefixlen, flags and scope must be zero, no attributes are
> accepted, and a non-zero ifa_index restricts the dump to that device.
> The dump runs under RCU and netif_addr_lock_bh() and does not need
> RTNL.
>
> Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
> ---
> net/core/rtnetlink.c | 129 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 129 insertions(+)
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 81c5a6104dea..b2febdb6915e 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -4566,6 +4566,133 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
> return skb->len ? : ret;
> }
>
> +static int rtnl_fill_mcaddr(struct sk_buff *skb, const struct net_device *dev,
> + const struct netdev_hw_addr *ha, u32 portid,
> + u32 seq, unsigned int flags)
> +{
> + struct ifaddrmsg *ifm;
> + struct nlmsghdr *nlh;
> +
> + nlh = nlmsg_put(skb, portid, seq, RTM_GETMULTICAST, sizeof(*ifm),
> + flags);
> + if (!nlh)
> + return -EMSGSIZE;
> +
> + ifm = nlmsg_data(nlh);
> + ifm->ifa_family = AF_PACKET;
> + ifm->ifa_prefixlen = 0;
> + ifm->ifa_flags = ha->global_use ? IFA_F_PERMANENT : 0;
I wonder if adding a new attribute IFA_F_GLOBAL would not make the API more
understandable.
> + ifm->ifa_scope = RT_SCOPE_LINK;
> + ifm->ifa_index = dev->ifindex;
> +
> + if (nla_put(skb, IFA_MULTICAST, dev->addr_len, ha->addr) ||
> + nla_put_u32(skb, IFA_MC_USERS, ha->refcount)) {
> + nlmsg_cancel(skb, nlh);
> + return -EMSGSIZE;
> + }
> +
> + nlmsg_end(skb, nlh);
> + return 0;
> +}
> +
> +static int rtnl_dump_mcaddr_dev(struct net_device *dev, struct sk_buff *skb,
> + struct netlink_callback *cb, int *s_addr_idx,
> + unsigned int flags)
> +{
> + struct netdev_hw_addr *ha;
> + int addr_idx = 0;
> + int err = 0;
> +
> + netif_addr_lock_bh(dev);
> + netdev_for_each_mc_addr(ha, dev) {
> + if (addr_idx < *s_addr_idx) {
> + addr_idx++;
> + continue;
> + }
> + err = rtnl_fill_mcaddr(skb, dev, ha, NETLINK_CB(cb->skb).portid,
> + cb->nlh->nlmsg_seq, flags);
> + if (err < 0)
> + break;
> + addr_idx++;
> + }
> + netif_addr_unlock_bh(dev);
> +
> + *s_addr_idx = err < 0 ? addr_idx : 0;
> +
> + return err;
> +}
> +
> +static int rtnl_valid_dump_mcaddr_req(const struct nlmsghdr *nlh,
> + struct netlink_ext_ack *extack,
> + int *pifindex)
> +{
> + struct ifaddrmsg *ifm;
> +
> + ifm = nlmsg_payload(nlh, sizeof(*ifm));
> + if (!ifm) {
> + NL_SET_ERR_MSG(extack,
> + "Invalid header for multicast dump request");
> + return -EINVAL;
> + }
> +
> + if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) {
> + NL_SET_ERR_MSG(extack,
> + "Invalid values in multicast dump header");
> + return -EINVAL;
> + }
> +
> + if (nlmsg_attrlen(nlh, sizeof(*ifm))) {
> + NL_SET_ERR_MSG(extack,
> + "Invalid data after multicast dump header");
> + return -EINVAL;
> + }
> +
> + *pifindex = ifm->ifa_index;
> +
> + return 0;
> +}
> +
> +static int rtnl_dump_mcaddr(struct sk_buff *skb, struct netlink_callback *cb)
> +{
> + struct net *net = sock_net(skb->sk);
For consistency with ipv4/ipv6, it would be nice to handle IFA_TARGET_NETNSID.
> + unsigned int flags = NLM_F_MULTI;
> + struct {
> + unsigned long ifindex;
> + int addr_idx;
> + } *ctx = (void *)cb->ctx;
> + struct net_device *dev;
> + int ifindex;
> + int err;
> +
> + err = rtnl_valid_dump_mcaddr_req(cb->nlh, cb->extack, &ifindex);
> + if (err < 0)
> + return err;
> +
> + rcu_read_lock();
> +
> + if (ifindex) {
> + cb->answer_flags |= NLM_F_DUMP_FILTERED;
> + flags |= NLM_F_DUMP_FILTERED;
> + dev = dev_get_by_index_rcu(net, ifindex);
> + if (!dev) {
> + err = -ENODEV;
> + goto out;
> + }
> + err = rtnl_dump_mcaddr_dev(dev, skb, cb, &ctx->addr_idx, flags);
> + goto out;
> + }
> +
> + for_each_netdev_dump(net, dev, ctx->ifindex) {
> + err = rtnl_dump_mcaddr_dev(dev, skb, cb, &ctx->addr_idx,
> + flags);
> + if (err < 0)
> + break;
> + }
> +out:
> + rcu_read_unlock();
> + return err;
> +}
> +
> struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
> unsigned int change,
> u32 event, gfp_t flags, int *new_nsid,
> @@ -7251,6 +7378,8 @@ static const struct rtnl_msg_handler rtnetlink_rtnl_msg_handlers[] __initconst =
> {.msgtype = RTM_SETSTATS, .doit = rtnl_stats_set},
> {.msgtype = RTM_NEWLINKPROP, .doit = rtnl_newlinkprop},
> {.msgtype = RTM_DELLINKPROP, .doit = rtnl_dellinkprop},
> + {.protocol = PF_PACKET, .msgtype = RTM_GETMULTICAST,
> + .dumpit = rtnl_dump_mcaddr, .flags = RTNL_FLAG_DUMP_UNLOCKED},
> {.protocol = PF_BRIDGE, .msgtype = RTM_GETLINK,
> .dumpit = rtnl_bridge_getlink},
> {.protocol = PF_BRIDGE, .msgtype = RTM_DELLINK,
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps
2026-09-09 8:44 ` Nicolas Dichtel
@ 2026-09-09 11:15 ` Yuyang Huang
0 siblings, 0 replies; 12+ messages in thread
From: Yuyang Huang @ 2026-09-09 11:15 UTC (permalink / raw)
To: nicolas.dichtel
Cc: David S. Miller, David Ahern, Donald Hunter, Eric Dumazet,
Ido Schimmel, Jakub Kicinski, Kuniyuki Iwashima, Nikolaos Gkarlis,
Paolo Abeni, Sabrina Dubroca, Shuah Khan, Simon Horman,
Stanislav Fomichev, linux-kernel, linux-kselftest, netdev
> > + - IFA_F_PERMANENT marks entries added with SIOCADDMULTI
> > + (netdev_hw_addr::global_use, "static" in "ip maddr")
> The global flag is also set for addresses added via dev_mc_add_excl(), ie by
> some drivers.
Thanks for the reminder, will fix the comment in patchset v3
> > + ifm->ifa_flags = ha->global_use ? IFA_F_PERMANENT : 0;
> I wonder if adding a new attribute IFA_F_GLOBAL would not make the API more
> understandable.
Good point, IFA_F_GLOBAL is indeed a better API that will fixed in patchset v3.
> > + struct net *net = sock_net(skb->sk);
> For consistency with ipv4/ipv6, it would be nice to handle IFA_TARGET_NETNSID.
Will do in v3.
Thanks,
Yuyang
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps
2026-09-09 1:33 ` [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps Yuyang Huang
2026-09-09 8:44 ` Nicolas Dichtel
@ 2026-09-10 1:48 ` netdev-bot+sashiko
2026-09-10 3:21 ` Yuyang Huang
1 sibling, 1 reply; 12+ messages in thread
From: netdev-bot+sashiko @ 2026-09-10 1:48 UTC (permalink / raw)
To: sigefriedhyy
Cc: davem, dsahern, donald.hunter, edumazet, idosch, kuba, kuniyu,
nicolas.dichtel, nickgarlis, pabeni, sd, shuah, horms, sdf.kernel,
linux-kernel, linux-kselftest, netdev
Thank you for your contribution! Sashiko AI review found 3 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 1 (1) · Low: 2
- [Medium] rtnl_dump_mcaddr()/rtnl_dump_mcaddr_dev()
(net/core/rtnetlink.c:4598-4623, 4655-4694) resume a multi-part…
- [Low] The commit message claims 'AF_UNSPEC keeps its "all families"
meaning from RTM_GETADDR'.
- [Low] Concern (validated as resolved within this series): after this
patch alone, Documentation/netlink/specs/rt-addr.yaml still described…
Pre-existing issues:
- [Medium] rtnl_fill_mcaddr() emits IFA_MULTICAST with a length read from
dev->addr_len at dump time (net/core/rtnetlink.c:4588), while struct…
--
rtnetlink: add AF_PACKET multicast dumps
This adds a PF_PACKET RTM_GETMULTICAST dump handler that walks dev->mc and
reports each netdev_hw_addr in the existing ifaddrmsg format, so the
link-layer multicast filter no longer has to be read from
/proc/net/dev_mcast. The handler runs unlocked with respect to RTNL, under
RCU and netif_addr_lock_bh().
A few questions below.
> This covers every column of /proc/net/dev_mcast. AF_PACKET is the
> family iproute2 already uses for link-layer addresses ("ip -0"), and
> AF_UNSPEC keeps its "all families" meaning from RTM_GETADDR.
[Severity: Low]
Is the AF_UNSPEC part of this sentence accurate for RTM_GETMULTICAST?
Grepping the tree, RTM_GETMULTICAST has a dumpit registered only for
PF_INET (net/ipv4/devinet.c), PF_INET6 (net/ipv6/addrconf.c) and, with this
patch, PF_PACKET. There is no PF_UNSPEC handler, so an AF_UNSPEC dump ends
up in the fallback in rtnetlink_rcv_msg():
link = rtnl_get_link(family, type);
if (!link || !link->dumpit) {
family = PF_UNSPEC;
link = rtnl_get_link(family, type);
if (!link || !link->dumpit)
goto err_unlock;
and returns -EOPNOTSUPP.
Additionally, rtnl_dump_all() explicitly skips PF_PACKET:
if (idx < s_idx || idx == PF_PACKET)
continue;
so even if a PF_UNSPEC RTM_GETMULTICAST handler were added later, these new
link-layer entries would not appear in an all-families dump. Could the
changelog drop or reword that claim?
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 81c5a6104dea..b2febdb6915e 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -4566,6 +4566,133 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
> return skb->len ? : ret;
> }
>
> +static int rtnl_fill_mcaddr(struct sk_buff *skb, const struct net_device *dev,
> + const struct netdev_hw_addr *ha, u32 portid,
> + u32 seq, unsigned int flags)
> +{
> + struct ifaddrmsg *ifm;
> + struct nlmsghdr *nlh;
> +
> + nlh = nlmsg_put(skb, portid, seq, RTM_GETMULTICAST, sizeof(*ifm),
> + flags);
> + if (!nlh)
> + return -EMSGSIZE;
> +
> + ifm = nlmsg_data(nlh);
> + ifm->ifa_family = AF_PACKET;
> + ifm->ifa_prefixlen = 0;
> + ifm->ifa_flags = ha->global_use ? IFA_F_PERMANENT : 0;
> + ifm->ifa_scope = RT_SCOPE_LINK;
> + ifm->ifa_index = dev->ifindex;
> +
> + if (nla_put(skb, IFA_MULTICAST, dev->addr_len, ha->addr) ||
[Severity: Medium]
This isn't a bug introduced by this patch, but can this copy expose
uninitialized bytes from ha->addr?
The length comes from dev->addr_len as read at dump time, while the entry
was filled in at insertion time by __hw_addr_create() in
net/core/dev_addr_lists.c:
ha = kmalloc(alloc_size, GFP_ATOMIC);
if (!ha)
return NULL;
memcpy(ha->addr, addr, addr_len);
The allocation is not zeroed and only addr_len bytes of
ha->addr[MAX_ADDR_LEN] are written.
If dev->addr_len grows after the entry was created, the tail is
uninitialized heap. One such path is tun's TUNSETLINK, which does:
tun->dev->type = (int) arg;
tun->dev->addr_len = tun_get_addr_len(tun->dev->type);
without flushing dev->mc, so a 6-byte entry added with SIOCADDMULTI while
the device was ARPHRD_ETHER would later be dumped as 16 bytes.
The same disclosure already exists through the world-readable
/proc/net/dev_mcast, where dev_mc_seq_show() prints with (int)dev->addr_len
over the same buffer, so this is not new here. Would it make sense to
bound the copy (min_t(unsigned int, dev->addr_len, MAX_ADDR_LEN)) and/or
zero the allocation in __hw_addr_create()?
[Severity: Low]
With this patch alone, Documentation/netlink/specs/rt-addr.yaml still
describes operation getmulticast as:
name: getmulticast
doc: Get / dump IPv4/IPv6 multicast addresses.
while this reply carries a link-layer IFA_MULTICAST of dev->addr_len bytes,
no IFA_CACHEINFO, ifa_scope of RT_SCOPE_LINK and IFA_F_PERMANENT with a
different meaning. The following patch in the series, "netlink: specs:
rt-addr: document AF_PACKET multicast dumps", updates that doc, so the
divergence only exists at this point in the series and needs no action.
> + nla_put_u32(skb, IFA_MC_USERS, ha->refcount)) {
> + nlmsg_cancel(skb, nlh);
> + return -EMSGSIZE;
> + }
> +
> + nlmsg_end(skb, nlh);
> + return 0;
> +}
> +
> +static int rtnl_dump_mcaddr_dev(struct net_device *dev, struct sk_buff *skb,
> + struct netlink_callback *cb, int *s_addr_idx,
> + unsigned int flags)
> +{
> + struct netdev_hw_addr *ha;
> + int addr_idx = 0;
> + int err = 0;
> +
> + netif_addr_lock_bh(dev);
> + netdev_for_each_mc_addr(ha, dev) {
> + if (addr_idx < *s_addr_idx) {
> + addr_idx++;
> + continue;
> + }
> + err = rtnl_fill_mcaddr(skb, dev, ha, NETLINK_CB(cb->skb).portid,
> + cb->nlh->nlmsg_seq, flags);
> + if (err < 0)
> + break;
> + addr_idx++;
> + }
> + netif_addr_unlock_bh(dev);
> +
> + *s_addr_idx = err < 0 ? addr_idx : 0;
[Severity: Medium]
Can this positional resume cursor silently skip dev->mc entries?
Resume state is the ordinal position in the list, and both
netif_addr_lock_bh() and rcu_read_lock() are dropped before the callback
returns, so between netlink dump rounds a writer can unlink an entry that
sits before the saved index:
net/core/dev_addr_lists.c:__hw_addr_del_entry() {
...
list_del_rcu(&ha->list);
kfree_rcu(ha, rcu_head);
list->count--;
...
}
Writers reaching that only need netif_addr_lock_bh() (dev_mc_del() from an
IGMP/MLD leave, SIOCDELMULTI, driver or bonding rx_mode churn), and RTNL
holders are free to run as well since the handler is registered with
RTNL_FLAG_DUMP_UNLOCKED. Removing N entries ahead of the saved addr_idx
shifts the survivors down and drops N entries that were never reported;
device add/remove similarly shifts the for_each_netdev_dump() cursor.
Neither cb->seq nor nl_dump_check_consistent() is used here, so
NLM_F_DUMP_INTR can never be set and user space sees a truncated dump that
looks complete.
The sibling handler for the same message type does maintain that:
net/ipv4/devinet.c:inet_dump_addr() {
...
cb->seq = inet_base_seq(tgt_net);
...
}
net/ipv4/devinet.c:in_dev_dump_ifmcaddr() {
...
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
...
}
Would setting cb->seq from a generation counter and calling
nl_dump_check_consistent() in rtnl_dump_mcaddr_dev() be appropriate here
too?
> +
> + return err;
> +}
> +
[ ... ]
> +static int rtnl_dump_mcaddr(struct sk_buff *skb, struct netlink_callback *cb)
> +{
> + struct net *net = sock_net(skb->sk);
> + unsigned int flags = NLM_F_MULTI;
> + struct {
> + unsigned long ifindex;
> + int addr_idx;
> + } *ctx = (void *)cb->ctx;
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260909013401.14408-1-sigefriedhyy%40gmail.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 2/3] netlink: specs: rt-addr: document AF_PACKET multicast dumps
2026-09-09 1:34 ` [PATCH net-next v2 2/3] netlink: specs: rt-addr: document " Yuyang Huang
@ 2026-09-10 1:48 ` netdev-bot+sashiko
2026-09-10 3:29 ` Yuyang Huang
0 siblings, 1 reply; 12+ messages in thread
From: netdev-bot+sashiko @ 2026-09-10 1:48 UTC (permalink / raw)
To: sigefriedhyy
Cc: davem, dsahern, donald.hunter, edumazet, idosch, kuba, kuniyu,
nicolas.dichtel, nickgarlis, pabeni, sd, shuah, horms, sdf.kernel,
linux-kernel, linux-kselftest, netdev
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 0 (1) · Low: 1
- [Low] The new getmulticast doc text in Documentation/netlink/specs/rt-
addr.yaml enumerates ifa-family values (AF_INET, AF_INET6, AF_PACKET)…
Pre-existing issues:
- [Medium] Documentation/netlink/specs/rt-addr.yaml declares a `do:`
operation for getmulticast (request value 58, reply value 58), and…
--
netlink: specs: rt-addr: document AF_PACKET multicast dumps
This updates the getmulticast doc string in the rt-addr YAML spec to
describe the ifa-family values it accepts, including the newly added
AF_PACKET link-layer multicast dumps and the meaning of the permanent
flag for those entries.
> diff --git a/Documentation/netlink/specs/rt-addr.yaml b/Documentation/netlink/specs/rt-addr.yaml
> index 0ecbd24c890c..2a2310cb0df0 100644
> --- a/Documentation/netlink/specs/rt-addr.yaml
> +++ b/Documentation/netlink/specs/rt-addr.yaml
> @@ -168,7 +168,12 @@ operations:
> attributes: *ifaddr-all
> -
> name: getmulticast
> - doc: Get / dump IPv4/IPv6 multicast addresses.
> + doc: |
> + Get / dump multicast addresses. ifa-family selects the address
> + family: AF_INET or AF_INET6 for the IP multicast groups joined on
> + a device, AF_PACKET for the link-layer multicast addresses in the
> + device filter. Link-layer entries added with SIOCADDMULTI are
> + reported with the permanent flag set.
[Severity: Low]
The new text reads as if ifa-family were a plain family selector, but
should it also mention that an AF_UNSPEC dump does not include the
AF_PACKET entries?
The PF_PACKET handler is only reachable when the request names the family
explicitly:
net/core/rtnetlink.c:
{.protocol = PF_PACKET, .msgtype = RTM_GETMULTICAST,
.dumpit = rtnl_dump_mcaddr, .flags = RTNL_FLAG_DUMP_UNLOCKED},
and the "all families" walk in rtnl_dump_all() skips it:
net/core/rtnetlink.c:rtnl_dump_all() {
...
if (idx < s_idx || idx == PF_PACKET)
continue;
...
}
So a client that sends RTM_GETMULTICAST with ifa_family = AF_UNSPEC and
NLM_F_DUMP gets only the IP multicast groups, with no error and no hint
that the device multicast filter was left out.
Since documenting the new AF_PACKET behaviour is the purpose of this
change, would it be worth stating that caveat here too?
> attribute-set: addr-attrs
> fixed-header: ifaddrmsg
> do:
[Severity: Medium]
This is a pre-existing issue and not introduced by this patch, but the
doc string being reworded here still says "Get / dump", and the spec still
declares a do operation for getmulticast:
Documentation/netlink/specs/rt-addr.yaml:
do:
request:
value: 58
attributes: []
reply:
value: 58
attributes: &mcaddr-attrs
Is there any family that implements a non-dump RTM_GETMULTICAST? All
three registrations are dumpit-only:
net/core/rtnetlink.c:
{.protocol = PF_PACKET, .msgtype = RTM_GETMULTICAST,
.dumpit = rtnl_dump_mcaddr, .flags = RTNL_FLAG_DUMP_UNLOCKED},
net/ipv4/devinet.c:
{.owner = THIS_MODULE, .protocol = PF_INET, .msgtype = RTM_GETMULTICAST,
.dumpit = inet_dump_ifmcaddr, .flags = RTNL_FLAG_DUMP_UNLOCKED},
net/ipv6/addrconf.c:
{.owner = THIS_MODULE, .protocol = PF_INET6, .msgtype = RTM_GETMULTICAST,
.dumpit = inet6_dump_ifmcaddr,
.flags = RTNL_FLAG_DUMP_UNLOCKED},
The non-dump dispatch path needs a doit callback, otherwise err stays
-EOPNOTSUPP:
net/core/rtnetlink.c:rtnetlink_rcv_msg() {
...
link = rtnl_get_link(family, type);
if (!link || !link->doit) {
family = PF_UNSPEC;
link = rtnl_get_link(PF_UNSPEC, type);
if (!link || !link->doit)
goto out_unlock;
}
...
}
So a ynl-generated single-object get built from this do block fails for
every ifa-family value, including the AF_PACKET case being documented
here. Since this change is extending the "Get" wording to AF_PACKET,
would it make sense to either drop the do block or say the operation is
dump-only?
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260909013401.14408-1-sigefriedhyy%40gmail.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 3/3] selftests: net: test AF_PACKET multicast dumps
2026-09-09 1:34 ` [PATCH net-next v2 3/3] selftests: net: test " Yuyang Huang
@ 2026-09-10 1:48 ` netdev-bot+sashiko
2026-09-10 3:31 ` Yuyang Huang
0 siblings, 1 reply; 12+ messages in thread
From: netdev-bot+sashiko @ 2026-09-10 1:48 UTC (permalink / raw)
To: sigefriedhyy
Cc: davem, dsahern, donald.hunter, edumazet, idosch, kuba, kuniyu,
nicolas.dichtel, nickgarlis, pabeni, sd, shuah, horms, sdf.kernel,
linux-kernel, linux-kselftest, netdev
Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 1 · Low: 1
- [Medium] In the new `dump_mcaddr_l2_check()`
(tools/testing/selftests/net/rtnetlink.py) the non-fatal presence…
- [Low] dump_mcaddr_l2_check() creates a netlink socket via `rtnl =
RtnlAddrFamily()` (rtnetlink.py:125) inside the temporary netns and…
--
selftests: net: test AF_PACKET multicast dumps
This adds dump_mcaddr_l2_check() to tools/testing/selftests/net/rtnetlink.py,
which dumps the link-layer multicast addresses of a dummy device and checks
the ifa-index filter, the flags of the all-hosts entry joined on link up, and
the mc-users/permanent state of an address added with SIOCADDMULTI. The case
is skipped when the kernel answers EOPNOTSUPP.
> diff --git a/tools/testing/selftests/net/rtnetlink.py b/tools/testing/selftests/net/rtnetlink.py
> index 5cc3ebdcf08d..cea636f10aeb 100755
> --- a/tools/testing/selftests/net/rtnetlink.py
> +++ b/tools/testing/selftests/net/rtnetlink.py
[ ... ]
> @@ -105,6 +109,52 @@ def dump_mcaddr6_check() -> None:
> s2.close()
>
>
> +def dump_mcaddr_l2_check() -> None:
> + """
> + Verify link-layer multicast addresses in an AF_PACKET RTM_GETMULTICAST
> + dump: the ifa-index filter, mc-users and the permanent flag.
> + """
> +
> + with NetNS() as ns, NetNSEnter(str(ns)):
> + for ifname in ("dummy1", "dummy2"):
> + ip(f"link add name {ifname} type dummy")
> + ip(f"link set {ifname} up")
> + dev_idx = socket.if_nametoindex("dummy1")
> + ip(f"maddr add {ETH_TEST_MULTICAST_STR} dev dummy1")
> +
> + rtnl = RtnlAddrFamily()
[Severity: Low]
Does dump_mcaddr_l2_check() leak the netlink socket created here?
YnlFamily.__init__() in tools/net/ynl/pyynl/lib/ynl.py opens
socket.socket(AF_NETLINK, SOCK_RAW, ...) and only releases it from close()
or __exit__(); there is no __del__, and the class installs
functools.partial(self._op, op_name) attributes on itself, so reference
cycles make prompt collection unreliable.
This function has no "with RtnlAddrFamily() as rtnl:", no finally: rtnl.close()
and no defer(rtnl.close). On the early-exit paths below (KsftSkipEx for
EOPNOTSUPP, the re-raised NlError) the traceback also keeps this frame alive.
Since the socket is created inside the temporary namespace, it keeps that
namespace referenced after NetNS teardown runs 'ip netns del'. The same
file already uses the symmetric idiom in _rtnl_route_subscribe():
rtnl = RtnlRouteFamily()
defer(rtnl.close)
Would adding defer(rtnl.close) here be preferable? Note the neighbouring
dump_mcaddr_check()/dump_mcaddr6_check() have the same open-without-close
shape, so this is mostly about consistency.
> + try:
> + addresses = rtnl.getmulticast(
> + {"ifa-family": socket.AF_PACKET, "ifa-index": dev_idx},
> + dump=True)
> + except NlError as e:
> + if e.error == errno.EOPNOTSUPP:
> + raise KsftSkipEx(
> + "kernel does not support AF_PACKET multicast dump")
> + raise
> +
> + # dummy2 has entries as well, only dummy1 may be listed
> + ksft_eq({addr['ifa-index'] for addr in addresses}, {dev_idx},
> + "AF_PACKET multicast dump ignored ifa-index filter")
> +
> + entries = {addr['multicast']: addr for addr in addresses}
> +
> + # Bringing an Ethernet device up joins 224.0.0.1, which maps
> + # to 01:00:5e:00:00:01 in the device multicast list.
> + ksft_in(ETH_ALL_HOSTS_MULTICAST, entries,
> + "dummy1 does not have the all-hosts link-layer address")
> + ksft_not_in('permanent',
> + entries[ETH_ALL_HOSTS_MULTICAST]['ifa-flags'],
> + "protocol entry is permanent")
[Severity: Medium]
Can this raise KeyError instead of reporting a clean check failure?
ksft_in() in tools/testing/selftests/net/lib/py/ksft.py is non-fatal, it
neither raises nor returns a value:
def ksft_in(a, b, comment=""):
if a not in b:
_fail("Check failed", a, "not in", b, comment)
So when the all-hosts entry is missing from the dump, execution continues to
entries[ETH_ALL_HOSTS_MULTICAST]['ifa-flags'], which raises KeyError while
the argument is evaluated. ksft_run() catches BaseException and prints a
traceback, and the remaining checks in this case never run - including the
two SIOCADDMULTI checks below.
The same applies to the ETH_TEST_MULTICAST lookups:
ksft_in(ETH_TEST_MULTICAST, entries, ...)
ksft_eq(entries[ETH_TEST_MULTICAST]['mc-users'], 1, ...)
ksft_in('permanent', entries[ETH_TEST_MULTICAST]['ifa-flags'], ...)
Would a guard before the subscripts be better here, matching the idiom used
elsewhere in this file, e.g. _users_for():
if 'mc-users' not in matches[0]:
return None
and the "if attrs is not None:" guard after ksft_not_none()?
> +
> + ksft_in(ETH_TEST_MULTICAST, entries,
> + "dummy1 does not have the SIOCADDMULTI address")
> + ksft_eq(entries[ETH_TEST_MULTICAST]['mc-users'], 1,
> + "unexpected mc-users for the SIOCADDMULTI address")
> + ksft_in('permanent', entries[ETH_TEST_MULTICAST]['ifa-flags'],
> + "SIOCADDMULTI entry is not permanent")
> +
> +
> def ipv4_devconf_notify() -> None:
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260909013401.14408-1-sigefriedhyy%40gmail.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps
2026-09-10 1:48 ` netdev-bot+sashiko
@ 2026-09-10 3:21 ` Yuyang Huang
0 siblings, 0 replies; 12+ messages in thread
From: Yuyang Huang @ 2026-09-10 3:21 UTC (permalink / raw)
To: netdev-bot+sashiko
Cc: davem, dsahern, donald.hunter, edumazet, idosch, kuba, kuniyu,
nicolas.dichtel, nickgarlis, pabeni, sd, shuah, horms, sdf.kernel,
linux-kernel, linux-kselftest, netdev
> Could the changelog drop or reword that claim?
Okay, I'll drop the claim in v4.
> This isn't a bug introduced by this patch, but can this copy expose
uninitialized bytes from ha->addr?
Not related to this patch, will send a follow up.
> Can this positional resume cursor silently skip dev->mc entries?
In theory yes, but this follows the existing dumps: there is no
generation counter for dev->mc, and in_dev_dump_ifmcaddr() has the
same window. I'd rather keep it consistent than add a counter just
for this one. If the issue is really worth fixing, I will send a
follow up to fix both places.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 2/3] netlink: specs: rt-addr: document AF_PACKET multicast dumps
2026-09-10 1:48 ` netdev-bot+sashiko
@ 2026-09-10 3:29 ` Yuyang Huang
0 siblings, 0 replies; 12+ messages in thread
From: Yuyang Huang @ 2026-09-10 3:29 UTC (permalink / raw)
To: netdev-bot+sashiko
Cc: davem, dsahern, donald.hunter, edumazet, idosch, kuba, kuniyu,
nicolas.dichtel, nickgarlis, pabeni, sd, shuah, horms, sdf.kernel,
linux-kernel, linux-kselftest, netdev
> should it also mention that an AF_UNSPEC dump does not include the
> AF_PACKET entries?
AF_UNSPEC dump returns -EOPNOTSUPP now, there is no PF_UNSPEC handler
for RTM_GETMULTICAST, so nothing is silently left out. I'll say that
ifa-family must be set in v4.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v2 3/3] selftests: net: test AF_PACKET multicast dumps
2026-09-10 1:48 ` netdev-bot+sashiko
@ 2026-09-10 3:31 ` Yuyang Huang
0 siblings, 0 replies; 12+ messages in thread
From: Yuyang Huang @ 2026-09-10 3:31 UTC (permalink / raw)
To: netdev-bot+sashiko
Cc: davem, dsahern, donald.hunter, edumazet, idosch, kuba, kuniyu,
nicolas.dichtel, nickgarlis, pabeni, sd, shuah, horms, sdf.kernel,
linux-kernel, linux-kselftest, netdev
On Thu, Sep 10, 2026 at 10:48 AM <netdev-bot+sashiko@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 2 potential
> issue(s) to consider:
>
> Critical: 0 · High: 0 · Medium: 1 · Low: 1
>
> - [Medium] In the new `dump_mcaddr_l2_check()`
> (tools/testing/selftests/net/rtnetlink.py) the non-fatal presence…
> - [Low] dump_mcaddr_l2_check() creates a netlink socket via `rtnl =
> RtnlAddrFamily()` (rtnetlink.py:125) inside the temporary netns and…
>
Good suggestion for the test case improvement, will fixed in patchset v4.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-09-10 3:31 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-09 1:33 [PATCH net-next v2 0/3] rtnetlink: dump link-layer multicast addresses Yuyang Huang
2026-09-09 1:33 ` [PATCH net-next v2 1/3] rtnetlink: add AF_PACKET multicast dumps Yuyang Huang
2026-09-09 8:44 ` Nicolas Dichtel
2026-09-09 11:15 ` Yuyang Huang
2026-09-10 1:48 ` netdev-bot+sashiko
2026-09-10 3:21 ` Yuyang Huang
2026-09-09 1:34 ` [PATCH net-next v2 2/3] netlink: specs: rt-addr: document " Yuyang Huang
2026-09-10 1:48 ` netdev-bot+sashiko
2026-09-10 3:29 ` Yuyang Huang
2026-09-09 1:34 ` [PATCH net-next v2 3/3] selftests: net: test " Yuyang Huang
2026-09-10 1:48 ` netdev-bot+sashiko
2026-09-10 3:31 ` Yuyang Huang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox