forked from Minki/linux
cfg80211: accept no-op interface mode changes
When somebody tries to set the interface mode to the existing mode, don't ask the driver but silently accept the setting. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
86f04680df
commit
ac7f9cfa2c
@ -607,6 +607,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
|||||||
enum nl80211_iftype type;
|
enum nl80211_iftype type;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
u32 _flags, *flags = NULL;
|
u32 _flags, *flags = NULL;
|
||||||
|
bool change = false;
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
|
|
||||||
@ -620,11 +621,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
|||||||
type = dev->ieee80211_ptr->iftype;
|
type = dev->ieee80211_ptr->iftype;
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
|
|
||||||
err = -EINVAL;
|
|
||||||
if (info->attrs[NL80211_ATTR_IFTYPE]) {
|
if (info->attrs[NL80211_ATTR_IFTYPE]) {
|
||||||
type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
|
enum nl80211_iftype ntype;
|
||||||
if (type > NL80211_IFTYPE_MAX)
|
|
||||||
|
ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
|
||||||
|
if (type != ntype)
|
||||||
|
change = true;
|
||||||
|
type = ntype;
|
||||||
|
if (type > NL80211_IFTYPE_MAX) {
|
||||||
|
err = -EINVAL;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drv->ops->change_virtual_intf ||
|
if (!drv->ops->change_virtual_intf ||
|
||||||
@ -640,6 +647,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
|||||||
}
|
}
|
||||||
params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
|
params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
|
||||||
params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
|
params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
|
||||||
|
change = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
|
if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
|
||||||
@ -649,12 +657,18 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
|
|||||||
}
|
}
|
||||||
err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
|
err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
|
||||||
&_flags);
|
&_flags);
|
||||||
if (!err)
|
if (err)
|
||||||
flags = &_flags;
|
goto unlock;
|
||||||
|
|
||||||
|
flags = &_flags;
|
||||||
|
change = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
|
if (change)
|
||||||
type, flags, ¶ms);
|
err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
|
||||||
|
type, flags, ¶ms);
|
||||||
|
else
|
||||||
|
err = 0;
|
||||||
|
|
||||||
dev = __dev_get_by_index(&init_net, ifindex);
|
dev = __dev_get_by_index(&init_net, ifindex);
|
||||||
WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
|
WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
|
||||||
|
@ -66,6 +66,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
|
|||||||
struct cfg80211_registered_device *rdev;
|
struct cfg80211_registered_device *rdev;
|
||||||
struct vif_params vifparams;
|
struct vif_params vifparams;
|
||||||
enum nl80211_iftype type;
|
enum nl80211_iftype type;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!wdev)
|
if (!wdev)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@ -96,10 +97,16 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == wdev->iftype)
|
||||||
|
return 0;
|
||||||
|
|
||||||
memset(&vifparams, 0, sizeof(vifparams));
|
memset(&vifparams, 0, sizeof(vifparams));
|
||||||
|
|
||||||
return rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
|
ret = rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
|
||||||
NULL, &vifparams);
|
NULL, &vifparams);
|
||||||
|
WARN_ON(!ret && wdev->iftype != type);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cfg80211_wext_siwmode);
|
EXPORT_SYMBOL(cfg80211_wext_siwmode);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user