aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c8
-rw-r--r--net/wireless/nl80211.c199
2 files changed, 120 insertions, 87 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 393b2a4445b8..944051b43bad 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -976,6 +976,14 @@ static int ieee80211_change_station(struct wiphy *wiphy,
976 return -EINVAL; 976 return -EINVAL;
977 } 977 }
978 978
979 /* in station mode, supported rates are only valid with TDLS */
980 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
981 params->supported_rates &&
982 !test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
983 rcu_read_unlock();
984 return -EINVAL;
985 }
986
979 if (params->vlan && params->vlan != sta->sdata->dev) { 987 if (params->vlan && params->vlan != sta->sdata->dev) {
980 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 988 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
981 989
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d86428145c32..b07c4fc4ae22 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2579,6 +2579,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2579 params.ht_capa = 2579 params.ht_capa =
2580 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 2580 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
2581 2581
2582 if (!rdev->ops->change_station)
2583 return -EOPNOTSUPP;
2584
2582 if (parse_station_flags(info, &params)) 2585 if (parse_station_flags(info, &params))
2583 return -EINVAL; 2586 return -EINVAL;
2584 2587
@@ -2590,73 +2593,84 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2590 params.plink_state = 2593 params.plink_state =
2591 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); 2594 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
2592 2595
2593 params.vlan = get_vlan(info, rdev);
2594 if (IS_ERR(params.vlan))
2595 return PTR_ERR(params.vlan);
2596
2597 /* validate settings */
2598 err = 0;
2599
2600 switch (dev->ieee80211_ptr->iftype) { 2596 switch (dev->ieee80211_ptr->iftype) {
2601 case NL80211_IFTYPE_AP: 2597 case NL80211_IFTYPE_AP:
2602 case NL80211_IFTYPE_AP_VLAN: 2598 case NL80211_IFTYPE_AP_VLAN:
2603 case NL80211_IFTYPE_P2P_GO: 2599 case NL80211_IFTYPE_P2P_GO:
2604 /* disallow mesh-specific things */ 2600 /* disallow mesh-specific things */
2605 if (params.plink_action) 2601 if (params.plink_action)
2606 err = -EINVAL; 2602 return -EINVAL;
2603
2604 /* TDLS can't be set, ... */
2605 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
2606 return -EINVAL;
2607 /*
2608 * ... but don't bother the driver with it. This works around
2609 * a hostapd/wpa_supplicant issue -- it always includes the
2610 * TLDS_PEER flag in the mask even for AP mode.
2611 */
2612 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2613
2614 /* accept only the listed bits */
2615 if (params.sta_flags_mask &
2616 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
2617 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
2618 BIT(NL80211_STA_FLAG_WME) |
2619 BIT(NL80211_STA_FLAG_MFP)))
2620 return -EINVAL;
2621
2622 /* must be last in here for error handling */
2623 params.vlan = get_vlan(info, rdev);
2624 if (IS_ERR(params.vlan))
2625 return PTR_ERR(params.vlan);
2607 break; 2626 break;
2608 case NL80211_IFTYPE_P2P_CLIENT: 2627 case NL80211_IFTYPE_P2P_CLIENT:
2609 case NL80211_IFTYPE_STATION: 2628 case NL80211_IFTYPE_STATION:
2610 /* disallow things sta doesn't support */ 2629 /* disallow things sta doesn't support */
2611 if (params.plink_action) 2630 if (params.plink_action)
2612 err = -EINVAL; 2631 return -EINVAL;
2613 if (params.vlan)
2614 err = -EINVAL;
2615 if (params.supported_rates &&
2616 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
2617 err = -EINVAL;
2618 if (params.ht_capa) 2632 if (params.ht_capa)
2619 err = -EINVAL; 2633 return -EINVAL;
2620 if (params.listen_interval >= 0) 2634 if (params.listen_interval >= 0)
2621 err = -EINVAL; 2635 return -EINVAL;
2622 if (params.sta_flags_mask & 2636 /*
2623 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | 2637 * Don't allow userspace to change the TDLS_PEER flag,
2624 BIT(NL80211_STA_FLAG_TDLS_PEER))) 2638 * but silently ignore attempts to change it since we
2625 err = -EINVAL; 2639 * don't have state here to verify that it doesn't try
2626 /* can't change the TDLS bit */ 2640 * to change the flag.
2627 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) && 2641 */
2628 (params.sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER))) 2642 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2629 err = -EINVAL; 2643
2644 /* reject any changes other than AUTHORIZED */
2645 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
2646 return -EINVAL;
2630 break; 2647 break;
2631 case NL80211_IFTYPE_MESH_POINT: 2648 case NL80211_IFTYPE_MESH_POINT:
2632 /* disallow things mesh doesn't support */ 2649 /* disallow things mesh doesn't support */
2633 if (params.vlan) 2650 if (params.vlan)
2634 err = -EINVAL; 2651 return -EINVAL;
2635 if (params.ht_capa) 2652 if (params.ht_capa)
2636 err = -EINVAL; 2653 return -EINVAL;
2637 if (params.listen_interval >= 0) 2654 if (params.listen_interval >= 0)
2638 err = -EINVAL; 2655 return -EINVAL;
2656 /*
2657 * No special handling for TDLS here -- the userspace
2658 * mesh code doesn't have this bug.
2659 */
2639 if (params.sta_flags_mask & 2660 if (params.sta_flags_mask &
2640 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | 2661 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2641 BIT(NL80211_STA_FLAG_MFP) | 2662 BIT(NL80211_STA_FLAG_MFP) |
2642 BIT(NL80211_STA_FLAG_AUTHORIZED))) 2663 BIT(NL80211_STA_FLAG_AUTHORIZED)))
2643 err = -EINVAL; 2664 return -EINVAL;
2644 break; 2665 break;
2645 default: 2666 default:
2646 err = -EINVAL; 2667 return -EOPNOTSUPP;
2647 } 2668 }
2648 2669
2649 if (err) 2670 /* be aware of params.vlan when changing code here */
2650 goto out;
2651
2652 if (!rdev->ops->change_station) {
2653 err = -EOPNOTSUPP;
2654 goto out;
2655 }
2656 2671
2657 err = rdev->ops->change_station(&rdev->wiphy, dev, mac_addr, &params); 2672 err = rdev->ops->change_station(&rdev->wiphy, dev, mac_addr, &params);
2658 2673
2659 out:
2660 if (params.vlan) 2674 if (params.vlan)
2661 dev_put(params.vlan); 2675 dev_put(params.vlan);
2662 2676
@@ -2711,70 +2725,81 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2711 params.plink_action = 2725 params.plink_action =
2712 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 2726 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2713 2727
2728 if (!rdev->ops->add_station)
2729 return -EOPNOTSUPP;
2730
2714 if (parse_station_flags(info, &params)) 2731 if (parse_station_flags(info, &params))
2715 return -EINVAL; 2732 return -EINVAL;
2716 2733
2717 /* parse WME attributes if sta is WME capable */ 2734 switch (dev->ieee80211_ptr->iftype) {
2718 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && 2735 case NL80211_IFTYPE_AP:
2719 (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) && 2736 case NL80211_IFTYPE_AP_VLAN:
2720 info->attrs[NL80211_ATTR_STA_WME]) { 2737 case NL80211_IFTYPE_P2P_GO:
2721 struct nlattr *tb[NL80211_STA_WME_MAX + 1]; 2738 /* parse WME attributes if sta is WME capable */
2722 struct nlattr *nla; 2739 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
2740 (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) &&
2741 info->attrs[NL80211_ATTR_STA_WME]) {
2742 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
2743 struct nlattr *nla;
2744
2745 nla = info->attrs[NL80211_ATTR_STA_WME];
2746 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
2747 nl80211_sta_wme_policy);
2748 if (err)
2749 return err;
2723 2750
2724 nla = info->attrs[NL80211_ATTR_STA_WME]; 2751 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
2725 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla, 2752 params.uapsd_queues =
2726 nl80211_sta_wme_policy); 2753 nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]);
2727 if (err) 2754 if (params.uapsd_queues &
2728 return err; 2755 ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
2756 return -EINVAL;
2729 2757
2730 if (tb[NL80211_STA_WME_UAPSD_QUEUES]) 2758 if (tb[NL80211_STA_WME_MAX_SP])
2731 params.uapsd_queues = 2759 params.max_sp =
2732 nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]); 2760 nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
2733 if (params.uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
2734 return -EINVAL;
2735 2761
2736 if (tb[NL80211_STA_WME_MAX_SP]) 2762 if (params.max_sp &
2737 params.max_sp = 2763 ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
2738 nla_get_u8(tb[NL80211_STA_WME_MAX_SP]); 2764 return -EINVAL;
2739 2765
2740 if (params.max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) 2766 params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
2767 }
2768 /* TDLS peers cannot be added */
2769 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
2741 return -EINVAL; 2770 return -EINVAL;
2771 /* but don't bother the driver with it */
2772 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2742 2773
2743 params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD; 2774 /* must be last in here for error handling */
2775 params.vlan = get_vlan(info, rdev);
2776 if (IS_ERR(params.vlan))
2777 return PTR_ERR(params.vlan);
2778 break;
2779 case NL80211_IFTYPE_MESH_POINT:
2780 /* TDLS peers cannot be added */
2781 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
2782 return -EINVAL;
2783 break;
2784 case NL80211_IFTYPE_STATION:
2785 /* Only TDLS peers can be added */
2786 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
2787 return -EINVAL;
2788 /* Can only add if TDLS ... */
2789 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
2790 return -EOPNOTSUPP;
2791 /* ... with external setup is supported */
2792 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
2793 return -EOPNOTSUPP;
2794 break;
2795 default:
2796 return -EOPNOTSUPP;
2744 } 2797 }
2745 2798
2746 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2799 /* be aware of params.vlan when changing code here */
2747 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2748 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
2749 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO &&
2750 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
2751 return -EINVAL;
2752
2753 /*
2754 * Only managed stations can add TDLS peers, and only when the
2755 * wiphy supports external TDLS setup.
2756 */
2757 if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION &&
2758 !((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
2759 (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
2760 (rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)))
2761 return -EINVAL;
2762
2763 params.vlan = get_vlan(info, rdev);
2764 if (IS_ERR(params.vlan))
2765 return PTR_ERR(params.vlan);
2766
2767 /* validate settings */
2768 err = 0;
2769
2770 if (!rdev->ops->add_station) {
2771 err = -EOPNOTSUPP;
2772 goto out;
2773 }
2774 2800
2775 err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params); 2801 err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params);
2776 2802
2777 out:
2778 if (params.vlan) 2803 if (params.vlan)
2779 dev_put(params.vlan); 2804 dev_put(params.vlan);
2780 return err; 2805 return err;