From: Denis Kenzior <denkenz@gmail.com>
To: linux-wireless@vger.kernel.org
Cc: Denis Kenzior <denkenz@gmail.com>
Subject: [RFC v5 2/9] nl80211: Implement TX of control port frames
Date: Tue, 13 Mar 2018 16:59:35 -0500 [thread overview]
Message-ID: <20180313215942.29176-3-denkenz@gmail.com> (raw)
In-Reply-To: <20180313215942.29176-1-denkenz@gmail.com>
This commit implements the TX side of NL80211_CMD_CONTROL_PORT_FRAME.
Userspace provides the raw EAPoL frame using NL80211_ATTR_FRAME.
Userspace should also provide the destination address and the protocol
type to use when sending the frame. This is used to implement TX of
Pre-authentication frames. If CONTROL_PORT_ETHERTYPE_NO_ENCRYPT is
specified, then the driver will be asked not to encrypt the outgoing
frame.
A new EXT_FEATURE flag is introduced so that nl80211 code can check
whether a given wiphy has capability to pass EAPoL frames over NL80211.
Signed-off-by: Denis Kenzior <denkenz@gmail.com>
---
include/net/cfg80211.h | 9 ++++++
include/uapi/linux/nl80211.h | 3 ++
net/wireless/nl80211.c | 70 +++++++++++++++++++++++++++++++++++++++++++-
net/wireless/rdev-ops.h | 15 ++++++++++
net/wireless/trace.h | 26 ++++++++++++++++
5 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6dee630ee66d..76b6783f35f6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2960,6 +2960,9 @@ struct cfg80211_external_auth_params {
*
* @external_auth: indicates result of offloaded authentication processing from
* user space
+ *
+ * @tx_control_port: TX a control port frame (EAPoL). The noencrypt parameter
+ * tells the driver that the frame should not be encrypted.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3255,6 +3258,12 @@ struct cfg80211_ops {
const u8 *aa);
int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_external_auth_params *params);
+
+ int (*tx_control_port)(struct wiphy *wiphy,
+ struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *dest, const __be16 proto,
+ const bool noencrypt);
};
/*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1334f810f7b4..77675ae3e475 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -5012,6 +5012,8 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
* @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
* @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211: Driver supports sending and
+ * receiving control port frames over NL80211 instead of the netdevice.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5042,6 +5044,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
NL80211_EXT_FEATURE_LOW_POWER_SCAN,
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
+ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d7dcc2d05025..3c4dbfa0ca71 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12517,6 +12517,67 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
return rdev_external_auth(rdev, dev, ¶ms);
}
+static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ const u8 *buf;
+ size_t len;
+ u8 *dest;
+ u16 proto;
+ bool noencrypt;
+ int err;
+
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
+ return -EOPNOTSUPP;
+
+ if (!rdev->ops->tx_control_port)
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_FRAME] ||
+ !info->attrs[NL80211_ATTR_MAC] ||
+ !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE])
+ return -EINVAL;
+
+ wdev_lock(wdev);
+
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_P2P_GO:
+ case NL80211_IFTYPE_MESH_POINT:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ if (wdev->current_bss)
+ break;
+ err = -ENOTCONN;
+ goto out;
+ default:
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ wdev_unlock(wdev);
+
+ buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+ len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+ dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
+ noencrypt =
+ nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
+
+ return rdev_tx_control_port(rdev, dev, buf, len,
+ dest, cpu_to_be16(proto), noencrypt);
+
+ out:
+ wdev_unlock(wdev);
+ return err;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -13420,7 +13481,14 @@ static const struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
-
+ {
+ .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
+ .doit = nl80211_tx_control_port,
+ .policy = nl80211_policy,
+ .flags = GENL_UNS_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_family nl80211_fam __ro_after_init = {
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 84f23ae015fc..87479a53411b 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -714,6 +714,21 @@ static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
return ret;
}
+static inline int rdev_tx_control_port(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ const void *buf, size_t len,
+ const u8 *dest, __be16 proto,
+ const bool noencrypt)
+{
+ int ret;
+ trace_rdev_tx_control_port(&rdev->wiphy, dev, buf, len,
+ dest, proto, noencrypt);
+ ret = rdev->ops->tx_control_port(&rdev->wiphy, dev, buf, len,
+ dest, proto, noencrypt);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
static inline int
rdev_mgmt_tx_cancel_wait(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, u64 cookie)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 24e84dfe54fd..5794cfa371c7 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1882,6 +1882,32 @@ TRACE_EVENT(rdev_mgmt_tx,
BOOL_TO_STR(__entry->dont_wait_for_ack))
);
+TRACE_EVENT(rdev_tx_control_port,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ const u8 *buf, size_t len, const u8 *dest, __be16 proto,
+ bool unencrypted),
+ TP_ARGS(wiphy, netdev, buf, len, dest, proto, unencrypted),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(dest)
+ __field(__be16, proto)
+ __field(bool, unencrypted)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(dest, dest);
+ __entry->proto = proto;
+ __entry->unencrypted = unencrypted;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ","
+ " proto: %x, unencrypted: %s",
+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dest),
+ be16_to_cpu(__entry->proto),
+ BOOL_TO_STR(__entry->unencrypted))
+);
+
TRACE_EVENT(rdev_set_noack_map,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
u16 noack_map),
--
2.13.5
next prev parent reply other threads:[~2018-03-13 21:59 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-13 21:59 [RFC v5 0/9] EAPoL over NL80211 Denis Kenzior
2018-03-13 21:59 ` [RFC v5 1/9] nl80211: Add CMD_CONTROL_PORT_FRAME API Denis Kenzior
2018-03-13 21:59 ` Denis Kenzior [this message]
2018-03-13 21:59 ` [RFC v5 3/9] nl80211: Add CONTROL_PORT_OVER_NL80211 attribute Denis Kenzior
2018-03-21 7:47 ` Johannes Berg
2018-03-21 15:01 ` Denis Kenzior
2018-03-21 15:09 ` Johannes Berg
2018-03-13 21:59 ` [RFC v5 4/9] cfg80211: Support all iftypes in autodisconnect_wk Denis Kenzior
2018-03-21 7:46 ` Johannes Berg
2018-03-21 15:27 ` Denis Kenzior
2018-03-21 15:40 ` Johannes Berg
2018-03-13 21:59 ` [RFC v5 5/9] nl80211: Add SOCKET_OWNER support to JOIN_IBSS Denis Kenzior
2018-03-13 21:59 ` [RFC v5 6/9] nl80211: Add SOCKET_OWNER support to JOIN_MESH Denis Kenzior
2018-03-13 21:59 ` [RFC v5 7/9] nl80211: Add SOCKET_OWNER support to START_AP Denis Kenzior
2018-03-13 21:59 ` [RFC v5 8/9] mac80211: Add support for tx_control_port Denis Kenzior
2018-03-13 21:59 ` [RFC v5 9/9] mac80211: Send control port frames over nl80211 Denis Kenzior
2018-03-21 15:13 ` [RFC v5 0/9] EAPoL over NL80211 Johannes Berg
2018-03-21 15:18 ` Denis Kenzior
2018-03-22 10:28 ` Johannes Berg
2018-03-22 13:54 ` Denis Kenzior
2018-03-23 8:04 ` Johannes Berg
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=20180313215942.29176-3-denkenz@gmail.com \
--to=denkenz@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.