aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2013-02-27 10:14:27 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-03-06 10:35:51 -0500
commit355199e02b831fd4f652c34d6c7673d973da1369 (patch)
treebd4bfa7f90b431aa87342dd008d6dcc0f7d3e825
parent723d568aa585028a145c79a744dba2e018815873 (diff)
cfg80211: Extend support for IEEE 802.11r Fast BSS Transition
Add NL80211_CMD_UPDATE_FT_IES to support update of FT IEs to the WLAN driver and NL80211_CMD_FT_EVENT to send FT events from the WLAN driver. This will carry the target AP's MAC address along with the relevant Information Elements. This event is used to report received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE). These changes allow FT to be supported with drivers that use an internal SME instead of user space option (like FT implementation in wpa_supplicant with mac80211-based drivers). Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h41
-rw-r--r--include/uapi/linux/nl80211.h19
-rw-r--r--net/wireless/nl80211.c76
-rw-r--r--net/wireless/rdev-ops.h13
-rw-r--r--net/wireless/trace.h46
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 */
1774struct 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);
4045void cfg80211_unregister_wdev(struct wireless_dev *wdev); 4062void 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 */
4072struct 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 */
4085void 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
8166static 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
8846static struct genl_multicast_group nl80211_mlme_mcgrp = { 8878static 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
10577void 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}
10619EXPORT_SYMBOL(cfg80211_ft_event);
10620
10545/* initialisation/exit functions */ 10621/* initialisation/exit functions */
10546 10622
10547int nl80211_init(void) 10623int 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
891static 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
1788TRACE_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
2436TRACE_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