@@ -1258,6 +1258,11 @@ struct survey_info {
* port frames over NL80211 instead of the network interface.
* @control_port_no_preauth: disables pre-auth rx over the nl80211 control
* port for mac80211
+ * @control_port_vlan_id: if set (nonzero) userspace expect to receive also
+ * 8021Q tagged control port protocol frames. Verification of VLAN id
+ * should be done in lower layer. Also 8021Q header should be stripped.
+ * For tx path userspace expect lower layer will add proper 8021Q header
+ * and setup VLAN id.
* @psk: PSK (for devices supporting 4-way-handshake offload)
* @sae_pwd: password for SAE authentication (for devices supporting SAE
* offload)
@@ -1290,6 +1295,7 @@ struct cfg80211_crypto_settings {
bool control_port_no_encrypt;
bool control_port_over_nl80211;
bool control_port_no_preauth;
+ u16 control_port_vlan_id;
const u8 *psk;
const u8 *sae_pwd;
u8 sae_pwd_len;
@@ -4963,7 +4969,7 @@ struct cfg80211_ops {
const u8 *buf, size_t len,
const u8 *dest, const __be16 proto,
const bool noencrypt, int link_id,
- u64 *cookie);
+ u64 *cookie, u16 vlan_id);
int (*get_ftm_responder_stats)(struct wiphy *wiphy,
struct net_device *dev,
@@ -2670,7 +2670,8 @@ enum nl80211_commands {
* Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13.
*
* @NL80211_ATTR_VLAN_ID: VLAN ID (1..4094) for the station and VLAN group key
- * (u16).
+ * (u16). For %NL80211_ATTR_CONTROL_PORT_OVER_NL80211 allow to receive
+ * and send tagged (8021Q) control port packets.
*
* @NL80211_ATTR_HE_BSS_COLOR: nested attribute for BSS Color Settings.
*
@@ -2105,7 +2105,7 @@ void ieee80211_clear_fast_xmit(struct sta_info *sta);
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len,
const u8 *dest, __be16 proto, bool unencrypted,
- int link_id, u64 *cookie);
+ int link_id, u64 *cookie, u16 vlan_id);
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len);
void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
@@ -6139,7 +6139,7 @@ void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len,
const u8 *dest, __be16 proto, bool unencrypted,
- int link_id, u64 *cookie)
+ int link_id, u64 *cookie, u16 vlan_id)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
@@ -11009,6 +11009,10 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH])
settings->control_port_no_preauth = true;
+
+ if (info->attrs[NL80211_ATTR_VLAN_ID])
+ settings->control_port_vlan_id =
+ nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
}
if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
@@ -15790,6 +15794,7 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
u8 *dest;
u16 proto;
bool noencrypt;
+ u16 vlan_id = 0;
u64 cookie = 0;
int link_id;
int err;
@@ -15835,9 +15840,12 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
link_id = nl80211_link_id_or_invalid(info->attrs);
+ if (info->attrs[NL80211_ATTR_VLAN_ID])
+ vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
+
err = rdev_tx_control_port(rdev, dev, buf, len,
dest, cpu_to_be16(proto), noencrypt, link_id,
- dont_wait_for_ack ? NULL : &cookie);
+ dont_wait_for_ack ? NULL : &cookie, vlan_id);
if (!err && !dont_wait_for_ack)
nl_set_extack_cookie_u64(info->extack, cookie);
return err;
@@ -769,13 +769,14 @@ static inline int rdev_tx_control_port(struct cfg80211_registered_device *rdev,
const void *buf, size_t len,
const u8 *dest, __be16 proto,
const bool noencrypt, int link,
- u64 *cookie)
+ u64 *cookie, u16 vlan_id)
{
int ret;
trace_rdev_tx_control_port(&rdev->wiphy, dev, buf, len,
- dest, proto, noencrypt, link);
+ dest, proto, noencrypt, link, vlan_id);
ret = rdev->ops->tx_control_port(&rdev->wiphy, dev, buf, len,
- dest, proto, noencrypt, link, cookie);
+ dest, proto, noencrypt, link,
+ cookie, vlan_id);
if (cookie)
trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
else
@@ -2170,8 +2170,8 @@ TRACE_EVENT(rdev_mgmt_tx,
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, int link_id),
- TP_ARGS(wiphy, netdev, buf, len, dest, proto, unencrypted, link_id),
+ bool unencrypted, int link_id, u16 vlan_id),
+ TP_ARGS(wiphy, netdev, buf, len, dest, proto, unencrypted, link_id, vlan_id),
TP_STRUCT__entry(
WIPHY_ENTRY
NETDEV_ENTRY
@@ -2179,6 +2179,7 @@ TRACE_EVENT(rdev_tx_control_port,
__field(__be16, proto)
__field(bool, unencrypted)
__field(int, link_id)
+ __field(u16, vlan_id)
),
TP_fast_assign(
WIPHY_ASSIGN;
@@ -2187,13 +2188,16 @@ TRACE_EVENT(rdev_tx_control_port,
__entry->proto = proto;
__entry->unencrypted = unencrypted;
__entry->link_id = link_id;
+ __entry->vlan_id = vlan_id;
),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", %pM,"
- " proto: 0x%x, unencrypted: %s, link: %d",
+ " proto: 0x%x, unencrypted: %s, link: %d,"
+ " vlan_id: %hu",
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->dest,
be16_to_cpu(__entry->proto),
BOOL_TO_STR(__entry->unencrypted),
- __entry->link_id)
+ __entry->link_id,
+ __entry->vlan_id)
);
TRACE_EVENT(rdev_set_noack_map,
Base on EasyMesh spec and traffic separation we have: "If a Multi-AP Agent configures a Primary VLAN ID, the Multi-AP Agent shall send EtherType 0x888E frames on a Wi-Fi link in a Multi-AP Profile-2 Network Segment with an 802.1Q C-Tag with VLAN ID equal to the Primary VLAN ID." Add option that extend current control port implementation when NL80211_ATTR_CONTROL_PORT_OVER_NL80211 used and allow to setup VLAN id for both TX/RX direction. When set for RX direction: - lower layer should check vlan id and strip 8021Q header before pass it to usermode When set for TX direction: - lower layer should add proper 8021Q header Signed-off-by: Janusz Dziedzic <janusz.dziedzic@gmail.com> --- [v2]: - reuse NL80211_ATTR_VLAN_ID - check NL80211_ATTR_CONTROL_PORT_OVER_NL80211 - fix mac80211 compilation include/net/cfg80211.h | 8 +++++++- include/uapi/linux/nl80211.h | 3 ++- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/tx.c | 2 +- net/wireless/nl80211.c | 10 +++++++++- net/wireless/rdev-ops.h | 7 ++++--- net/wireless/trace.h | 12 ++++++++---- 7 files changed, 32 insertions(+), 12 deletions(-)