diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-12-03 09:20:42 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-06 16:01:28 -0500 |
commit | f9e10ce4cf86945eb5efcab31284c971877ed012 (patch) | |
tree | a56ec8ed84019901bf92aa969e366afb8b8ce36b | |
parent | 09b174702601079c3a04806754be30ffbd70db4d (diff) | |
download | op-kernel-dev-f9e10ce4cf86945eb5efcab31284c971877ed012.zip op-kernel-dev-f9e10ce4cf86945eb5efcab31284c971877ed012.tar.gz |
cfg80211: require add_virtual_intf to return new dev
cfg80211 used to do all its bookkeeping in
the notifier, but some new stuff will have
to use local variables so make the callback
return the netdev pointer.
Tested-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/net/cfg80211.h | 11 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 20 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 7 |
3 files changed, 24 insertions, 14 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 93a4b20..902895d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1033,7 +1033,8 @@ struct cfg80211_pmksa { * * @add_virtual_intf: create a new virtual interface with the given name, * must set the struct wireless_dev's iftype. Beware: You must create - * the new netdev in the wiphy's network namespace! + * the new netdev in the wiphy's network namespace! Returns the netdev, + * or an ERR_PTR. * * @del_virtual_intf: remove the virtual interface determined by ifindex. * @@ -1168,9 +1169,11 @@ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); int (*resume)(struct wiphy *wiphy); - int (*add_virtual_intf)(struct wiphy *wiphy, char *name, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params); + struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, + char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params); int (*del_virtual_intf)(struct wiphy *wiphy, struct net_device *dev); int (*change_virtual_intf)(struct wiphy *wiphy, struct net_device *dev, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ce69368..d34c7c3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -19,9 +19,10 @@ #include "rate.h" #include "mesh.h" -static int ieee80211_add_iface(struct wiphy *wiphy, char *name, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params) +static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) { struct ieee80211_local *local = wiphy_priv(wiphy); struct net_device *dev; @@ -29,12 +30,15 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, int err; err = ieee80211_if_add(local, name, &dev, type, params); - if (err || type != NL80211_IFTYPE_MONITOR || !flags) - return err; + if (err) + return ERR_PTR(err); - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - sdata->u.mntr_flags = *flags; - return 0; + if (type == NL80211_IFTYPE_MONITOR && flags) { + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + sdata->u.mntr_flags = *flags; + } + + return dev; } static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0b90cab..cc2e5d6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1368,6 +1368,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct vif_params params; + struct net_device *dev; int err; enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; u32 flags; @@ -1403,11 +1404,13 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, &flags); - err = rdev->ops->add_virtual_intf(&rdev->wiphy, + dev = rdev->ops->add_virtual_intf(&rdev->wiphy, nla_data(info->attrs[NL80211_ATTR_IFNAME]), type, err ? NULL : &flags, ¶ms); + if (IS_ERR(dev)) + return PTR_ERR(dev); - return err; + return 0; } static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) |