aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-11-16 15:49:57 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-19 09:47:32 -0500
commit3475b0946bd2057497628790d4b4fce4bfdcc304 (patch)
tree182cdbcfffa95409a1a6973e28ba0fa41cdf4bb0
parent90b9e446fbb64630c72cab48c007d7081aec2533 (diff)
cfg80211: Add TDLS event to allow drivers to request operations
The NL80211_CMD_TDLS_OPER command was previously used only for userspace request for the kernel code to perform TDLS operations. However, there are also cases where the driver may need to request operations from userspace, e.g., when using security on the AP path. Add a new cfg80211 function for generating a TDLS operation event for drivers to request a new link to be set up (NL80211_TDLS_SETUP) or an existing link to be torn down (NL80211_TDLS_TEARDOWN). Drivers can optionally use these events, e.g., based on noticing data traffic being sent to a peer station that is seen with good signal strength. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h19
-rw-r--r--include/uapi/linux/nl80211.h6
-rw-r--r--net/wireless/nl80211.c47
-rw-r--r--net/wireless/trace.h23
4 files changed, 95 insertions, 0 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 81d725038f97..8a1aec54e68f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3594,6 +3594,25 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
3594 enum nl80211_channel_type type); 3594 enum nl80211_channel_type type);
3595 3595
3596/* 3596/*
3597 * cfg80211_tdls_oper_request - request userspace to perform TDLS operation
3598 * @dev: the device on which the operation is requested
3599 * @peer: the MAC address of the peer device
3600 * @oper: the requested TDLS operation (NL80211_TDLS_SETUP or
3601 * NL80211_TDLS_TEARDOWN)
3602 * @reason_code: the reason code for teardown request
3603 * @gfp: allocation flags
3604 *
3605 * This function is used to request userspace to perform TDLS operation that
3606 * requires knowledge of keys, i.e., link setup or teardown when the AP
3607 * connection uses encryption. This is optional mechanism for the driver to use
3608 * if it can automatically determine when a TDLS link could be useful (e.g.,
3609 * based on traffic and signal strength for a peer).
3610 */
3611void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
3612 enum nl80211_tdls_operation oper,
3613 u16 reason_code, gfp_t gfp);
3614
3615/*
3597 * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units) 3616 * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units)
3598 * @rate: given rate_info to calculate bitrate from 3617 * @rate: given rate_info to calculate bitrate from
3599 * 3618 *
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 06ddc89f026c..1a9a819cfab0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -526,6 +526,12 @@
526 * of PMKSA caching dandidates. 526 * of PMKSA caching dandidates.
527 * 527 *
528 * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup). 528 * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
529 * In addition, this can be used as an event to request userspace to take
530 * actions on TDLS links (set up a new link or tear down an existing one).
531 * In such events, %NL80211_ATTR_TDLS_OPERATION indicates the requested
532 * operation, %NL80211_ATTR_MAC contains the peer MAC address, and
533 * %NL80211_ATTR_REASON_CODE the reason code to be used (only with
534 * %NL80211_TDLS_TEARDOWN).
529 * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. 535 * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
530 * 536 *
531 * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP 537 * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c18b2fc9d492..4c427fa5c450 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9027,6 +9027,53 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
9027} 9027}
9028EXPORT_SYMBOL(cfg80211_report_obss_beacon); 9028EXPORT_SYMBOL(cfg80211_report_obss_beacon);
9029 9029
9030void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
9031 enum nl80211_tdls_operation oper,
9032 u16 reason_code, gfp_t gfp)
9033{
9034 struct wireless_dev *wdev = dev->ieee80211_ptr;
9035 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
9036 struct sk_buff *msg;
9037 void *hdr;
9038 int err;
9039
9040 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
9041 reason_code);
9042
9043 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9044 if (!msg)
9045 return;
9046
9047 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
9048 if (!hdr) {
9049 nlmsg_free(msg);
9050 return;
9051 }
9052
9053 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
9054 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
9055 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
9056 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
9057 (reason_code > 0 &&
9058 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
9059 goto nla_put_failure;
9060
9061 err = genlmsg_end(msg, hdr);
9062 if (err < 0) {
9063 nlmsg_free(msg);
9064 return;
9065 }
9066
9067 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
9068 nl80211_mlme_mcgrp.id, gfp);
9069 return;
9070
9071 nla_put_failure:
9072 genlmsg_cancel(msg, hdr);
9073 nlmsg_free(msg);
9074}
9075EXPORT_SYMBOL(cfg80211_tdls_oper_request);
9076
9030static int nl80211_netlink_notify(struct notifier_block * nb, 9077static int nl80211_netlink_notify(struct notifier_block * nb,
9031 unsigned long state, 9078 unsigned long state,
9032 void *_notify) 9079 void *_notify)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 8e03c6382a8a..f264c20a7090 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2157,6 +2157,29 @@ TRACE_EVENT(cfg80211_report_obss_beacon,
2157 WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm) 2157 WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm)
2158); 2158);
2159 2159
2160TRACE_EVENT(cfg80211_tdls_oper_request,
2161 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *peer,
2162 enum nl80211_tdls_operation oper, u16 reason_code),
2163 TP_ARGS(wiphy, netdev, peer, oper, reason_code),
2164 TP_STRUCT__entry(
2165 WIPHY_ENTRY
2166 NETDEV_ENTRY
2167 MAC_ENTRY(peer)
2168 __field(enum nl80211_tdls_operation, oper)
2169 __field(u16, reason_code)
2170 ),
2171 TP_fast_assign(
2172 WIPHY_ASSIGN;
2173 NETDEV_ASSIGN;
2174 MAC_ASSIGN(peer, peer);
2175 __entry->oper = oper;
2176 __entry->reason_code = reason_code;
2177 ),
2178 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", oper: %d, reason_code %u",
2179 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper,
2180 __entry->reason_code)
2181 );
2182
2160TRACE_EVENT(cfg80211_scan_done, 2183TRACE_EVENT(cfg80211_scan_done,
2161 TP_PROTO(struct cfg80211_scan_request *request, bool aborted), 2184 TP_PROTO(struct cfg80211_scan_request *request, bool aborted),
2162 TP_ARGS(request, aborted), 2185 TP_ARGS(request, aborted),