From: Carolina Jubran <[email protected]>

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 <[email protected]>
Signed-off-by: Carolina Jubran <[email protected]>
Signed-off-by: Mark Bloch <[email protected]>
---
 drivers/net/vxlan/vxlan_vnifilter.c | 13 ++++-------
 fs/nfsd/nfsctl.c                    | 36 +++++++++++------------------
 include/net/netlink.h               | 14 +++++++++++
 3 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/drivers/net/vxlan/vxlan_vnifilter.c 
b/drivers/net/vxlan/vxlan_vnifilter.c
index 4ff56d9f8f28..adc89e651e27 100644
--- a/drivers/net/vxlan/vxlan_vnifilter.c
+++ b/drivers/net/vxlan/vxlan_vnifilter.c
@@ -971,15 +971,10 @@ static int vxlan_vnifilter_process(struct sk_buff *skb, 
struct nlmsghdr *nlh,
        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;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 6a42cc7a845a..657d44afc062 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1621,10 +1621,9 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct 
genl_info *info)
                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);
 
@@ -1635,12 +1634,11 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, 
struct genl_info *info)
        }
 
        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] ||
@@ -1781,14 +1779,12 @@ int nfsd_nl_version_set_doit(struct sk_buff *skb, 
struct genl_info *info)
        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;
@@ -1939,14 +1935,12 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, 
struct genl_info *info)
         * 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;
@@ -2001,15 +1995,13 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, 
struct genl_info *info)
                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;
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 90a560dc167a..1a8356ca4b78 100644
--- 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?
@@ -966,6 +968,18 @@ static inline u32 nlmsg_seq(const struct nlmsghdr *nlh)
        nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
                          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
-- 
2.34.1


Reply via email to