cfg80211: move add/change interface monitor flags into params
Instead passing both flags, which can be NULL, and vif_params, which are never NULL, move the flags into the vif_params and use BIT(0), which is invalid from userspace, to indicate that the flags were changed. While updating all drivers, fix a small bug in wil6210 where it was setting the flags to 0 instead of leaving them unchanged. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -430,7 +430,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
||||
void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
|
||||
int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, enum nl80211_iftype ntype,
|
||||
u32 *flags, struct vif_params *params);
|
||||
struct vif_params *params);
|
||||
void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
|
||||
void cfg80211_process_wdev_events(struct wireless_dev *wdev);
|
||||
|
||||
|
@@ -2726,6 +2726,8 @@ static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
|
||||
if (flags[flag])
|
||||
*mntrflags |= (1<<flag);
|
||||
|
||||
*mntrflags |= MONITOR_FLAG_CHANGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2762,7 +2764,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
int err;
|
||||
enum nl80211_iftype otype, ntype;
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
u32 _flags, *flags = NULL;
|
||||
bool change = false;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
@@ -2809,14 +2810,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
if (ntype != NL80211_IFTYPE_MONITOR)
|
||||
return -EINVAL;
|
||||
err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
|
||||
&_flags);
|
||||
¶ms.flags);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
flags = &_flags;
|
||||
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;
|
||||
@@ -2847,12 +2851,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
change = true;
|
||||
}
|
||||
|
||||
if (flags && (*flags & MONITOR_FLAG_ACTIVE) &&
|
||||
!(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (change)
|
||||
err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms);
|
||||
err = cfg80211_change_iface(rdev, dev, ntype, ¶ms);
|
||||
else
|
||||
err = 0;
|
||||
|
||||
@@ -2870,7 +2870,6 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
struct sk_buff *msg;
|
||||
int err;
|
||||
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
|
||||
u32 flags;
|
||||
|
||||
/* to avoid failing a new interface creation due to pending removal */
|
||||
cfg80211_destroy_ifaces(rdev);
|
||||
@@ -2906,11 +2905,17 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
|
||||
info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
|
||||
&flags);
|
||||
if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
|
||||
if (type != NL80211_IFTYPE_MONITOR)
|
||||
return -EINVAL;
|
||||
|
||||
if (!err && (flags & MONITOR_FLAG_ACTIVE) &&
|
||||
err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
|
||||
¶ms.flags);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (params.flags & MONITOR_FLAG_ACTIVE &&
|
||||
!(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -2920,8 +2925,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
wdev = rdev_add_virtual_intf(rdev,
|
||||
nla_data(info->attrs[NL80211_ATTR_IFNAME]),
|
||||
NET_NAME_USER, type, err ? NULL : &flags,
|
||||
¶ms);
|
||||
NET_NAME_USER, type, ¶ms);
|
||||
if (WARN_ON(!wdev)) {
|
||||
nlmsg_free(msg);
|
||||
return -EPROTO;
|
||||
|
@@ -36,13 +36,13 @@ static inline void rdev_set_wakeup(struct cfg80211_registered_device *rdev,
|
||||
static inline struct wireless_dev
|
||||
*rdev_add_virtual_intf(struct cfg80211_registered_device *rdev, char *name,
|
||||
unsigned char name_assign_type,
|
||||
enum nl80211_iftype type, u32 *flags,
|
||||
enum nl80211_iftype type,
|
||||
struct vif_params *params)
|
||||
{
|
||||
struct wireless_dev *ret;
|
||||
trace_rdev_add_virtual_intf(&rdev->wiphy, name, type);
|
||||
ret = rdev->ops->add_virtual_intf(&rdev->wiphy, name, name_assign_type,
|
||||
type, flags, params);
|
||||
type, params);
|
||||
trace_rdev_return_wdev(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -61,12 +61,11 @@ rdev_del_virtual_intf(struct cfg80211_registered_device *rdev,
|
||||
static inline int
|
||||
rdev_change_virtual_intf(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, enum nl80211_iftype type,
|
||||
u32 *flags, struct vif_params *params)
|
||||
struct vif_params *params)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_change_virtual_intf(&rdev->wiphy, dev, type);
|
||||
ret = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, type, flags,
|
||||
params);
|
||||
ret = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, type, params);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -985,7 +985,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
|
||||
|
||||
int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, enum nl80211_iftype ntype,
|
||||
u32 *flags, struct vif_params *params)
|
||||
struct vif_params *params)
|
||||
{
|
||||
int err;
|
||||
enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;
|
||||
@@ -1043,7 +1043,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
||||
cfg80211_process_rdev_events(rdev);
|
||||
}
|
||||
|
||||
err = rdev_change_virtual_intf(rdev, dev, ntype, flags, params);
|
||||
err = rdev_change_virtual_intf(rdev, dev, ntype, params);
|
||||
|
||||
WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
|
||||
|
||||
|
@@ -62,7 +62,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
|
||||
|
||||
memset(&vifparams, 0, sizeof(vifparams));
|
||||
|
||||
return cfg80211_change_iface(rdev, dev, type, NULL, &vifparams);
|
||||
return cfg80211_change_iface(rdev, dev, type, &vifparams);
|
||||
}
|
||||
EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
|
||||
|
||||
|
Reference in New Issue
Block a user