Merge tag 'mac80211-next-for-net-next-2020-02-14' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== A few big new things: * 802.11 frame encapsulation offload support * more HE (802.11ax) support, including some for 6 GHz band * powersave in hwsim, for better testing Of course as usual there are various cleanups and small fixes. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -385,7 +385,7 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev);
|
||||
int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
|
||||
u16 frame_type, const u8 *match_data,
|
||||
int match_len);
|
||||
int match_len, struct netlink_ext_ack *extack);
|
||||
void cfg80211_mlme_unreg_wk(struct work_struct *wk);
|
||||
void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
|
||||
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
|
||||
|
@@ -4,6 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2015 Intel Deutschland GmbH
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -470,7 +471,7 @@ void cfg80211_mlme_unreg_wk(struct work_struct *wk)
|
||||
|
||||
int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
|
||||
u16 frame_type, const u8 *match_data,
|
||||
int match_len)
|
||||
int match_len, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
@@ -481,15 +482,38 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
|
||||
if (!wdev->wiphy->mgmt_stypes)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
|
||||
if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) {
|
||||
NL_SET_ERR_MSG(extack, "frame type not management");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
|
||||
if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid frame type");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
|
||||
if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
|
||||
if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Registration to specific type not supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* To support Pre Association Security Negotiation (PASN), registration
|
||||
* for authentication frames should be supported. However, as some
|
||||
* versions of the user space daemons wrongly register to all types of
|
||||
* authentication frames (which might result in unexpected behavior)
|
||||
* allow such registration if the request is for a specific
|
||||
* authentication algorithm number.
|
||||
*/
|
||||
if (wdev->iftype == NL80211_IFTYPE_STATION &&
|
||||
(frame_type & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_AUTH &&
|
||||
!(match_data && match_len >= 2)) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Authentication algorithm number required");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
|
||||
if (!nreg)
|
||||
@@ -504,6 +528,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
|
||||
continue;
|
||||
|
||||
if (memcmp(reg->match, match_data, mlen) == 0) {
|
||||
NL_SET_ERR_MSG(extack, "Match already configured");
|
||||
err = -EALREADY;
|
||||
break;
|
||||
}
|
||||
|
@@ -321,6 +321,13 @@ he_obss_pd_policy[NL80211_HE_OBSS_PD_ATTR_MAX + 1] = {
|
||||
NLA_POLICY_RANGE(NLA_U8, 1, 20),
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
|
||||
[NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63),
|
||||
[NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG },
|
||||
[NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
|
||||
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
|
||||
@@ -626,6 +633,9 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
[NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
|
||||
[NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
|
||||
[NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
|
||||
[NL80211_ATTR_SRC_MAC] = NLA_POLICY_ETH_ADDR,
|
||||
[NL80211_ATTR_DST_MAC] = NLA_POLICY_ETH_ADDR,
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -965,6 +975,9 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
|
||||
if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
|
||||
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
|
||||
goto nla_put_failure;
|
||||
if ((chan->flags & IEEE80211_CHAN_NO_HE) &&
|
||||
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HE))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
|
||||
@@ -1886,6 +1899,46 @@ static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nl80211_put_iftype_akm_suites(struct cfg80211_registered_device *rdev,
|
||||
struct sk_buff *msg)
|
||||
{
|
||||
int i;
|
||||
struct nlattr *nested, *nested_akms;
|
||||
const struct wiphy_iftype_akm_suites *iftype_akms;
|
||||
|
||||
if (!rdev->wiphy.num_iftype_akm_suites ||
|
||||
!rdev->wiphy.iftype_akm_suites)
|
||||
return 0;
|
||||
|
||||
nested = nla_nest_start(msg, NL80211_ATTR_IFTYPE_AKM_SUITES);
|
||||
if (!nested)
|
||||
return -ENOBUFS;
|
||||
|
||||
for (i = 0; i < rdev->wiphy.num_iftype_akm_suites; i++) {
|
||||
nested_akms = nla_nest_start(msg, i + 1);
|
||||
if (!nested_akms)
|
||||
return -ENOBUFS;
|
||||
|
||||
iftype_akms = &rdev->wiphy.iftype_akm_suites[i];
|
||||
|
||||
if (nl80211_put_iftypes(msg, NL80211_IFTYPE_AKM_ATTR_IFTYPES,
|
||||
iftype_akms->iftypes_mask))
|
||||
return -ENOBUFS;
|
||||
|
||||
if (nla_put(msg, NL80211_IFTYPE_AKM_ATTR_SUITES,
|
||||
sizeof(u32) * iftype_akms->n_akm_suites,
|
||||
iftype_akms->akm_suites)) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
nla_nest_end(msg, nested_akms);
|
||||
}
|
||||
|
||||
nla_nest_end(msg, nested);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nl80211_dump_wiphy_state {
|
||||
s64 filter_wiphy;
|
||||
long start;
|
||||
@@ -2444,6 +2497,9 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
|
||||
rdev->wiphy.akm_suites))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nl80211_put_iftype_akm_suites(rdev, msg))
|
||||
goto nla_put_failure;
|
||||
|
||||
/* done */
|
||||
state->split_start = 0;
|
||||
break;
|
||||
@@ -4512,6 +4568,30 @@ static int nl80211_parse_he_obss_pd(struct nlattr *attrs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nl80211_parse_he_bss_color(struct nlattr *attrs,
|
||||
struct cfg80211_he_bss_color *he_bss_color)
|
||||
{
|
||||
struct nlattr *tb[NL80211_HE_BSS_COLOR_ATTR_MAX + 1];
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NL80211_HE_BSS_COLOR_ATTR_MAX, attrs,
|
||||
he_bss_color_policy, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!tb[NL80211_HE_BSS_COLOR_ATTR_COLOR])
|
||||
return -EINVAL;
|
||||
|
||||
he_bss_color->color =
|
||||
nla_get_u8(tb[NL80211_HE_BSS_COLOR_ATTR_COLOR]);
|
||||
he_bss_color->disabled =
|
||||
nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
|
||||
he_bss_color->partial =
|
||||
nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
|
||||
const u8 *rates)
|
||||
{
|
||||
@@ -4804,6 +4884,14 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
|
||||
err = nl80211_parse_he_bss_color(
|
||||
info->attrs[NL80211_ATTR_HE_BSS_COLOR],
|
||||
¶ms.he_bss_color);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
nl80211_calculate_ap_params(¶ms);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
|
||||
@@ -10539,8 +10627,9 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
|
||||
nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
|
||||
nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
|
||||
nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
|
||||
nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]),
|
||||
info->extack);
|
||||
}
|
||||
|
||||
static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
||||
@@ -13609,6 +13698,7 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
||||
const u8 *buf;
|
||||
size_t len;
|
||||
u8 *dest;
|
||||
u8 src[ETH_ALEN];
|
||||
u16 proto;
|
||||
bool noencrypt;
|
||||
int err;
|
||||
@@ -13646,6 +13736,13 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* copy src address under wdev_lock, as we may copy wdev_address */
|
||||
if (info->attrs[NL80211_ATTR_SRC_MAC])
|
||||
ether_addr_copy(src,
|
||||
nla_data(info->attrs[NL80211_ATTR_SRC_MAC]));
|
||||
else
|
||||
ether_addr_copy(src, wdev_address(wdev));
|
||||
|
||||
wdev_unlock(wdev);
|
||||
|
||||
buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
|
||||
@@ -13656,7 +13753,7 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
||||
nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
|
||||
|
||||
return rdev_tx_control_port(rdev, dev, buf, len,
|
||||
dest, cpu_to_be16(proto), noencrypt);
|
||||
dest, src, cpu_to_be16(proto), noencrypt);
|
||||
|
||||
out:
|
||||
wdev_unlock(wdev);
|
||||
@@ -15913,7 +16010,8 @@ static int __nl80211_rx_control_port(struct net_device *dev,
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct ethhdr *ehdr = eth_hdr(skb);
|
||||
const u8 *addr = ehdr->h_source;
|
||||
const u8 *daddr = ehdr->h_dest;
|
||||
const u8 *saddr = ehdr->h_source;
|
||||
u16 proto = be16_to_cpu(skb->protocol);
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
@@ -15938,7 +16036,8 @@ static int __nl80211_rx_control_port(struct net_device *dev,
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
|
||||
nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
|
||||
NL80211_ATTR_PAD) ||
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, saddr) ||
|
||||
nla_put(msg, NL80211_ATTR_DST_MAC, ETH_ALEN, daddr) ||
|
||||
nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
|
||||
(unencrypted && nla_put_flag(msg,
|
||||
NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
|
||||
|
@@ -734,14 +734,14 @@ static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
static inline int rdev_tx_control_port(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
const void *buf, size_t len,
|
||||
const u8 *dest, __be16 proto,
|
||||
const bool noencrypt)
|
||||
const u8 *dest, const u8 *src,
|
||||
__be16 proto, const bool noencrypt)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_tx_control_port(&rdev->wiphy, dev, buf, len,
|
||||
dest, proto, noencrypt);
|
||||
dest, src, proto, noencrypt);
|
||||
ret = rdev->ops->tx_control_port(&rdev->wiphy, dev, buf, len,
|
||||
dest, proto, noencrypt);
|
||||
dest, src, proto, noencrypt);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -1569,6 +1569,8 @@ static u32 map_regdom_flags(u32 rd_flags)
|
||||
channel_flags |= IEEE80211_CHAN_NO_80MHZ;
|
||||
if (rd_flags & NL80211_RRF_NO_160MHZ)
|
||||
channel_flags |= IEEE80211_CHAN_NO_160MHZ;
|
||||
if (rd_flags & NL80211_RRF_NO_HE)
|
||||
channel_flags |= IEEE80211_CHAN_NO_HE;
|
||||
return channel_flags;
|
||||
}
|
||||
|
||||
|
@@ -1928,27 +1928,31 @@ TRACE_EVENT(rdev_mgmt_tx,
|
||||
|
||||
TRACE_EVENT(rdev_tx_control_port,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
const u8 *buf, size_t len, const u8 *dest, __be16 proto,
|
||||
const u8 *buf, size_t len,
|
||||
const u8 *dest, const u8 *src, __be16 proto,
|
||||
bool unencrypted),
|
||||
TP_ARGS(wiphy, netdev, buf, len, dest, proto, unencrypted),
|
||||
TP_ARGS(wiphy, netdev, buf, len, dest, src, proto, unencrypted),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
MAC_ENTRY(dest)
|
||||
__field(__be16, proto)
|
||||
MAC_ENTRY(src)
|
||||
__field(u16, proto)
|
||||
__field(bool, unencrypted)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(dest, dest);
|
||||
__entry->proto = proto;
|
||||
MAC_ASSIGN(src, src);
|
||||
__entry->proto = be16_to_cpu(proto);
|
||||
__entry->unencrypted = unencrypted;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ","
|
||||
" proto: 0x%x, unencrypted: %s",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dest),
|
||||
be16_to_cpu(__entry->proto),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", dest: " MAC_PR_FMT
|
||||
", src: " MAC_PR_FMT ", proto: 0x%x, unencrypted: %s",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG,
|
||||
MAC_PR_ARG(dest), MAC_PR_ARG(src),
|
||||
__entry->proto,
|
||||
BOOL_TO_STR(__entry->unencrypted))
|
||||
);
|
||||
|
||||
@@ -2840,6 +2844,7 @@ TRACE_EVENT(cfg80211_rx_control_port,
|
||||
TP_STRUCT__entry(
|
||||
NETDEV_ENTRY
|
||||
__field(int, len)
|
||||
MAC_ENTRY(to)
|
||||
MAC_ENTRY(from)
|
||||
__field(u16, proto)
|
||||
__field(bool, unencrypted)
|
||||
@@ -2847,12 +2852,14 @@ TRACE_EVENT(cfg80211_rx_control_port,
|
||||
TP_fast_assign(
|
||||
NETDEV_ASSIGN;
|
||||
__entry->len = skb->len;
|
||||
MAC_ASSIGN(to, eth_hdr(skb)->h_dest);
|
||||
MAC_ASSIGN(from, eth_hdr(skb)->h_source);
|
||||
__entry->proto = be16_to_cpu(skb->protocol);
|
||||
__entry->unencrypted = unencrypted;
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT ", len=%d, " MAC_PR_FMT ", proto: 0x%x, unencrypted: %s",
|
||||
NETDEV_PR_ARG, __entry->len, MAC_PR_ARG(from),
|
||||
TP_printk(NETDEV_PR_FMT ", len=%d, dest: " MAC_PR_FMT
|
||||
", src: " MAC_PR_FMT ", proto: 0x%x, unencrypted: %s",
|
||||
NETDEV_PR_ARG, __entry->len, MAC_PR_ARG(to), MAC_PR_ARG(from),
|
||||
__entry->proto, BOOL_TO_STR(__entry->unencrypted))
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user