diff options
author | David S. Miller <davem@davemloft.net> | 2018-07-24 12:38:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-24 12:38:50 -0400 |
commit | e1adf31471f01df708b4c10a380f9304a687d867 (patch) | |
tree | e3cc79ec9252ca8fad9e882f254505893fe69ece | |
parent | 144fe2bfd236dc814eae587aea7e2af03dbdd755 (diff) | |
parent | e31f6456c01c76f154e1b25cd54df97809a49edb (diff) |
Merge tag 'mac80211-for-davem-2018-07-24' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says:
====================
Only a few fixes:
* always keep regulatory user hint
* add missing break statement in station flags parsing
* fix non-linear SKBs in port-control-over-nl80211
* reconfigure VLAN stations during HW restart
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/cfg80211.h | 12 | ||||
-rw-r--r-- | net/mac80211/rx.c | 5 | ||||
-rw-r--r-- | net/mac80211/util.c | 3 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 25 | ||||
-rw-r--r-- | net/wireless/reg.c | 28 | ||||
-rw-r--r-- | net/wireless/trace.h | 18 |
6 files changed, 38 insertions, 53 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5fbfe61f41c6..1beb3ead0385 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -5835,10 +5835,11 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, | |||
5835 | /** | 5835 | /** |
5836 | * cfg80211_rx_control_port - notification about a received control port frame | 5836 | * cfg80211_rx_control_port - notification about a received control port frame |
5837 | * @dev: The device the frame matched to | 5837 | * @dev: The device the frame matched to |
5838 | * @buf: control port frame | 5838 | * @skb: The skbuf with the control port frame. It is assumed that the skbuf |
5839 | * @len: length of the frame data | 5839 | * is 802.3 formatted (with 802.3 header). The skb can be non-linear. |
5840 | * @addr: The peer from which the frame was received | 5840 | * This function does not take ownership of the skb, so the caller is |
5841 | * @proto: frame protocol, typically PAE or Pre-authentication | 5841 | * responsible for any cleanup. The caller must also ensure that |
5842 | * skb->protocol is set appropriately. | ||
5842 | * @unencrypted: Whether the frame was received unencrypted | 5843 | * @unencrypted: Whether the frame was received unencrypted |
5843 | * | 5844 | * |
5844 | * This function is used to inform userspace about a received control port | 5845 | * This function is used to inform userspace about a received control port |
@@ -5851,8 +5852,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, | |||
5851 | * Return: %true if the frame was passed to userspace | 5852 | * Return: %true if the frame was passed to userspace |
5852 | */ | 5853 | */ |
5853 | bool cfg80211_rx_control_port(struct net_device *dev, | 5854 | bool cfg80211_rx_control_port(struct net_device *dev, |
5854 | const u8 *buf, size_t len, | 5855 | struct sk_buff *skb, bool unencrypted); |
5855 | const u8 *addr, u16 proto, bool unencrypted); | ||
5856 | 5856 | ||
5857 | /** | 5857 | /** |
5858 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event | 5858 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0a38cc1cbebc..932985ca4e66 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2254,11 +2254,8 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, | |||
2254 | sdata->control_port_over_nl80211)) { | 2254 | sdata->control_port_over_nl80211)) { |
2255 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2255 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2256 | bool noencrypt = status->flag & RX_FLAG_DECRYPTED; | 2256 | bool noencrypt = status->flag & RX_FLAG_DECRYPTED; |
2257 | struct ethhdr *ehdr = eth_hdr(skb); | ||
2258 | 2257 | ||
2259 | cfg80211_rx_control_port(dev, skb->data, skb->len, | 2258 | cfg80211_rx_control_port(dev, skb, noencrypt); |
2260 | ehdr->h_source, | ||
2261 | be16_to_cpu(skb->protocol), noencrypt); | ||
2262 | dev_kfree_skb(skb); | 2259 | dev_kfree_skb(skb); |
2263 | } else { | 2260 | } else { |
2264 | /* deliver to local stack */ | 2261 | /* deliver to local stack */ |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5e2e511c4a6f..d02fbfec3783 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -2111,7 +2111,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
2111 | if (!sta->uploaded) | 2111 | if (!sta->uploaded) |
2112 | continue; | 2112 | continue; |
2113 | 2113 | ||
2114 | if (sta->sdata->vif.type != NL80211_IFTYPE_AP) | 2114 | if (sta->sdata->vif.type != NL80211_IFTYPE_AP && |
2115 | sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN) | ||
2115 | continue; | 2116 | continue; |
2116 | 2117 | ||
2117 | for (state = IEEE80211_STA_NOTEXIST; | 2118 | for (state = IEEE80211_STA_NOTEXIST; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4eece06be1e7..80bc986c79e5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -4409,6 +4409,7 @@ static int parse_station_flags(struct genl_info *info, | |||
4409 | params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) | | 4409 | params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
4410 | BIT(NL80211_STA_FLAG_MFP) | | 4410 | BIT(NL80211_STA_FLAG_MFP) | |
4411 | BIT(NL80211_STA_FLAG_AUTHORIZED); | 4411 | BIT(NL80211_STA_FLAG_AUTHORIZED); |
4412 | break; | ||
4412 | default: | 4413 | default: |
4413 | return -EINVAL; | 4414 | return -EINVAL; |
4414 | } | 4415 | } |
@@ -14923,20 +14924,24 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, | |||
14923 | EXPORT_SYMBOL(cfg80211_mgmt_tx_status); | 14924 | EXPORT_SYMBOL(cfg80211_mgmt_tx_status); |
14924 | 14925 | ||
14925 | static int __nl80211_rx_control_port(struct net_device *dev, | 14926 | static int __nl80211_rx_control_port(struct net_device *dev, |
14926 | const u8 *buf, size_t len, | 14927 | struct sk_buff *skb, |
14927 | const u8 *addr, u16 proto, | ||
14928 | bool unencrypted, gfp_t gfp) | 14928 | bool unencrypted, gfp_t gfp) |
14929 | { | 14929 | { |
14930 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 14930 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
14931 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 14931 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
14932 | struct ethhdr *ehdr = eth_hdr(skb); | ||
14933 | const u8 *addr = ehdr->h_source; | ||
14934 | u16 proto = be16_to_cpu(skb->protocol); | ||
14932 | struct sk_buff *msg; | 14935 | struct sk_buff *msg; |
14933 | void *hdr; | 14936 | void *hdr; |
14937 | struct nlattr *frame; | ||
14938 | |||
14934 | u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid); | 14939 | u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid); |
14935 | 14940 | ||
14936 | if (!nlportid) | 14941 | if (!nlportid) |
14937 | return -ENOENT; | 14942 | return -ENOENT; |
14938 | 14943 | ||
14939 | msg = nlmsg_new(100 + len, gfp); | 14944 | msg = nlmsg_new(100 + skb->len, gfp); |
14940 | if (!msg) | 14945 | if (!msg) |
14941 | return -ENOMEM; | 14946 | return -ENOMEM; |
14942 | 14947 | ||
@@ -14950,13 +14955,17 @@ static int __nl80211_rx_control_port(struct net_device *dev, | |||
14950 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 14955 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
14951 | nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev), | 14956 | nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev), |
14952 | NL80211_ATTR_PAD) || | 14957 | NL80211_ATTR_PAD) || |
14953 | nla_put(msg, NL80211_ATTR_FRAME, len, buf) || | ||
14954 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || | 14958 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || |
14955 | nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) || | 14959 | nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) || |
14956 | (unencrypted && nla_put_flag(msg, | 14960 | (unencrypted && nla_put_flag(msg, |
14957 | NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))) | 14961 | NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))) |
14958 | goto nla_put_failure; | 14962 | goto nla_put_failure; |
14959 | 14963 | ||
14964 | frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len); | ||
14965 | if (!frame) | ||
14966 | goto nla_put_failure; | ||
14967 | |||
14968 | skb_copy_bits(skb, 0, nla_data(frame), skb->len); | ||
14960 | genlmsg_end(msg, hdr); | 14969 | genlmsg_end(msg, hdr); |
14961 | 14970 | ||
14962 | return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); | 14971 | return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); |
@@ -14967,14 +14976,12 @@ static int __nl80211_rx_control_port(struct net_device *dev, | |||
14967 | } | 14976 | } |
14968 | 14977 | ||
14969 | bool cfg80211_rx_control_port(struct net_device *dev, | 14978 | bool cfg80211_rx_control_port(struct net_device *dev, |
14970 | const u8 *buf, size_t len, | 14979 | struct sk_buff *skb, bool unencrypted) |
14971 | const u8 *addr, u16 proto, bool unencrypted) | ||
14972 | { | 14980 | { |
14973 | int ret; | 14981 | int ret; |
14974 | 14982 | ||
14975 | trace_cfg80211_rx_control_port(dev, buf, len, addr, proto, unencrypted); | 14983 | trace_cfg80211_rx_control_port(dev, skb, unencrypted); |
14976 | ret = __nl80211_rx_control_port(dev, buf, len, addr, proto, | 14984 | ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC); |
14977 | unencrypted, GFP_ATOMIC); | ||
14978 | trace_cfg80211_return_bool(ret == 0); | 14985 | trace_cfg80211_return_bool(ret == 0); |
14979 | return ret == 0; | 14986 | return ret == 0; |
14980 | } | 14987 | } |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index bbe6298e4bb9..4fc66a117b7d 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -2240,7 +2240,9 @@ static void wiphy_update_regulatory(struct wiphy *wiphy, | |||
2240 | * as some drivers used this to restore its orig_* reg domain. | 2240 | * as some drivers used this to restore its orig_* reg domain. |
2241 | */ | 2241 | */ |
2242 | if (initiator == NL80211_REGDOM_SET_BY_CORE && | 2242 | if (initiator == NL80211_REGDOM_SET_BY_CORE && |
2243 | wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) | 2243 | wiphy->regulatory_flags & REGULATORY_CUSTOM_REG && |
2244 | !(wiphy->regulatory_flags & | ||
2245 | REGULATORY_WIPHY_SELF_MANAGED)) | ||
2244 | reg_call_notifier(wiphy, lr); | 2246 | reg_call_notifier(wiphy, lr); |
2245 | return; | 2247 | return; |
2246 | } | 2248 | } |
@@ -2787,26 +2789,6 @@ static void notify_self_managed_wiphys(struct regulatory_request *request) | |||
2787 | } | 2789 | } |
2788 | } | 2790 | } |
2789 | 2791 | ||
2790 | static bool reg_only_self_managed_wiphys(void) | ||
2791 | { | ||
2792 | struct cfg80211_registered_device *rdev; | ||
2793 | struct wiphy *wiphy; | ||
2794 | bool self_managed_found = false; | ||
2795 | |||
2796 | ASSERT_RTNL(); | ||
2797 | |||
2798 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | ||
2799 | wiphy = &rdev->wiphy; | ||
2800 | if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) | ||
2801 | self_managed_found = true; | ||
2802 | else | ||
2803 | return false; | ||
2804 | } | ||
2805 | |||
2806 | /* make sure at least one self-managed wiphy exists */ | ||
2807 | return self_managed_found; | ||
2808 | } | ||
2809 | |||
2810 | /* | 2792 | /* |
2811 | * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* | 2793 | * Processes regulatory hints, this is all the NL80211_REGDOM_SET_BY_* |
2812 | * Regulatory hints come on a first come first serve basis and we | 2794 | * Regulatory hints come on a first come first serve basis and we |
@@ -2839,10 +2821,6 @@ static void reg_process_pending_hints(void) | |||
2839 | spin_unlock(®_requests_lock); | 2821 | spin_unlock(®_requests_lock); |
2840 | 2822 | ||
2841 | notify_self_managed_wiphys(reg_request); | 2823 | notify_self_managed_wiphys(reg_request); |
2842 | if (reg_only_self_managed_wiphys()) { | ||
2843 | reg_free_request(reg_request); | ||
2844 | return; | ||
2845 | } | ||
2846 | 2824 | ||
2847 | reg_process_hint(reg_request); | 2825 | reg_process_hint(reg_request); |
2848 | 2826 | ||
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 2b417a2fe63f..7c73510b161f 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -2627,23 +2627,25 @@ TRACE_EVENT(cfg80211_mgmt_tx_status, | |||
2627 | ); | 2627 | ); |
2628 | 2628 | ||
2629 | TRACE_EVENT(cfg80211_rx_control_port, | 2629 | TRACE_EVENT(cfg80211_rx_control_port, |
2630 | TP_PROTO(struct net_device *netdev, const u8 *buf, size_t len, | 2630 | TP_PROTO(struct net_device *netdev, struct sk_buff *skb, |
2631 | const u8 *addr, u16 proto, bool unencrypted), | 2631 | bool unencrypted), |
2632 | TP_ARGS(netdev, buf, len, addr, proto, unencrypted), | 2632 | TP_ARGS(netdev, skb, unencrypted), |
2633 | TP_STRUCT__entry( | 2633 | TP_STRUCT__entry( |
2634 | NETDEV_ENTRY | 2634 | NETDEV_ENTRY |
2635 | MAC_ENTRY(addr) | 2635 | __field(int, len) |
2636 | MAC_ENTRY(from) | ||
2636 | __field(u16, proto) | 2637 | __field(u16, proto) |
2637 | __field(bool, unencrypted) | 2638 | __field(bool, unencrypted) |
2638 | ), | 2639 | ), |
2639 | TP_fast_assign( | 2640 | TP_fast_assign( |
2640 | NETDEV_ASSIGN; | 2641 | NETDEV_ASSIGN; |
2641 | MAC_ASSIGN(addr, addr); | 2642 | __entry->len = skb->len; |
2642 | __entry->proto = proto; | 2643 | MAC_ASSIGN(from, eth_hdr(skb)->h_source); |
2644 | __entry->proto = be16_to_cpu(skb->protocol); | ||
2643 | __entry->unencrypted = unencrypted; | 2645 | __entry->unencrypted = unencrypted; |
2644 | ), | 2646 | ), |
2645 | TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT " proto: 0x%x, unencrypted: %s", | 2647 | TP_printk(NETDEV_PR_FMT ", len=%d, " MAC_PR_FMT ", proto: 0x%x, unencrypted: %s", |
2646 | NETDEV_PR_ARG, MAC_PR_ARG(addr), | 2648 | NETDEV_PR_ARG, __entry->len, MAC_PR_ARG(from), |
2647 | __entry->proto, BOOL_TO_STR(__entry->unencrypted)) | 2649 | __entry->proto, BOOL_TO_STR(__entry->unencrypted)) |
2648 | ); | 2650 | ); |
2649 | 2651 | ||