]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: nl80211: Split the links handling of an association request
authorIlan Peer <ilan.peer@intel.com>
Thu, 2 Jan 2025 14:19:54 +0000 (16:19 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 13 Jan 2025 14:34:08 +0000 (15:34 +0100)
And move it to a separate function so it could later be reused for
dynamic addition of links.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250102161730.1e9c1873796a.I27a51c8c1d455f0a6d5b59f93f2c9ac49282febb@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/nl80211.c

index 111e47a0dc1a8d3ebb97191e018c1b5e3869dc83..5bf9a27e2c68e05043b613735b20f2db11d4a549 100644 (file)
@@ -11114,12 +11114,83 @@ static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device
        return bss;
 }
 
+static int nl80211_process_links(struct cfg80211_registered_device *rdev,
+                                struct cfg80211_assoc_link *links,
+                                const u8 *ssid, int ssid_len,
+                                struct genl_info *info)
+{
+       unsigned int attrsize = NUM_NL80211_ATTR * sizeof(struct nlattr *);
+       struct nlattr **attrs __free(kfree) = kzalloc(attrsize, GFP_KERNEL);
+       struct nlattr *link;
+       unsigned int link_id;
+       int rem, err;
+
+       if (!attrs)
+               return -ENOMEM;
+
+       nla_for_each_nested(link, info->attrs[NL80211_ATTR_MLO_LINKS], rem) {
+               memset(attrs, 0, attrsize);
+
+               nla_parse_nested(attrs, NL80211_ATTR_MAX, link, NULL, NULL);
+
+               if (!attrs[NL80211_ATTR_MLO_LINK_ID]) {
+                       NL_SET_BAD_ATTR(info->extack, link);
+                       return -EINVAL;
+               }
+
+               link_id = nla_get_u8(attrs[NL80211_ATTR_MLO_LINK_ID]);
+               /* cannot use the same link ID again */
+               if (links[link_id].bss) {
+                       NL_SET_BAD_ATTR(info->extack, link);
+                       return -EINVAL;
+               }
+               links[link_id].bss =
+                       nl80211_assoc_bss(rdev, ssid, ssid_len, attrs,
+                                         link_id, link_id);
+               if (IS_ERR(links[link_id].bss)) {
+                       err = PTR_ERR(links[link_id].bss);
+                       links[link_id].bss = NULL;
+                       NL_SET_ERR_MSG_ATTR(info->extack, link,
+                                           "Error fetching BSS for link");
+                       return err;
+               }
+
+               if (attrs[NL80211_ATTR_IE]) {
+                       links[link_id].elems = nla_data(attrs[NL80211_ATTR_IE]);
+                       links[link_id].elems_len =
+                               nla_len(attrs[NL80211_ATTR_IE]);
+
+                       if (cfg80211_find_elem(WLAN_EID_FRAGMENT,
+                                              links[link_id].elems,
+                                              links[link_id].elems_len)) {
+                               NL_SET_ERR_MSG_ATTR(info->extack,
+                                                   attrs[NL80211_ATTR_IE],
+                                                   "cannot deal with fragmentation");
+                               return -EINVAL;
+                       }
+
+                       if (cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+                                                  links[link_id].elems,
+                                                  links[link_id].elems_len)) {
+                               NL_SET_ERR_MSG_ATTR(info->extack,
+                                                   attrs[NL80211_ATTR_IE],
+                                                   "cannot deal with non-inheritance");
+                               return -EINVAL;
+                       }
+               }
+
+               links[link_id].disabled =
+                       nla_get_flag(attrs[NL80211_ATTR_MLO_LINK_DISABLED]);
+       }
+
+       return 0;
+}
+
 static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
        struct net_device *dev = info->user_ptr[1];
        struct cfg80211_assoc_request req = {};
-       struct nlattr **attrs = NULL;
        const u8 *ap_addr, *ssid;
        unsigned int link_id;
        int err, ssid_len;
@@ -11258,10 +11329,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
        req.link_id = nl80211_link_id_or_invalid(info->attrs);
 
        if (info->attrs[NL80211_ATTR_MLO_LINKS]) {
-               unsigned int attrsize = NUM_NL80211_ATTR * sizeof(*attrs);
-               struct nlattr *link;
-               int rem = 0;
-
                if (req.link_id < 0)
                        return -EINVAL;
 
@@ -11276,72 +11343,10 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                req.ap_mld_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
                ap_addr = req.ap_mld_addr;
 
-               attrs = kzalloc(attrsize, GFP_KERNEL);
-               if (!attrs)
-                       return -ENOMEM;
-
-               nla_for_each_nested(link,
-                                   info->attrs[NL80211_ATTR_MLO_LINKS],
-                                   rem) {
-                       memset(attrs, 0, attrsize);
-
-                       nla_parse_nested(attrs, NL80211_ATTR_MAX,
-                                        link, NULL, NULL);
-
-                       if (!attrs[NL80211_ATTR_MLO_LINK_ID]) {
-                               err = -EINVAL;
-                               NL_SET_BAD_ATTR(info->extack, link);
-                               goto free;
-                       }
-
-                       link_id = nla_get_u8(attrs[NL80211_ATTR_MLO_LINK_ID]);
-                       /* cannot use the same link ID again */
-                       if (req.links[link_id].bss) {
-                               err = -EINVAL;
-                               NL_SET_BAD_ATTR(info->extack, link);
-                               goto free;
-                       }
-                       req.links[link_id].bss =
-                               nl80211_assoc_bss(rdev, ssid, ssid_len, attrs,
-                                                 req.link_id, link_id);
-                       if (IS_ERR(req.links[link_id].bss)) {
-                               err = PTR_ERR(req.links[link_id].bss);
-                               req.links[link_id].bss = NULL;
-                               NL_SET_ERR_MSG_ATTR(info->extack,
-                                                   link, "Error fetching BSS for link");
-                               goto free;
-                       }
-
-                       if (attrs[NL80211_ATTR_IE]) {
-                               req.links[link_id].elems =
-                                       nla_data(attrs[NL80211_ATTR_IE]);
-                               req.links[link_id].elems_len =
-                                       nla_len(attrs[NL80211_ATTR_IE]);
-
-                               if (cfg80211_find_elem(WLAN_EID_FRAGMENT,
-                                                      req.links[link_id].elems,
-                                                      req.links[link_id].elems_len)) {
-                                       NL_SET_ERR_MSG_ATTR(info->extack,
-                                                           attrs[NL80211_ATTR_IE],
-                                                           "cannot deal with fragmentation");
-                                       err = -EINVAL;
-                                       goto free;
-                               }
-
-                               if (cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
-                                                          req.links[link_id].elems,
-                                                          req.links[link_id].elems_len)) {
-                                       NL_SET_ERR_MSG_ATTR(info->extack,
-                                                           attrs[NL80211_ATTR_IE],
-                                                           "cannot deal with non-inheritance");
-                                       err = -EINVAL;
-                                       goto free;
-                               }
-                       }
-
-                       req.links[link_id].disabled =
-                               nla_get_flag(attrs[NL80211_ATTR_MLO_LINK_DISABLED]);
-               }
+               err = nl80211_process_links(rdev, req.links, ssid, ssid_len,
+                                           info);
+               if (err)
+                       goto free;
 
                if (!req.links[req.link_id].bss) {
                        err = -EINVAL;
@@ -11361,9 +11366,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                        err = -EINVAL;
                        goto free;
                }
-
-               kfree(attrs);
-               attrs = NULL;
        } else {
                if (req.link_id >= 0)
                        return -EINVAL;
@@ -11423,7 +11425,6 @@ free:
        for (link_id = 0; link_id < ARRAY_SIZE(req.links); link_id++)
                cfg80211_put_bss(&rdev->wiphy, req.links[link_id].bss);
        cfg80211_put_bss(&rdev->wiphy, req.bss);
-       kfree(attrs);
 
        return err;
 }