diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-06-15 18:00:26 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-07-12 06:08:10 -0400 |
commit | 84efbb84cf76238faf26facf481c8675859bfaeb (patch) | |
tree | 3cc01b479a4c2db70b1b9ed59e1451d93acb5769 /net/wireless/nl80211.c | |
parent | 71bbc9943883cffaf5d7a7728a4e4c50b3ac44d3 (diff) |
cfg80211: use wireless_dev for interface management
In order to be able to create P2P Device wdevs, move
the virtual interface management over to wireless_dev
structures.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0dc3356eea40..789d0c7b287e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1971,7 +1971,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
1971 | { | 1971 | { |
1972 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 1972 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1973 | struct vif_params params; | 1973 | struct vif_params params; |
1974 | struct net_device *dev; | 1974 | struct wireless_dev *wdev; |
1975 | int err; | 1975 | int err; |
1976 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; | 1976 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; |
1977 | u32 flags; | 1977 | u32 flags; |
@@ -2001,16 +2001,14 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2001 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 2001 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
2002 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 2002 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
2003 | &flags); | 2003 | &flags); |
2004 | dev = rdev->ops->add_virtual_intf(&rdev->wiphy, | 2004 | wdev = rdev->ops->add_virtual_intf(&rdev->wiphy, |
2005 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), | 2005 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
2006 | type, err ? NULL : &flags, ¶ms); | 2006 | type, err ? NULL : &flags, ¶ms); |
2007 | if (IS_ERR(dev)) | 2007 | if (IS_ERR(wdev)) |
2008 | return PTR_ERR(dev); | 2008 | return PTR_ERR(wdev); |
2009 | 2009 | ||
2010 | if (type == NL80211_IFTYPE_MESH_POINT && | 2010 | if (type == NL80211_IFTYPE_MESH_POINT && |
2011 | info->attrs[NL80211_ATTR_MESH_ID]) { | 2011 | info->attrs[NL80211_ATTR_MESH_ID]) { |
2012 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
2013 | |||
2014 | wdev_lock(wdev); | 2012 | wdev_lock(wdev); |
2015 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != | 2013 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != |
2016 | IEEE80211_MAX_MESH_ID_LEN); | 2014 | IEEE80211_MAX_MESH_ID_LEN); |
@@ -2027,12 +2025,22 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2027 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) | 2025 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) |
2028 | { | 2026 | { |
2029 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2027 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2030 | struct net_device *dev = info->user_ptr[1]; | 2028 | struct wireless_dev *wdev = info->user_ptr[1]; |
2031 | 2029 | ||
2032 | if (!rdev->ops->del_virtual_intf) | 2030 | if (!rdev->ops->del_virtual_intf) |
2033 | return -EOPNOTSUPP; | 2031 | return -EOPNOTSUPP; |
2034 | 2032 | ||
2035 | return rdev->ops->del_virtual_intf(&rdev->wiphy, dev); | 2033 | /* |
2034 | * If we remove a wireless device without a netdev then clear | ||
2035 | * user_ptr[1] so that nl80211_post_doit won't dereference it | ||
2036 | * to check if it needs to do dev_put(). Otherwise it crashes | ||
2037 | * since the wdev has been freed, unlike with a netdev where | ||
2038 | * we need the dev_put() for the netdev to really be freed. | ||
2039 | */ | ||
2040 | if (!wdev->netdev) | ||
2041 | info->user_ptr[1] = NULL; | ||
2042 | |||
2043 | return rdev->ops->del_virtual_intf(&rdev->wiphy, wdev); | ||
2036 | } | 2044 | } |
2037 | 2045 | ||
2038 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) | 2046 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) |
@@ -6874,7 +6882,7 @@ static struct genl_ops nl80211_ops[] = { | |||
6874 | .doit = nl80211_del_interface, | 6882 | .doit = nl80211_del_interface, |
6875 | .policy = nl80211_policy, | 6883 | .policy = nl80211_policy, |
6876 | .flags = GENL_ADMIN_PERM, | 6884 | .flags = GENL_ADMIN_PERM, |
6877 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 6885 | .internal_flags = NL80211_FLAG_NEED_WDEV | |
6878 | NL80211_FLAG_NEED_RTNL, | 6886 | NL80211_FLAG_NEED_RTNL, |
6879 | }, | 6887 | }, |
6880 | { | 6888 | { |