diff options
-rw-r--r-- | include/net/cfg80211.h | 41 | ||||
-rw-r--r-- | include/uapi/linux/nl80211.h | 19 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 76 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 13 | ||||
-rw-r--r-- | net/wireless/trace.h | 46 |
5 files changed, 195 insertions, 0 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 73a523901c73..dfef0d5b5d3d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1763,6 +1763,21 @@ struct cfg80211_gtk_rekey_data { | |||
1763 | }; | 1763 | }; |
1764 | 1764 | ||
1765 | /** | 1765 | /** |
1766 | * struct cfg80211_update_ft_ies_params - FT IE Information | ||
1767 | * | ||
1768 | * This structure provides information needed to update the fast transition IE | ||
1769 | * | ||
1770 | * @md: The Mobility Domain ID, 2 Octet value | ||
1771 | * @ie: Fast Transition IEs | ||
1772 | * @ie_len: Length of ft_ie in octets | ||
1773 | */ | ||
1774 | struct cfg80211_update_ft_ies_params { | ||
1775 | u16 md; | ||
1776 | const u8 *ie; | ||
1777 | size_t ie_len; | ||
1778 | }; | ||
1779 | |||
1780 | /** | ||
1766 | * struct cfg80211_ops - backend description for wireless configuration | 1781 | * struct cfg80211_ops - backend description for wireless configuration |
1767 | * | 1782 | * |
1768 | * This struct is registered by fullmac card drivers and/or wireless stacks | 1783 | * This struct is registered by fullmac card drivers and/or wireless stacks |
@@ -2208,6 +2223,8 @@ struct cfg80211_ops { | |||
2208 | int (*start_radar_detection)(struct wiphy *wiphy, | 2223 | int (*start_radar_detection)(struct wiphy *wiphy, |
2209 | struct net_device *dev, | 2224 | struct net_device *dev, |
2210 | struct cfg80211_chan_def *chandef); | 2225 | struct cfg80211_chan_def *chandef); |
2226 | int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev, | ||
2227 | struct cfg80211_update_ft_ies_params *ftie); | ||
2211 | }; | 2228 | }; |
2212 | 2229 | ||
2213 | /* | 2230 | /* |
@@ -4045,6 +4062,30 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate); | |||
4045 | void cfg80211_unregister_wdev(struct wireless_dev *wdev); | 4062 | void cfg80211_unregister_wdev(struct wireless_dev *wdev); |
4046 | 4063 | ||
4047 | /** | 4064 | /** |
4065 | * struct cfg80211_ft_event - FT Information Elements | ||
4066 | * @ies: FT IEs | ||
4067 | * @ies_len: length of the FT IE in bytes | ||
4068 | * @target_ap: target AP's MAC address | ||
4069 | * @ric_ies: RIC IE | ||
4070 | * @ric_ies_len: length of the RIC IE in bytes | ||
4071 | */ | ||
4072 | struct cfg80211_ft_event_params { | ||
4073 | const u8 *ies; | ||
4074 | size_t ies_len; | ||
4075 | const u8 *target_ap; | ||
4076 | const u8 *ric_ies; | ||
4077 | size_t ric_ies_len; | ||
4078 | }; | ||
4079 | |||
4080 | /** | ||
4081 | * cfg80211_ft_event - notify userspace about FT IE and RIC IE | ||
4082 | * @netdev: network device | ||
4083 | * @ft_event: IE information | ||
4084 | */ | ||
4085 | void cfg80211_ft_event(struct net_device *netdev, | ||
4086 | struct cfg80211_ft_event_params *ft_event); | ||
4087 | |||
4088 | /** | ||
4048 | * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer | 4089 | * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer |
4049 | * @ies: the input IE buffer | 4090 | * @ies: the input IE buffer |
4050 | * @len: the input length | 4091 | * @len: the input length |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 2c3e88360037..2d0cff57ff89 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -629,6 +629,14 @@ | |||
629 | * i.e. features for the nl80211 protocol rather than device features. | 629 | * i.e. features for the nl80211 protocol rather than device features. |
630 | * Returns the features in the %NL80211_ATTR_PROTOCOL_FEATURES bitmap. | 630 | * Returns the features in the %NL80211_ATTR_PROTOCOL_FEATURES bitmap. |
631 | * | 631 | * |
632 | * @NL80211_CMD_UPDATE_FT_IES: Pass down the most up-to-date Fast Transition | ||
633 | * Information Element to the WLAN driver | ||
634 | * | ||
635 | * @NL80211_CMD_FT_EVENT: Send a Fast transition event from the WLAN driver | ||
636 | * to the supplicant. This will carry the target AP's MAC address along | ||
637 | * with the relevant Information Elements. This event is used to report | ||
638 | * received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE). | ||
639 | * | ||
632 | * @NL80211_CMD_MAX: highest used command number | 640 | * @NL80211_CMD_MAX: highest used command number |
633 | * @__NL80211_CMD_AFTER_LAST: internal use | 641 | * @__NL80211_CMD_AFTER_LAST: internal use |
634 | */ | 642 | */ |
@@ -785,6 +793,9 @@ enum nl80211_commands { | |||
785 | 793 | ||
786 | NL80211_CMD_GET_PROTOCOL_FEATURES, | 794 | NL80211_CMD_GET_PROTOCOL_FEATURES, |
787 | 795 | ||
796 | NL80211_CMD_UPDATE_FT_IES, | ||
797 | NL80211_CMD_FT_EVENT, | ||
798 | |||
788 | /* add new commands above here */ | 799 | /* add new commands above here */ |
789 | 800 | ||
790 | /* used to define NL80211_CMD_MAX below */ | 801 | /* used to define NL80211_CMD_MAX below */ |
@@ -1396,6 +1407,11 @@ enum nl80211_commands { | |||
1396 | * receiving the data for a single wiphy split across multiple | 1407 | * receiving the data for a single wiphy split across multiple |
1397 | * messages, given with wiphy dump message | 1408 | * messages, given with wiphy dump message |
1398 | * | 1409 | * |
1410 | * @NL80211_ATTR_MDID: Mobility Domain Identifier | ||
1411 | * | ||
1412 | * @NL80211_ATTR_IE_RIC: Resource Information Container Information | ||
1413 | * Element | ||
1414 | * | ||
1399 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1415 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1400 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1416 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1401 | */ | 1417 | */ |
@@ -1688,6 +1704,9 @@ enum nl80211_attrs { | |||
1688 | NL80211_ATTR_DISABLE_VHT, | 1704 | NL80211_ATTR_DISABLE_VHT, |
1689 | NL80211_ATTR_VHT_CAPABILITY_MASK, | 1705 | NL80211_ATTR_VHT_CAPABILITY_MASK, |
1690 | 1706 | ||
1707 | NL80211_ATTR_MDID, | ||
1708 | NL80211_ATTR_IE_RIC, | ||
1709 | |||
1691 | /* add attributes here, update the policy in nl80211.c */ | 1710 | /* add attributes here, update the policy in nl80211.c */ |
1692 | 1711 | ||
1693 | __NL80211_ATTR_AFTER_LAST, | 1712 | __NL80211_ATTR_AFTER_LAST, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a8bd453d22b9..08de0c6035f1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -375,6 +375,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
375 | [NL80211_ATTR_VHT_CAPABILITY_MASK] = { | 375 | [NL80211_ATTR_VHT_CAPABILITY_MASK] = { |
376 | .len = NL80211_VHT_CAPABILITY_LEN, | 376 | .len = NL80211_VHT_CAPABILITY_LEN, |
377 | }, | 377 | }, |
378 | [NL80211_ATTR_MDID] = { .type = NLA_U16 }, | ||
379 | [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, | ||
380 | .len = IEEE80211_MAX_DATA_LEN }, | ||
378 | }; | 381 | }; |
379 | 382 | ||
380 | /* policy for the key attributes */ | 383 | /* policy for the key attributes */ |
@@ -8160,6 +8163,27 @@ static int nl80211_get_protocol_features(struct sk_buff *skb, | |||
8160 | return -ENOBUFS; | 8163 | return -ENOBUFS; |
8161 | } | 8164 | } |
8162 | 8165 | ||
8166 | static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info) | ||
8167 | { | ||
8168 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
8169 | struct cfg80211_update_ft_ies_params ft_params; | ||
8170 | struct net_device *dev = info->user_ptr[1]; | ||
8171 | |||
8172 | if (!rdev->ops->update_ft_ies) | ||
8173 | return -EOPNOTSUPP; | ||
8174 | |||
8175 | if (!info->attrs[NL80211_ATTR_MDID] || | ||
8176 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | ||
8177 | return -EINVAL; | ||
8178 | |||
8179 | memset(&ft_params, 0, sizeof(ft_params)); | ||
8180 | ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]); | ||
8181 | ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]); | ||
8182 | ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | ||
8183 | |||
8184 | return rdev_update_ft_ies(rdev, dev, &ft_params); | ||
8185 | } | ||
8186 | |||
8163 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 8187 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
8164 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 8188 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
8165 | #define NL80211_FLAG_NEED_RTNL 0x04 | 8189 | #define NL80211_FLAG_NEED_RTNL 0x04 |
@@ -8841,6 +8865,14 @@ static struct genl_ops nl80211_ops[] = { | |||
8841 | .doit = nl80211_get_protocol_features, | 8865 | .doit = nl80211_get_protocol_features, |
8842 | .policy = nl80211_policy, | 8866 | .policy = nl80211_policy, |
8843 | }, | 8867 | }, |
8868 | { | ||
8869 | .cmd = NL80211_CMD_UPDATE_FT_IES, | ||
8870 | .doit = nl80211_update_ft_ies, | ||
8871 | .policy = nl80211_policy, | ||
8872 | .flags = GENL_ADMIN_PERM, | ||
8873 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
8874 | NL80211_FLAG_NEED_RTNL, | ||
8875 | }, | ||
8844 | }; | 8876 | }; |
8845 | 8877 | ||
8846 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 8878 | static struct genl_multicast_group nl80211_mlme_mcgrp = { |
@@ -10542,6 +10574,50 @@ static struct notifier_block nl80211_netlink_notifier = { | |||
10542 | .notifier_call = nl80211_netlink_notify, | 10574 | .notifier_call = nl80211_netlink_notify, |
10543 | }; | 10575 | }; |
10544 | 10576 | ||
10577 | void cfg80211_ft_event(struct net_device *netdev, | ||
10578 | struct cfg80211_ft_event_params *ft_event) | ||
10579 | { | ||
10580 | struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy; | ||
10581 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
10582 | struct sk_buff *msg; | ||
10583 | void *hdr; | ||
10584 | int err; | ||
10585 | |||
10586 | trace_cfg80211_ft_event(wiphy, netdev, ft_event); | ||
10587 | |||
10588 | if (!ft_event->target_ap) | ||
10589 | return; | ||
10590 | |||
10591 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
10592 | if (!msg) | ||
10593 | return; | ||
10594 | |||
10595 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT); | ||
10596 | if (!hdr) { | ||
10597 | nlmsg_free(msg); | ||
10598 | return; | ||
10599 | } | ||
10600 | |||
10601 | nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
10602 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | ||
10603 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap); | ||
10604 | if (ft_event->ies) | ||
10605 | nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies); | ||
10606 | if (ft_event->ric_ies) | ||
10607 | nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, | ||
10608 | ft_event->ric_ies); | ||
10609 | |||
10610 | err = genlmsg_end(msg, hdr); | ||
10611 | if (err < 0) { | ||
10612 | nlmsg_free(msg); | ||
10613 | return; | ||
10614 | } | ||
10615 | |||
10616 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
10617 | nl80211_mlme_mcgrp.id, GFP_KERNEL); | ||
10618 | } | ||
10619 | EXPORT_SYMBOL(cfg80211_ft_event); | ||
10620 | |||
10545 | /* initialisation/exit functions */ | 10621 | /* initialisation/exit functions */ |
10546 | 10622 | ||
10547 | int nl80211_init(void) | 10623 | int nl80211_init(void) |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 422d38291d66..8c8b26f574e8 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -887,4 +887,17 @@ static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev, | |||
887 | trace_rdev_return_int(&rdev->wiphy, ret); | 887 | trace_rdev_return_int(&rdev->wiphy, ret); |
888 | return ret; | 888 | return ret; |
889 | } | 889 | } |
890 | |||
891 | static inline int rdev_update_ft_ies(struct cfg80211_registered_device *rdev, | ||
892 | struct net_device *dev, | ||
893 | struct cfg80211_update_ft_ies_params *ftie) | ||
894 | { | ||
895 | int ret; | ||
896 | |||
897 | trace_rdev_update_ft_ies(&rdev->wiphy, dev, ftie); | ||
898 | ret = rdev->ops->update_ft_ies(&rdev->wiphy, dev, ftie); | ||
899 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
900 | return ret; | ||
901 | } | ||
902 | |||
890 | #endif /* __CFG80211_RDEV_OPS */ | 903 | #endif /* __CFG80211_RDEV_OPS */ |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index b7a531380e19..ccadef2106ac 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1785,6 +1785,26 @@ TRACE_EVENT(rdev_set_mac_acl, | |||
1785 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->acl_policy) | 1785 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->acl_policy) |
1786 | ); | 1786 | ); |
1787 | 1787 | ||
1788 | TRACE_EVENT(rdev_update_ft_ies, | ||
1789 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1790 | struct cfg80211_update_ft_ies_params *ftie), | ||
1791 | TP_ARGS(wiphy, netdev, ftie), | ||
1792 | TP_STRUCT__entry( | ||
1793 | WIPHY_ENTRY | ||
1794 | NETDEV_ENTRY | ||
1795 | __field(u16, md) | ||
1796 | __dynamic_array(u8, ie, ftie->ie_len) | ||
1797 | ), | ||
1798 | TP_fast_assign( | ||
1799 | WIPHY_ASSIGN; | ||
1800 | NETDEV_ASSIGN; | ||
1801 | __entry->md = ftie->md; | ||
1802 | memcpy(__get_dynamic_array(ie), ftie->ie, ftie->ie_len); | ||
1803 | ), | ||
1804 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", md: 0x%x", | ||
1805 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->md) | ||
1806 | ); | ||
1807 | |||
1788 | /************************************************************* | 1808 | /************************************************************* |
1789 | * cfg80211 exported functions traces * | 1809 | * cfg80211 exported functions traces * |
1790 | *************************************************************/ | 1810 | *************************************************************/ |
@@ -2413,6 +2433,32 @@ TRACE_EVENT(cfg80211_report_wowlan_wakeup, | |||
2413 | TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) | 2433 | TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) |
2414 | ); | 2434 | ); |
2415 | 2435 | ||
2436 | TRACE_EVENT(cfg80211_ft_event, | ||
2437 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
2438 | struct cfg80211_ft_event_params *ft_event), | ||
2439 | TP_ARGS(wiphy, netdev, ft_event), | ||
2440 | TP_STRUCT__entry( | ||
2441 | WIPHY_ENTRY | ||
2442 | NETDEV_ENTRY | ||
2443 | __dynamic_array(u8, ies, ft_event->ies_len) | ||
2444 | MAC_ENTRY(target_ap) | ||
2445 | __dynamic_array(u8, ric_ies, ft_event->ric_ies_len) | ||
2446 | ), | ||
2447 | TP_fast_assign( | ||
2448 | WIPHY_ASSIGN; | ||
2449 | NETDEV_ASSIGN; | ||
2450 | if (ft_event->ies) | ||
2451 | memcpy(__get_dynamic_array(ies), ft_event->ies, | ||
2452 | ft_event->ies_len); | ||
2453 | MAC_ASSIGN(target_ap, ft_event->target_ap); | ||
2454 | if (ft_event->ric_ies) | ||
2455 | memcpy(__get_dynamic_array(ric_ies), ft_event->ric_ies, | ||
2456 | ft_event->ric_ies_len); | ||
2457 | ), | ||
2458 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", target_ap: " MAC_PR_FMT, | ||
2459 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) | ||
2460 | ); | ||
2461 | |||
2416 | #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ | 2462 | #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ |
2417 | 2463 | ||
2418 | #undef TRACE_INCLUDE_PATH | 2464 | #undef TRACE_INCLUDE_PATH |