cfg80211: require add_virtual_intf to return new dev
authorJohannes Berg <johannes.berg@intel.com>
Fri, 3 Dec 2010 08:20:42 +0000 (09:20 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 6 Dec 2010 21:01:28 +0000 (16:01 -0500)
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>
include/net/cfg80211.h
net/mac80211/cfg.c
net/wireless/nl80211.c

index 93a4b20..902895d 100644 (file)
@@ -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,
index ce69368..d34c7c3 100644 (file)
 #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)
index 0b90cab..cc2e5d6 100644 (file)
@@ -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, &params);
+       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)