Skip to content

Commit

Permalink
cfg80211: accept no-op interface mode changes
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
  • Loading branch information
jmberg authored and linvjw committed Mar 28, 2009
1 parent 86f0468 commit ac7f9cf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
28 changes: 21 additions & 7 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
enum nl80211_iftype type;
struct net_device *dev;
u32 _flags, *flags = NULL;
bool change = false;

memset(&params, 0, sizeof(params));

Expand All @@ -620,11 +621,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
type = dev->ieee80211_ptr->iftype;
dev_put(dev);

err = -EINVAL;
if (info->attrs[NL80211_ATTR_IFTYPE]) {
type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
if (type > NL80211_IFTYPE_MAX)
enum nl80211_iftype ntype;

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;
}
}

if (!drv->ops->change_virtual_intf ||
Expand All @@ -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_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
change = true;
}

if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
Expand All @@ -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],
&_flags);
if (!err)
flags = &_flags;
if (err)
goto unlock;

flags = &_flags;
change = true;
}

err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
type, flags, &params);
if (change)
err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
type, flags, &params);
else
err = 0;

dev = __dev_get_by_index(&init_net, ifindex);
WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
Expand Down
11 changes: 9 additions & 2 deletions net/wireless/wext-compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
struct cfg80211_registered_device *rdev;
struct vif_params vifparams;
enum nl80211_iftype type;
int ret;

if (!wdev)
return -EOPNOTSUPP;
Expand Down Expand Up @@ -96,10 +97,16 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
return -EINVAL;
}

if (type == wdev->iftype)
return 0;

memset(&vifparams, 0, sizeof(vifparams));

return rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
NULL, &vifparams);
ret = rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
NULL, &vifparams);
WARN_ON(!ret && wdev->iftype != type);

return ret;
}
EXPORT_SYMBOL(cfg80211_wext_siwmode);

Expand Down

0 comments on commit ac7f9cf

Please sign in to comment.