From: Johannes Berg <johannes@sipsolutions.net>
To: linux-wireless@vger.kernel.org
Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Subject: [PATCH] mac80211: implement critical protocol protection
Date: Fri, 26 Jul 2013 10:08:10 +0200 [thread overview]
Message-ID: <1374826090-17322-1-git-send-email-johannes@sipsolutions.net> (raw)
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This new API add in cfg80211 wasn't implemented in mac80211.
Advertise the capabilities based on the device's
implementation (possibly NULL) of crit_prot mac80211 ops.
This callback will be called by cfg80211 when hinted by
userspace that a critical protocol is happening, e.g. it can
be EAPOL, DHCP.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/cfg80211.h | 2 ++
include/net/mac80211.h | 7 +++++++
net/mac80211/cfg.c | 29 +++++++++++++++++++++++++++++
net/mac80211/driver-ops.h | 18 ++++++++++++++++++
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/iface.c | 14 ++++++++++++++
net/mac80211/main.c | 3 +++
net/mac80211/trace.h | 26 ++++++++++++++++++++++++++
net/wireless/nl80211.c | 6 ++++--
9 files changed, 104 insertions(+), 2 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 019e256..5dc5e75 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2452,6 +2452,7 @@ struct cfg80211_ops {
* @WIPHY_FLAG_SUPPORTS_BEACON_MEAS: Device supports beacon measurements. Should
* be set when the device can let all the beacon through up to cfg80211
* to proceed to measurements (i.e. RSSI measurements).
+ * @WIPHY_FLAG_SUPPORTS_CRIT_PROT: Device supports critical protocol protection.
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -2477,6 +2478,7 @@ enum wiphy_flags {
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22),
WIPHY_FLAG_SUPPORTS_BEACON_MEAS = BIT(23),
+ WIPHY_FLAG_SUPPORTS_CRIT_PROT = BIT(24),
};
/**
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index fb8f6c6..70d8ea4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2638,6 +2638,10 @@ enum ieee80211_roc_type {
* beacons must be let through and data for measurement should be set in
* &ieee80211_rx_status (rssi etc...).
*
+ * @crit_proto: Start or stop a critical protocol session. This can be DHCP, EAP
+ * or any other protocol that gates the connection. Look at
+ * %crit_prot_start in %cfg80211_ops.
+ *
* @ipv6_addr_change: IPv6 address assignment on the given interface changed.
* Currently, this is only called for managed or P2P client interfaces.
* This callback is optional; it must not sleep.
@@ -2826,6 +2830,9 @@ struct ieee80211_ops {
int (*beacon_measurement)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, bool state);
+ int (*crit_proto)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ enum nl80211_crit_proto_id protocol, bool start);
+
#if IS_ENABLED(CONFIG_IPV6)
void (*ipv6_addr_change)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 34b57a9..3070d5e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3407,6 +3407,33 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
return ret;
}
+static int ieee80211_crit_proto_start(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ enum nl80211_crit_proto_id protocol,
+ u16 duration)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+ int ret;
+
+ ret = drv_crit_proto(local, sdata, protocol, true);
+ if (!ret)
+ return ret;
+
+ ieee80211_queue_delayed_work(&sdata->local->hw,
+ &sdata->crit_prot_end_wk,
+ msecs_to_jiffies(duration));
+ return 0;
+}
+
+static void ieee80211_crit_proto_stop(struct wiphy *wiphy,
+ struct wireless_dev *wdev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+
+ flush_delayed_work(&sdata->crit_prot_end_wk);
+}
+
static int ieee80211_beacon_measurement(struct wiphy *wiphy,
struct wireless_dev *wdev,
bool state)
@@ -3505,5 +3532,7 @@ struct cfg80211_ops mac80211_config_ops = {
.get_et_strings = ieee80211_get_et_strings,
.get_channel = ieee80211_cfg_get_channel,
.start_radar_detection = ieee80211_start_radar_detection,
+ .crit_proto_start = ieee80211_crit_proto_start,
+ .crit_proto_stop = ieee80211_crit_proto_stop,
.beacon_measurement = ieee80211_beacon_measurement,
};
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 7fbe57f..30a773b 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1060,6 +1060,24 @@ drv_set_default_unicast_key(struct ieee80211_local *local,
trace_drv_return_void(local);
}
+static inline int drv_crit_proto(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ enum nl80211_crit_proto_id protocol,
+ bool start)
+{
+ int ret = -EOPNOTSUPP;
+ check_sdata_in_driver(sdata);
+
+ trace_drv_crit_proto(local, sdata, protocol, start);
+
+ if (local->ops->crit_proto)
+ ret = local->ops->crit_proto(&local->hw, &sdata->vif, protocol,
+ start);
+ trace_drv_return_int(local, ret);
+
+ return ret;
+}
+
static inline int
drv_beacon_measurement(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, bool state)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3d32df1..b04c62f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -683,6 +683,7 @@ struct ieee80211_sub_if_data {
int crypto_tx_tailroom_needed_cnt;
int crypto_tx_tailroom_pending_dec;
struct delayed_work dec_tailroom_needed_wk;
+ struct delayed_work crit_prot_end_wk;
struct net_device *dev;
struct ieee80211_local *local;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 4c41c11..700c937 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -806,6 +806,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
cancel_work_sync(&sdata->recalc_smps);
cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
+ /* this will end the critical protocol right away */
+ flush_delayed_work(&sdata->crit_prot_end_wk);
if (sdata->wdev.cac_started) {
WARN_ON(local->suspended);
@@ -1568,6 +1570,16 @@ static void ieee80211_cleanup_sdata_stas_wk(struct work_struct *wk)
ieee80211_cleanup_sdata_stas(sdata);
}
+static void ieee80211_crit_prot_timeout(struct work_struct *wk)
+{
+ struct ieee80211_sub_if_data *sdata;
+
+ sdata = container_of(wk, struct ieee80211_sub_if_data,
+ crit_prot_end_wk.work);
+
+ drv_crit_proto(sdata->local, sdata, NL80211_CRIT_PROTO_UNSPEC, false);
+}
+
int ieee80211_if_add(struct ieee80211_local *local, const char *name,
struct wireless_dev **new_wdev, enum nl80211_iftype type,
struct vif_params *params)
@@ -1647,6 +1659,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
ieee80211_dfs_cac_timer_work);
INIT_DELAYED_WORK(&sdata->dec_tailroom_needed_wk,
ieee80211_delayed_tailroom_dec);
+ INIT_DELAYED_WORK(&sdata->crit_prot_end_wk,
+ ieee80211_crit_prot_timeout);
for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
struct ieee80211_supported_band *sband;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 25eb35b..c3084e4 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -895,6 +895,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (local->ops->sched_scan_start)
local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+ if (local->ops->crit_proto)
+ local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_CRIT_PROT;
+
/* mac80211 based drivers don't support internal TDLS setup */
if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)
local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index d41bbe2..1e8eaaa 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1887,6 +1887,32 @@ TRACE_EVENT(drv_set_default_unicast_key,
LOCAL_PR_ARG, VIF_PR_ARG, __entry->key_idx)
);
+TRACE_EVENT(drv_crit_proto,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ enum nl80211_crit_proto_id protocol,
+ bool start),
+
+ TP_ARGS(local, sdata, protocol, start),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ __field(unsigned int, protocol)
+ __field(bool, start)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ __entry->protocol = protocol;
+ __entry->start = start;
+ ),
+
+ TP_printk(LOCAL_PR_FMT VIF_PR_FMT " protocol:%d start:%d",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->protocol, __entry->start)
+);
+
TRACE_EVENT(drv_beacon_measurement,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c2b43b6..e39c43d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1421,8 +1421,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
CMD(start_p2p_device, START_P2P_DEVICE);
CMD(set_mcast_rate, SET_MCAST_RATE);
if (state->split) {
- CMD(crit_proto_start, CRIT_PROTOCOL_START);
- CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
+ if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_CRIT_PROT) {
+ CMD(crit_proto_start, CRIT_PROTOCOL_START);
+ CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
+ }
}
#ifdef CONFIG_NL80211_TESTMODE
--
1.8.0
next reply other threads:[~2013-07-26 8:08 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-26 8:08 Johannes Berg [this message]
2013-07-30 18:36 ` [PATCH] mac80211: implement critical protocol protection Eliad Peller
2013-07-30 19:14 ` Grumbach, Emmanuel
2013-07-31 19:59 ` Arik Nemtsov
2013-08-01 6:07 ` Emmanuel Grumbach
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1374826090-17322-1-git-send-email-johannes@sipsolutions.net \
--to=johannes@sipsolutions.net \
--cc=emmanuel.grumbach@intel.com \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox