Linux 3.2.85
[pandora-kernel.git] / net / wireless / nl80211.c
index c06c365..446d224 100644 (file)
@@ -1815,6 +1815,9 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->get_key)
                return -EOPNOTSUPP;
 
+       if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
+               return -ENOENT;
+
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return -ENOMEM;
@@ -1832,10 +1835,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
        if (mac_addr)
                NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
 
-       if (pairwise && mac_addr &&
-           !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
-               return -ENOENT;
-
        err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise,
                                 mac_addr, &cookie, get_key_callback);
 
@@ -2007,7 +2006,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
        wdev_lock(dev->ieee80211_ptr);
        err = nl80211_key_allowed(dev->ieee80211_ptr);
 
-       if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr &&
+       if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
            !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
                err = -ENOENT;
 
@@ -2651,6 +2650,14 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
        if (parse_station_flags(info, &params))
                return -EINVAL;
 
+       /* HT requires QoS, but if we don't have that just ignore HT/VHT
+        * as userspace might just pass through the capabilities from the IEs
+        * directly, rather than enforcing this restriction and returning an
+        * error in this case.
+        */
+       if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
+               params.ht_capa = NULL;
+
        /* parse WME attributes if sta is WME capable */
        if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
            (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) &&
@@ -4804,6 +4811,9 @@ int cfg80211_testmode_reply(struct sk_buff *skb)
        void *hdr = ((void **)skb->cb)[1];
        struct nlattr *data = ((void **)skb->cb)[2];
 
+       /* clear CB data for netlink core to own from now on */
+       memset(skb->cb, 0, sizeof(skb->cb));
+
        if (WARN_ON(!rdev->testmode_info)) {
                kfree_skb(skb);
                return -EINVAL;
@@ -4826,12 +4836,17 @@ EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb);
 
 void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
 {
+       struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
        void *hdr = ((void **)skb->cb)[1];
        struct nlattr *data = ((void **)skb->cb)[2];
 
+       /* clear CB data for netlink core to own from now on */
+       memset(skb->cb, 0, sizeof(skb->cb));
+
        nla_nest_end(skb, data);
        genlmsg_end(skb, hdr);
-       genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp);
+       genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0,
+                               nl80211_testmode_mcgrp.id, gfp);
 }
 EXPORT_SYMBOL(cfg80211_testmode_event);
 #endif
@@ -7282,7 +7297,8 @@ void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
                return;
        }
 
-       genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+       genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+                               nl80211_mlme_mcgrp.id, gfp);
        return;
 
  nla_put_failure:
@@ -7480,7 +7496,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
        struct cfg80211_registered_device *rdev;
        struct wireless_dev *wdev;
 
-       if (state != NETLINK_URELEASE)
+       if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
                return NOTIFY_DONE;
 
        rcu_read_lock();