diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-06-15 18:05:37 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-07-12 06:10:40 -0400 |
commit | 1c90f9d404a45a1677c1e5791f5a2a8aaee0370a (patch) | |
tree | 4c1be9274172bc75c9a097ad7432aada73475570 /net/wireless/nl80211.c | |
parent | 84efbb84cf76238faf26facf481c8675859bfaeb (diff) |
nl80211: send interface after creation
After a new virtual interface is created, reply
to userspace with a message detailing it so it
knows the new wdev identifier.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 789d0c7b287e..6a9a1d7f51d1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1972,6 +1972,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
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 wireless_dev *wdev; | 1974 | struct wireless_dev *wdev; |
1975 | struct sk_buff *msg; | ||
1975 | int err; | 1976 | int err; |
1976 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; | 1977 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; |
1977 | u32 flags; | 1978 | u32 flags; |
@@ -1998,14 +1999,20 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
1998 | return err; | 1999 | return err; |
1999 | } | 2000 | } |
2000 | 2001 | ||
2002 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
2003 | if (!msg) | ||
2004 | return -ENOMEM; | ||
2005 | |||
2001 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 2006 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
2002 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 2007 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
2003 | &flags); | 2008 | &flags); |
2004 | wdev = rdev->ops->add_virtual_intf(&rdev->wiphy, | 2009 | wdev = rdev->ops->add_virtual_intf(&rdev->wiphy, |
2005 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), | 2010 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
2006 | type, err ? NULL : &flags, ¶ms); | 2011 | type, err ? NULL : &flags, ¶ms); |
2007 | if (IS_ERR(wdev)) | 2012 | if (IS_ERR(wdev)) { |
2013 | nlmsg_free(msg); | ||
2008 | return PTR_ERR(wdev); | 2014 | return PTR_ERR(wdev); |
2015 | } | ||
2009 | 2016 | ||
2010 | if (type == NL80211_IFTYPE_MESH_POINT && | 2017 | if (type == NL80211_IFTYPE_MESH_POINT && |
2011 | info->attrs[NL80211_ATTR_MESH_ID]) { | 2018 | info->attrs[NL80211_ATTR_MESH_ID]) { |
@@ -2019,7 +2026,13 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2019 | wdev_unlock(wdev); | 2026 | wdev_unlock(wdev); |
2020 | } | 2027 | } |
2021 | 2028 | ||
2022 | return 0; | 2029 | if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, |
2030 | rdev, wdev) < 0) { | ||
2031 | nlmsg_free(msg); | ||
2032 | return -ENOBUFS; | ||
2033 | } | ||
2034 | |||
2035 | return genlmsg_reply(msg, info); | ||
2023 | } | 2036 | } |
2024 | 2037 | ||
2025 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) | 2038 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) |