Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 984c311b authored by Johannes Berg's avatar Johannes Berg
Browse files

cfg80211: clean up station WME attribute parsing



Parse the attributes first, and then disable the apply
flag if needed.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 2c1aabf3
Loading
Loading
Loading
Loading
+37 −31
Original line number Diff line number Diff line
@@ -3619,6 +3619,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)

	memset(&params, 0, sizeof(params));

	if (!rdev->ops->add_station)
		return -EOPNOTSUPP;

	if (!info->attrs[NL80211_ATTR_MAC])
		return -EINVAL;

@@ -3671,20 +3674,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
			return -EINVAL;
	}

	if (!rdev->ops->add_station)
		return -EOPNOTSUPP;

	if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
		return -EINVAL;

	switch (dev->ieee80211_ptr->iftype) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_AP_VLAN:
	case NL80211_IFTYPE_P2P_GO:
		/* 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)) &&
		    info->attrs[NL80211_ATTR_STA_WME]) {
	if (info->attrs[NL80211_ATTR_STA_WME]) {
		struct nlattr *tb[NL80211_STA_WME_MAX + 1];
		struct nlattr *nla;

@@ -3697,20 +3687,30 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
		if (tb[NL80211_STA_WME_UAPSD_QUEUES])
			params.uapsd_queues =
			     nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]);
			if (params.uapsd_queues &
					~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
		if (params.uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
			return -EINVAL;

		if (tb[NL80211_STA_WME_MAX_SP])
				params.max_sp =
				     nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
			params.max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);

			if (params.max_sp &
					~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
		if (params.max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
			return -EINVAL;

		params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
	}

	if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
		return -EINVAL;

	switch (dev->ieee80211_ptr->iftype) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_AP_VLAN:
	case NL80211_IFTYPE_P2P_GO:
		/* ignore WME attributes if iface/sta is not capable */
		if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
		    !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
			params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;

		/* TDLS peers cannot be added */
		if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
			return -EINVAL;
@@ -3731,6 +3731,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
			return PTR_ERR(params.vlan);
		break;
	case NL80211_IFTYPE_MESH_POINT:
		/* ignore uAPSD data */
		params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;

		/* associated is disallowed */
		if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
			return -EINVAL;
@@ -3739,6 +3742,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
			return -EINVAL;
		break;
	case NL80211_IFTYPE_STATION:
		/* ignore uAPSD data */
		params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;

		/* associated is disallowed */
		if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
			return -EINVAL;