]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: nl80211: refactor nl80211_parse_chandef
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Thu, 19 Feb 2026 09:47:11 +0000 (11:47 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 2 Mar 2026 08:22:52 +0000 (09:22 +0100)
In order to be able to use this function also for nested attributes,
change this function to receive a pointer to extack and to the
attributes array, instead of receiving the info and extracting them out
of it.
While at it, use NL_SET_ERR_MSG_ATTR with the frequency of the chandef.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260219114327.2b994566a63b.I6c2b6f4c7e2e09f4c47285ca4ac8a37b20700e19@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/nl80211.c
net/wireless/nl80211.h
net/wireless/pmsr.c

index 0da055dad159b25066826a3e0aa3d8e924193634..3486475dc11990c87e6919674faf88db06402b55 100644 (file)
@@ -3573,11 +3573,10 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
 }
 
 static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
-                                 struct genl_info *info, bool monitor,
+                                 struct netlink_ext_ack *extack,
+                                 struct nlattr **attrs, bool monitor,
                                  struct cfg80211_chan_def *chandef)
 {
-       struct netlink_ext_ack *extack = info->extack;
-       struct nlattr **attrs = info->attrs;
        u32 control_freq;
 
        if (!attrs[NL80211_ATTR_WIPHY_FREQ]) {
@@ -3587,10 +3586,10 @@ static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
        }
 
        control_freq = MHZ_TO_KHZ(
-                       nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
-       if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
+                       nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]));
+       if (attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
                control_freq +=
-                   nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
+                   nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
 
        memset(chandef, 0, sizeof(*chandef));
        chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq);
@@ -3661,40 +3660,43 @@ static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
                        attrs[NL80211_ATTR_S1G_PRIMARY_2MHZ]);
        }
 
-       if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
+       if (attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
                chandef->edmg.channels =
-                     nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
+                     nla_get_u8(attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
 
-               if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
+               if (attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
                        chandef->edmg.bw_config =
-                    nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
+                    nla_get_u8(attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
        } else {
                chandef->edmg.bw_config = 0;
                chandef->edmg.channels = 0;
        }
 
-       if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
+       if (attrs[NL80211_ATTR_PUNCT_BITMAP]) {
                chandef->punctured =
-                       nla_get_u32(info->attrs[NL80211_ATTR_PUNCT_BITMAP]);
+                       nla_get_u32(attrs[NL80211_ATTR_PUNCT_BITMAP]);
 
                if (chandef->punctured &&
                    !wiphy_ext_feature_isset(&rdev->wiphy,
                                             NL80211_EXT_FEATURE_PUNCT)) {
-                       NL_SET_ERR_MSG(extack,
-                                      "driver doesn't support puncturing");
+                       NL_SET_ERR_MSG_ATTR(extack,
+                                           attrs[NL80211_ATTR_WIPHY_FREQ],
+                                           "driver doesn't support puncturing");
                        return -EINVAL;
                }
        }
 
        if (!cfg80211_chandef_valid(chandef)) {
-               NL_SET_ERR_MSG(extack, "invalid channel definition");
+               NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
+                                   "invalid channel definition");
                return -EINVAL;
        }
 
        if (!_cfg80211_chandef_usable(&rdev->wiphy, chandef,
                                      IEEE80211_CHAN_DISABLED,
                                      monitor ? IEEE80211_CHAN_CAN_MONITOR : 0)) {
-               NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
+               NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
+                                   "(extension) channel is disabled");
                return -EINVAL;
        }
 
@@ -3709,10 +3711,11 @@ static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
 }
 
 int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
-                         struct genl_info *info,
+                         struct netlink_ext_ack *extack,
+                         struct nlattr **attrs,
                          struct cfg80211_chan_def *chandef)
 {
-       return _nl80211_parse_chandef(rdev, info, false, chandef);
+       return _nl80211_parse_chandef(rdev, extack, attrs, false, chandef);
 }
 
 static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
@@ -3739,7 +3742,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
                link_id = 0;
        }
 
-       result = _nl80211_parse_chandef(rdev, info,
+       result = _nl80211_parse_chandef(rdev, info->extack, info->attrs,
                                        iftype == NL80211_IFTYPE_MONITOR,
                                        &chandef);
        if (result)
@@ -6817,7 +6820,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
        }
 
        if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
-               err = nl80211_parse_chandef(rdev, info, &params->chandef);
+               err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+                                           &params->chandef);
                if (err)
                        goto out;
        } else if (wdev->valid_links) {
@@ -11293,7 +11297,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
        if (dfs_region == NL80211_DFS_UNSET)
                return -EINVAL;
 
-       err = nl80211_parse_chandef(rdev, info, &chandef);
+       err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
        if (err)
                return err;
 
@@ -11382,7 +11386,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,
                return -EINVAL;
        }
 
-       err = nl80211_parse_chandef(rdev, info, &chandef);
+       err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
        if (err) {
                GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
                return err;
@@ -11567,7 +11571,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
                goto free;
 
 skip_beacons:
-       err = nl80211_parse_chandef(rdev, info, &params.chandef);
+       err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+                                   &params.chandef);
        if (err)
                goto free;
 
@@ -12788,7 +12793,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
                ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
        }
 
-       err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
+       err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+                                   &ibss.chandef);
        if (err)
                return err;
 
@@ -13786,7 +13792,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
            duration > rdev->wiphy.max_remain_on_channel_duration)
                return -EINVAL;
 
-       err = nl80211_parse_chandef(rdev, info, &chandef);
+       err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
        if (err)
                return err;
 
@@ -14002,7 +14008,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
         */
        chandef.chan = NULL;
        if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
-               err = nl80211_parse_chandef(rdev, info, &chandef);
+               err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+                                           &chandef);
                if (err)
                        return err;
        }
@@ -14404,7 +14411,8 @@ static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
        struct ocb_setup setup = {};
        int err;
 
-       err = nl80211_parse_chandef(rdev, info, &setup.chandef);
+       err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+                                   &setup.chandef);
        if (err)
                return err;
 
@@ -14479,7 +14487,8 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
                cfg.auto_open_plinks = false;
 
        if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
-               err = nl80211_parse_chandef(rdev, info, &setup.chandef);
+               err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+                                           &setup.chandef);
                if (err)
                        return err;
        } else {
@@ -16954,7 +16963,7 @@ static int nl80211_tdls_channel_switch(struct sk_buff *skb,
            !info->attrs[NL80211_ATTR_OPER_CLASS])
                return -EINVAL;
 
-       err = nl80211_parse_chandef(rdev, info, &chandef);
+       err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
        if (err)
                return err;
 
index 5e25782af1e074be5e6a33798894457993dd5acd..048ba92c3e42971fca5262e67ae482dde99e95a5 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Portions of this file
- * Copyright (C) 2018, 2020-2024 Intel Corporation
+ * Copyright (C) 2018, 2020-2025 Intel Corporation
  */
 #ifndef __NET_WIRELESS_NL80211_H
 #define __NET_WIRELESS_NL80211_H
@@ -23,7 +23,8 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
 }
 
 int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
-                         struct genl_info *info,
+                         struct netlink_ext_ack *extack,
+                         struct nlattr **attrs,
                          struct cfg80211_chan_def *chandef);
 int nl80211_parse_random_mac(struct nlattr **attrs,
                             u8 *mac_addr, u8 *mac_addr_mask);
index 44bd88c9ea6649ef31355799b82edd105f226881..556f30f5d60a2f0cec655a024b3e0ec725a4d5bb 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Copyright (C) 2018 - 2021, 2023 - 2024 Intel Corporation
+ * Copyright (C) 2018 - 2021, 2023 - 2026 Intel Corporation
  */
 #include <net/cfg80211.h>
 #include "core.h"
@@ -237,7 +237,8 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
        if (err)
                return err;
 
-       err = nl80211_parse_chandef(rdev, info, &out->chandef);
+       err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
+                                   &out->chandef);
        if (err)
                return err;