cfg80211: refactor nl80211 monitor option parsing
authorJohannes Berg <johannes.berg@intel.com>
Wed, 12 Apr 2017 09:36:31 +0000 (11:36 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 13 Apr 2017 11:41:39 +0000 (13:41 +0200)
Refactor the parsing of monitor flags and the MU-MIMO options.
This will allow adding more things cleanly in the future and
also allows setting the latter already when creating a monitor
interface.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/nl80211.c

index a07a55eda55be0f23ee4f2ca95e256da22144498..671b635c0625ca3bef0aca2248ded63368080181 100644 (file)
@@ -2731,6 +2731,69 @@ static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
        return 0;
 }
 
+static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
+                                    enum nl80211_iftype type,
+                                    struct genl_info *info,
+                                    struct vif_params *params)
+{
+       bool change = false;
+       int err;
+
+       if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
+               if (type != NL80211_IFTYPE_MONITOR)
+                       return -EINVAL;
+
+               err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
+                                         &params->flags);
+               if (err)
+                       return err;
+
+               change = true;
+       }
+
+       if (params->flags & MONITOR_FLAG_ACTIVE &&
+           !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
+               return -EOPNOTSUPP;
+
+       if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
+               const u8 *mumimo_groups;
+               u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
+
+               if (type != NL80211_IFTYPE_MONITOR)
+                       return -EINVAL;
+
+               if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
+                       return -EOPNOTSUPP;
+
+               mumimo_groups =
+                       nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
+
+               /* bits 0 and 63 are reserved and must be zero */
+               if ((mumimo_groups[0] & BIT(7)) ||
+                   (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(0)))
+                       return -EINVAL;
+
+               params->vht_mumimo_groups = mumimo_groups;
+               change = true;
+       }
+
+       if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
+               u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
+
+               if (type != NL80211_IFTYPE_MONITOR)
+                       return -EINVAL;
+
+               if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
+                       return -EOPNOTSUPP;
+
+               params->vht_mumimo_follow_addr =
+                       nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
+               change = true;
+       }
+
+       return change ? 1 : 0;
+}
+
 static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
                               struct net_device *netdev, u8 use_4addr,
                               enum nl80211_iftype iftype)
@@ -2806,50 +2869,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
                params.use_4addr = -1;
        }
 
-       if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
-               if (ntype != NL80211_IFTYPE_MONITOR)
-                       return -EINVAL;
-               err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
-                                         &params.flags);
-               if (err)
-                       return err;
-
-               change = true;
-       }
-
-       if (params.flags & MONITOR_FLAG_ACTIVE &&
-           !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
-               return -EOPNOTSUPP;
-
-       if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
-               const u8 *mumimo_groups;
-               u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
-
-               if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
-                       return -EOPNOTSUPP;
-
-               mumimo_groups =
-                       nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
-
-               /* bits 0 and 63 are reserved and must be zero */
-               if ((mumimo_groups[0] & BIT(7)) ||
-                   (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(0)))
-                       return -EINVAL;
-
-               params.vht_mumimo_groups = mumimo_groups;
-               change = true;
-       }
-
-       if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
-               u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
-
-               if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
-                       return -EOPNOTSUPP;
-
-               params.vht_mumimo_follow_addr =
-                       nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
+       err = nl80211_parse_mon_options(rdev, ntype, info, &params);
+       if (err < 0)
+               return err;
+       if (err > 0)
                change = true;
-       }
 
        if (change)
                err = cfg80211_change_iface(rdev, dev, ntype, &params);
@@ -2905,19 +2929,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
                        return err;
        }
 
-       if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
-               if (type != NL80211_IFTYPE_MONITOR)
-                       return -EINVAL;
-
-               err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
-                                         &params.flags);
-               if (err)
-                       return err;
-       }
-
-       if (params.flags & MONITOR_FLAG_ACTIVE &&
-           !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
-               return -EOPNOTSUPP;
+       err = nl80211_parse_mon_options(rdev, type, info, &params);
+       if (err < 0)
+               return err;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)