Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC28C4ABBDB; Thu, 17 Sep 2026 18:59:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789671563; cv=none; b=q4xi6JSWOd+T496gbUiqhZhxDdLi5b740RhhJKyaVdc6/eqgmGOabk2PCZzuCTAdcmzkztH2jGeASye2Uj5/DFXEaEm7M9Wo7KR4KG6qhxrMq9wc9uu6I4dz4DuuEVOudDcdnd2UbOZ8nkBLfOjZ6AaJ7zK2fVXetCDDkCQ8YWE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789671563; c=relaxed/simple; bh=GoWqbwTK3mw0Lm7JsmgAwO76LxdlI1hfs5qbjkR3/w8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EMEDuOxZoFizdkGD/ElsOGnOAvmd9ZckJRHwDSV6E08JnhX7njzkOKaXXH5/7i7zF5YKz8o7dTgb9hY8DilyP4z02JEtWbde/mpQxPSDaYIlJt+BgquIZgLe4P64f+lKDYjY/ix8q/vcUg3da85VjjAezM5XPzgs59VVOy1HNjc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=XBNZotox; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="XBNZotox" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9FD411F0089C; Thu, 17 Sep 2026 18:59:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1789671561; bh=TV/pvBh5hF83RUlzV8xiYu3D9GtWvwfHb/Vb7ph0YU0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=XBNZotoxXjl9Vm/ODf5K+6T/4pBni/sQM82vfHWWiEOKHoeiGAMYFt7Z19c6WY9i5 3OUQe0LqrIpOEnNZlVe6K8/7dxLzcsKVOFyPDz5IV1CPKY4SXiaaUsqfnE8auy7umj 02aQpcFSEtSnUuhMS4qO8l62WP/0Mbng/CYAw3F4= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Jakub Kicinski , Carolina Jubran , Mark Bloch , Sasha Levin Subject: [PATCH 6.12 1018/1102] netlink: introduce type-checking attribute iteration for nlmsg Date: Thu, 17 Sep 2026 16:16:01 +0100 Message-ID: <20260917151606.311948788@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260917151539.408551884@linuxfoundation.org> References: <20260917151539.408551884@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Carolina Jubran [ Upstream commit 42401c42389622424f2973ec57414f033ae6be8f ] Add the nlmsg_for_each_attr_type() macro to simplify iteration over attributes of a specific type in a Netlink message. Convert existing users in vxlan and nfsd to use the new macro. Suggested-by: Jakub Kicinski Signed-off-by: Carolina Jubran Signed-off-by: Mark Bloch Link: https://patch.msgid.link/20250629142138.361537-2-mbloch@nvidia.com Signed-off-by: Jakub Kicinski Stable-dep-of: bdcc85c2b05a ("nfsd: validate sockaddr length per family in listener_set") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/vxlan/vxlan_vnifilter.c | 13 ++++--------- fs/nfsd/nfsctl.c | 36 ++++++++++++++---------------------- include/net/netlink.h | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 31 deletions(-) --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -978,15 +978,10 @@ static int vxlan_vnifilter_process(struc if (!(vxlan->cfg.flags & VXLAN_F_VNIFILTER)) return -EOPNOTSUPP; - nlmsg_for_each_attr(attr, nlh, sizeof(*tmsg), rem) { - switch (nla_type(attr)) { - case VXLAN_VNIFILTER_ENTRY: - err = vxlan_process_vni_filter(vxlan, attr, - nlh->nlmsg_type, extack); - break; - default: - continue; - } + nlmsg_for_each_attr_type(attr, VXLAN_VNIFILTER_ENTRY, nlh, + sizeof(*tmsg), rem) { + err = vxlan_process_vni_filter(vxlan, attr, nlh->nlmsg_type, + extack); vnis++; if (err) break; --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1682,10 +1682,9 @@ int nfsd_nl_threads_set_doit(struct sk_b return -EINVAL; /* count number of SERVER_THREADS values */ - nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) { - if (nla_type(attr) == NFSD_A_SERVER_THREADS) - nrpools++; - } + nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_THREADS, info->nlhdr, + GENL_HDRLEN, rem) + nrpools++; mutex_lock(&nfsd_mutex); @@ -1696,12 +1695,11 @@ int nfsd_nl_threads_set_doit(struct sk_b } i = 0; - nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) { - if (nla_type(attr) == NFSD_A_SERVER_THREADS) { - nthreads[i++] = nla_get_u32(attr); - if (i >= nrpools) - break; - } + nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_THREADS, info->nlhdr, + GENL_HDRLEN, rem) { + nthreads[i++] = nla_get_u32(attr); + if (i >= nrpools) + break; } if (info->attrs[NFSD_A_SERVER_GRACETIME] || @@ -1842,14 +1840,12 @@ int nfsd_nl_version_set_doit(struct sk_b for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++) nfsd_minorversion(nn, i, NFSD_CLEAR); - nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) { + nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_PROTO_VERSION, info->nlhdr, + GENL_HDRLEN, rem) { struct nlattr *tb[NFSD_A_VERSION_MAX + 1]; u32 major, minor = 0; bool enabled; - if (nla_type(attr) != NFSD_A_SERVER_PROTO_VERSION) - continue; - if (nla_parse_nested(tb, NFSD_A_VERSION_MAX, attr, nfsd_version_nl_policy, info->extack) < 0) continue; @@ -2000,14 +1996,12 @@ int nfsd_nl_listener_set_doit(struct sk_ * Walk the list of server_socks from userland and move any that match * back to sv_permsocks */ - nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) { + nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_SOCK_ADDR, info->nlhdr, + GENL_HDRLEN, rem) { struct nlattr *tb[NFSD_A_SOCK_MAX + 1]; const char *xcl_name; struct sockaddr *sa; - if (nla_type(attr) != NFSD_A_SERVER_SOCK_ADDR) - continue; - if (nla_parse_nested(tb, NFSD_A_SOCK_MAX, attr, nfsd_sock_nl_policy, info->extack) < 0) continue; @@ -2062,15 +2056,13 @@ int nfsd_nl_listener_set_doit(struct sk_ svc_xprt_destroy_all(serv, net); /* walk list of addrs again, open any that still don't exist */ - nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) { + nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_SOCK_ADDR, info->nlhdr, + GENL_HDRLEN, rem) { struct nlattr *tb[NFSD_A_SOCK_MAX + 1]; const char *xcl_name; struct sockaddr *sa; int ret; - if (nla_type(attr) != NFSD_A_SERVER_SOCK_ADDR) - continue; - if (nla_parse_nested(tb, NFSD_A_SOCK_MAX, attr, nfsd_sock_nl_policy, info->extack) < 0) continue; --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -68,6 +68,8 @@ * nlmsg_for_each_msg() loop over all messages * nlmsg_validate() validate netlink message incl. attrs * nlmsg_for_each_attr() loop over all attributes + * nlmsg_for_each_attr_type() loop over all attributes with the + * given type * * Misc: * nlmsg_report() report back to application? @@ -941,6 +943,18 @@ static inline u32 nlmsg_seq(const struct nlmsg_attrlen(nlh, hdrlen), rem) /** + * nlmsg_for_each_attr_type - iterate over a stream of attributes + * @pos: loop counter, set to the current attribute + * @type: required attribute type for @pos + * @nlh: netlink message header + * @hdrlen: length of the family specific header + * @rem: initialized to len, holds bytes currently remaining in stream + */ +#define nlmsg_for_each_attr_type(pos, type, nlh, hdrlen, rem) \ + nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \ + if (nla_type(pos) == type) + +/** * nlmsg_put - Add a new netlink message to an skb * @skb: socket buffer to store message in * @portid: netlink PORTID of requesting application