diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4b4d3c8a1aed..24168560ebae 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1687,6 +1687,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
1687 | if (err) | 1687 | if (err) |
1688 | goto out_rtnl; | 1688 | goto out_rtnl; |
1689 | 1689 | ||
1690 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | ||
1691 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { | ||
1692 | err = -EINVAL; | ||
1693 | goto out; | ||
1694 | } | ||
1695 | |||
1690 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); | 1696 | err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); |
1691 | if (err) | 1697 | if (err) |
1692 | goto out; | 1698 | goto out; |
@@ -1738,7 +1744,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
1738 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); | 1744 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); |
1739 | params.listen_interval = | 1745 | params.listen_interval = |
1740 | nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); | 1746 | nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); |
1747 | |||
1741 | params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); | 1748 | params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); |
1749 | if (!params.aid || params.aid > IEEE80211_MAX_AID) | ||
1750 | return -EINVAL; | ||
1751 | |||
1742 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) | 1752 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) |
1743 | params.ht_capa = | 1753 | params.ht_capa = |
1744 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 1754 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |
@@ -3559,11 +3569,43 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) | |||
3559 | genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); | 3569 | genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); |
3560 | } | 3570 | } |
3561 | 3571 | ||
3572 | static int nl80211_add_scan_req(struct sk_buff *msg, | ||
3573 | struct cfg80211_registered_device *rdev) | ||
3574 | { | ||
3575 | struct cfg80211_scan_request *req = rdev->scan_req; | ||
3576 | struct nlattr *nest; | ||
3577 | int i; | ||
3578 | |||
3579 | if (WARN_ON(!req)) | ||
3580 | return 0; | ||
3581 | |||
3582 | nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS); | ||
3583 | if (!nest) | ||
3584 | goto nla_put_failure; | ||
3585 | for (i = 0; i < req->n_ssids; i++) | ||
3586 | NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid); | ||
3587 | nla_nest_end(msg, nest); | ||
3588 | |||
3589 | nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); | ||
3590 | if (!nest) | ||
3591 | goto nla_put_failure; | ||
3592 | for (i = 0; i < req->n_channels; i++) | ||
3593 | NLA_PUT_U32(msg, i, req->channels[i]->center_freq); | ||
3594 | nla_nest_end(msg, nest); | ||
3595 | |||
3596 | if (req->ie) | ||
3597 | NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie); | ||
3598 | |||
3599 | return 0; | ||
3600 | nla_put_failure: | ||
3601 | return -ENOBUFS; | ||
3602 | } | ||
3603 | |||
3562 | static int nl80211_send_scan_donemsg(struct sk_buff *msg, | 3604 | static int nl80211_send_scan_donemsg(struct sk_buff *msg, |
3563 | struct cfg80211_registered_device *rdev, | 3605 | struct cfg80211_registered_device *rdev, |
3564 | struct net_device *netdev, | 3606 | struct net_device *netdev, |
3565 | u32 pid, u32 seq, int flags, | 3607 | u32 pid, u32 seq, int flags, |
3566 | u32 cmd) | 3608 | u32 cmd) |
3567 | { | 3609 | { |
3568 | void *hdr; | 3610 | void *hdr; |
3569 | 3611 | ||
@@ -3574,7 +3616,8 @@ static int nl80211_send_scan_donemsg(struct sk_buff *msg, | |||
3574 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | 3616 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); |
3575 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 3617 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); |
3576 | 3618 | ||
3577 | /* XXX: we should probably bounce back the request? */ | 3619 | /* ignore errors and send incomplete event anyway */ |
3620 | nl80211_add_scan_req(msg, rdev); | ||
3578 | 3621 | ||
3579 | return genlmsg_end(msg, hdr); | 3622 | return genlmsg_end(msg, hdr); |
3580 | 3623 | ||
@@ -3828,7 +3871,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | |||
3828 | struct sk_buff *msg; | 3871 | struct sk_buff *msg; |
3829 | void *hdr; | 3872 | void *hdr; |
3830 | 3873 | ||
3831 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 3874 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); |
3832 | if (!msg) | 3875 | if (!msg) |
3833 | return; | 3876 | return; |
3834 | 3877 | ||
@@ -3852,7 +3895,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | |||
3852 | return; | 3895 | return; |
3853 | } | 3896 | } |
3854 | 3897 | ||
3855 | genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL); | 3898 | genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC); |
3856 | return; | 3899 | return; |
3857 | 3900 | ||
3858 | nla_put_failure: | 3901 | nla_put_failure: |