From patchwork Mon Apr 7 18:34:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Dziedzic X-Patchwork-Id: 879342 Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D99D2AEE3 for ; Mon, 7 Apr 2025 18:38:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744051126; cv=none; b=orsDXgBjAf9dAP//eBzhY/PI0dX0oJ5+oLK0T5q+BGTdTsdhLI7LhoEHH2BWNtDhqDkPltP+xnYsBGdpppYG4dU0OwIssRHN2ThKwnGvtXxE/wHbsyXE+ZtneHX0glC6gfKshL36B3YsnvY0Y9RYH63hBJaNgln1EXPWOU6jBU0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744051126; c=relaxed/simple; bh=iGsBLOZw4JzeSoMQlpcvwwxpXxXh0Xq3KIb4Lj3+xpA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=EjSGkNFnNdSns2j7Z5UMvBDd6JmiJ9pT4y0CURAq0VKVjq4SkTjAfBOd98pTV2TFbpfXFP/Q8+V3a/UEAKtFTcQvExD5egJDL1aehV2MXazsjIzGiEFvkxIavvMAfUCBLTJWrSdwlFcF6eDoUnK6IMREcKszNhl3vsZIOyOmGJ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VUcvZdn4; arc=none smtp.client-ip=209.85.218.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VUcvZdn4" Received: by mail-ej1-f54.google.com with SMTP id a640c23a62f3a-ac3fcf5ab0dso796373366b.3 for ; Mon, 07 Apr 2025 11:38:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1744051123; x=1744655923; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=VGu1XTxubzqy7PTXDOVdOtmV+HSHKwFlKswqmRXSA+o=; b=VUcvZdn4gnxCcoqy44EZZCJYfGs/eQcD9GmGTwVQvpLaM1vdftCNAEk/wvpcvFxseO GStYlDqYux+GXk7qa2emTNnn+43oYH5C4GCP8WxdE9Nj121W3LFTKEVWHjFl4Wc7r0Vj id0unXdclCLDTt4imbzyRHWPK4m7WLBPG5hD/iVi63QDwKcCB5cd/+jMuJetMqvZ/Jwe iWCKOSlzuEhtlKbv8a41+8bkFN/1trzr/4krDdmiUEJ6iYSEn0ltTSCfrIAvz2t9Ummn fQ3HQ40PRHNFBrdVEFa13ylwMnbyyuQH5CGudeLbQNdEZCTkJdrtEInXUA+86Ur5nc9/ vQjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744051123; x=1744655923; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=VGu1XTxubzqy7PTXDOVdOtmV+HSHKwFlKswqmRXSA+o=; b=dtz5Z26E/eTratC98zlNeQUNdTmXU5j+w75staKvqJf5mxUB/++rIHi5FVfcP/xHeY n//+7Y37fh03XprPv4+h3kQAsouRULFLKc6F+MQ4fr//VWKcxpiJ3mwhV8AhexixGI93 xD/FS9YBDvIltKL/L0ZGG6IdBErxAMAGJq9o15eUR1QSvf2ZHOOaYmq0DhY39BPKMTE0 FDruIWyLVmVxFyvMabPd3On1QN0SfUa8kxMnhCJ8p/ZDGzLxeNJcxcuttvcvfJVRSzIH KVx96sMxPSTPCBNtCCXYMTyeRabzKzuNnPX+8dcQsZtGQFrQ2dhc01rkSXTpbmLgOusP d4Ww== X-Gm-Message-State: AOJu0YxM4BlgQkCnOyGOxkdU5Ld1G3SQ9/6CdIKxRdOH/KxcfzXhzbJR DZzD0JZalyTXGKX4zcfT/DYrGyiJe1ZHk9yRnOX42VW8JTm53BGpFNYCXs9l X-Gm-Gg: ASbGncuedk0tS5HyOUQnPNyetsjLIUl/v3IieUUq89szS8e1N5NxyQIPVl1oRYqKNWg fw1g/1Zun17YltYzMBiwVHCrjxuqrYSDygrOqFrzBwDGhjpTNpZuPeg8DO8OqEw3y2H0JDQ0J6X y6h6h6NxHPMxIxPIEWhSM9WcxFImNbsMLV8EORAJkIiyyShmtaM/e7UcREw1tsbxntsHxO5HRLS 0tTcZCSBMmfqSMDLPL6nmtcOr/0Jkhy9d+zkC/xy9HHBpDAgU8u9MJM3tVx0G3zx3vsO0N7fLxJ wL2G8dKaFgdOd4dnzsmmrOkVJeEZ+oVP8jo8scawo1EoGftvn37YXsy7n+godbcTejfCKJhvLMK C21yok6DRSaVi7BYhytgFVVCIc/4nY5qy4iahkV95UIapZKfeu+KT0SNwY4ke X-Google-Smtp-Source: AGHT+IHJumOX2Hi/t0SHkpI+MnhvUOml5OoELzkBbas1M9H1ciwlWfiD0Rxdy8bz6gCZ76ywkGdJ9A== X-Received: by 2002:a17:907:1b1e:b0:ac7:19f0:aa5a with SMTP id a640c23a62f3a-ac7e72ce4dcmr839122466b.27.1744051122267; Mon, 07 Apr 2025 11:38:42 -0700 (PDT) Received: from hp.NAT.swidnica_mmp.vectranet.pl (178235177162.dynamic-4-waw-k-1-1-0.vectranet.pl. [178.235.177.162]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac7bfe99b24sm795355866b.53.2025.04.07.11.38.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Apr 2025 11:38:41 -0700 (PDT) From: Janusz Dziedzic To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, j@w1.fi, Janusz Dziedzic Subject: [RFC v2 wireless-next 1/2] wifi: cfg80211: allow send/recv tagged EAPOLs Date: Mon, 7 Apr 2025 20:34:07 +0200 Message-ID: <20250407183818.759759-1-janusz.dziedzic@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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 --- [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(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index efbd79c67be2..47cc25ebb56b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -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, diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index ddcc4cda74af..1564b4420cab 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -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. * diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fb05f3cd37ec..7012bda050bb 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -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, diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 20179db88c4a..1988234b6149 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -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; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f039a7d0d6f7..07ae84b0212f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -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; diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 9f4783c2354c..23e581a99a9c 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -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 diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 4ed9fada4ec0..4e92601fd72e 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -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, From patchwork Mon Apr 7 18:34:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Dziedzic X-Patchwork-Id: 879032 Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36F363208 for ; Mon, 7 Apr 2025 18:38:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744051127; cv=none; b=thSHaUVU8aTACK7TFrXAFLi28obTR1HveshogU9q8/kOlqo1eDVLJlQ3Nz0iJ8U+a3YZT8SBv2hGjinWOtiHdpQxLxDjPpCsoDffcke1inJwOFgK8mFFzrHPSaZVaRraZCf2AGcIU6IEFl3OWopiSrG08VzfDL3PQST8BIOamXs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744051127; c=relaxed/simple; bh=Ls8kV5zIYbsE22Y3kiIuOqPmNCFWqLLTxpNTl88I+JE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SJNef00P/a8d3tPitYJ74Jf2NwruZV5jrY0D+vmQ9Vjp5lahcPwBZZFZ9/Nh+TcFu+z/vHxVe82jOOUPqdRdbf+Cxnu4jLct1vL8QCrw/k+BzjEM7aGh1y9mySHy0P+lyvXwZSsPtuDvGcg6XG5TLY2suCCFIF4jwjLrQwj/g5Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NrFeydJF; arc=none smtp.client-ip=209.85.218.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NrFeydJF" Received: by mail-ej1-f54.google.com with SMTP id a640c23a62f3a-ac3eb3fdd2eso550314166b.0 for ; Mon, 07 Apr 2025 11:38:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1744051123; x=1744655923; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9Dv4+fJg4CM82PZEP84xrEdxNGkZsZOBCUv5yue9Iuk=; b=NrFeydJFDd3sQ5FwyzqZlfASAeFFCAarD1hoAXbb5VFXdTzh3455o8E3pV/Uxch7DL tJEeyqjRpE2L93jQ8q3A16AreRjPDKCWXL60LAKQYblnWemBbpCoFdYqPZ15FSOvG5NM l14Qez3+yn5s8RNfv7bXozNQdEdbyM2d5q4SK/AFgDbFST1qK78wJ7wqC187F62Alp3s RU+z0sGzkcGzXLi9dmu5zNGdeirY8BomSjhmWMCo1f4E2r+i5+CdEZJZA0ZY4mol1+HX C+aWZiEBShtep2iQO8ql4hQ9S1oB2vV9RbgWWDjWgVaG0XZBrETl1rF/kXw++iQ5WkGp R2pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744051123; x=1744655923; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9Dv4+fJg4CM82PZEP84xrEdxNGkZsZOBCUv5yue9Iuk=; b=U6T0mR4qHZ920gMq+uC3i/HM/I/gtMu2PF4jYqUVCXixOKpK8AegL4VmeN08NjnNDn VwuBvs03pApE0xu1YbzWTFG3RqdaEiUafdxlGCvTHUO3c8WWl+tEGsrs4BDiZWaNpGnc DfX87/9f02UHcCyUOvM4ILuLNASFSeB/GQrYkm+euoixFWRr1ZaZe/gaWKqVswfgtxqk tvSltIeQ/gITrPqy7Y0IuZ5J/8WJVTQhtSHU1NNWcBObmo7OSVDI7xZJ4nfubb0DqgyZ 30kEklfh0TrBai0tpd0Z0Z++zD5SkXvlYfpgFCDIGg/aVyjRMOFpMWVQ2vYT9S15JnwY XZOg== X-Gm-Message-State: AOJu0YxaeoTSN2pualpRdUILCWR4/QDP2LYeqgSVw24KCpVnbivw/7eF Pz2vjKxJjSUFElryLkmIwu9oz6M28uNME6nzx5Pu3g7cdR7a/pz9RHwot3Ha X-Gm-Gg: ASbGncv504bEEcrpSymv/2ifx/xz0MlombPeXK2wBiGGePcpffRFLQGG4OVn3iZy1P6 lYZVNDwnbBXH7i6PiMi0YnD4Df5oH0Q/4XyEq/y7LAcfSP9Nue09XppvB/Awv0aGxFVlrMKHR2G 47jd/43Uof1OGzaCqBQJEcAXR8Z5J3LGP6KGUkEl8CYogcKVJNZZa/VS+NPnYpK+XBYNOIRo+eM 2plaQ4nkXkAExNfShd97RDfjlooX0YvxAncWmi5KD1N+S7Xrje1n53zw/Pxtt0vQaT5KVlP3iaG jj8GyT3Cosa3y1/yxsjC2ZmVxNKy6iY+vNpX2uJZxitcHfplyCF6b/O9aDkVonCIS+eP/Z9ZW2K W/Un70+jdXoyAx7CSgPZi8IW1IH5N2nevPZUYuAyBnenD50yzhEK0y+0gDEK7gaYw7tHlBp8= X-Google-Smtp-Source: AGHT+IFcBAPIoOc021zKzjgQs58i7IqQm14LMxXpRjb8j49cfXOfUeEMBLgkKgDqL1O9VNeDUo00Gg== X-Received: by 2002:a17:907:1c8e:b0:ac7:c584:e691 with SMTP id a640c23a62f3a-ac7d1ccdc8fmr1295026466b.54.1744051123100; Mon, 07 Apr 2025 11:38:43 -0700 (PDT) Received: from hp.NAT.swidnica_mmp.vectranet.pl (178235177162.dynamic-4-waw-k-1-1-0.vectranet.pl. [178.235.177.162]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac7bfe99b24sm795355866b.53.2025.04.07.11.38.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Apr 2025 11:38:42 -0700 (PDT) From: Janusz Dziedzic To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, j@w1.fi, Janusz Dziedzic Subject: [RFC v2 wireless-next 2/2] wifi: mac80211: support tagged EAPOLs Date: Mon, 7 Apr 2025 20:34:08 +0200 Message-ID: <20250407183818.759759-2-janusz.dziedzic@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250407183818.759759-1-janusz.dziedzic@gmail.com> References: <20250407183818.759759-1-janusz.dziedzic@gmail.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 When configured control_port_over_nl80211 allow to receive/send tagged EAPOLs. Signed-off-by: Janusz Dziedzic --- [v2]: - introduce helpers - enable only when control_port_over_nl80211 net/mac80211/cfg.c | 3 +++ net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/iface.c | 2 ++ net/mac80211/rx.c | 54 ++++++++++++++++++++++++++++++++++++-- net/mac80211/tx.c | 23 +++++++++++++--- 5 files changed, 79 insertions(+), 6 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9f683f838431..33de4c1cafd6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1443,6 +1443,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, params->crypto.control_port_over_nl80211; sdata->control_port_no_preauth = params->crypto.control_port_no_preauth; + sdata->control_port_vlan_id = params->crypto.control_port_vlan_id; list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { vlan->control_port_protocol = @@ -1453,6 +1454,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, params->crypto.control_port_over_nl80211; vlan->control_port_no_preauth = params->crypto.control_port_no_preauth; + vlan->control_port_vlan_id = + params->crypto.control_port_vlan_id; } link_conf->dtim_period = params->dtim_period; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 7012bda050bb..9d6e8f5df310 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1142,6 +1142,7 @@ struct ieee80211_sub_if_data { bool control_port_no_encrypt; bool control_port_no_preauth; bool control_port_over_nl80211; + u16 control_port_vlan_id; atomic_t num_tx_queued; struct mac80211_qos_map __rcu *qos_map; @@ -1890,6 +1891,8 @@ void ieee80211_clear_fast_rx(struct sta_info *sta); bool ieee80211_is_our_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr, int *out_link_id); +bool ieee80211_is_vlan_control(struct ieee80211_sub_if_data *sdata, + struct ethhdr *ehdr); /* STA code */ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b0423046028c..9e5e40aabee0 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1257,6 +1257,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) master->control_port_over_nl80211; sdata->control_port_no_preauth = master->control_port_no_preauth; + sdata->control_port_vlan_id = + master->control_port_vlan_id; sdata->vif.cab_queue = master->vif.cab_queue; memcpy(sdata->vif.hw_queue, master->vif.hw_queue, sizeof(sdata->vif.hw_queue)); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f7f89cd1b7d7..d525fe901afc 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "ieee80211_i.h" #include "driver-ops.h" @@ -114,6 +115,43 @@ static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len, return false; } +bool ieee80211_is_vlan_control(struct ieee80211_sub_if_data *sdata, + struct ethhdr *ehdr) +{ + struct vlan_ethhdr *vhdr = (void *)ehdr; + + if (!sdata->control_port_over_nl80211) + return false; + if (ehdr->h_proto != cpu_to_be16(ETH_P_8021Q)) + return false; + if (vhdr->h_vlan_encapsulated_proto != sdata->control_port_protocol) + return false; + + return true; +} + +static bool ieee80211_vlan_control_allowed(struct ieee80211_rx_data *rx, + struct ethhdr *ehdr) +{ + struct vlan_ethhdr *vhdr = (void *)ehdr; + struct ieee80211_sub_if_data *sdata = rx->sdata; + u16 vlan_id; + + if (!sdata->control_port_over_nl80211) + return false; + if (!sdata->control_port_vlan_id) + return false; + + if (!ieee80211_is_vlan_control(sdata, ehdr)) + return false; + + vlan_id = be16_to_cpu(vhdr->h_vlan_TCI) & VLAN_VID_MASK; + if (vlan_id != sdata->control_port_vlan_id) + return false; + + return true; +} + static int ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local, struct ieee80211_rx_status *status, @@ -2551,7 +2589,8 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control) return RX_DROP_U_INVALID_8023; ehdr = (struct ethhdr *) rx->skb->data; - if (ehdr->h_proto == rx->sdata->control_port_protocol) + if (ehdr->h_proto == rx->sdata->control_port_protocol || + ieee80211_vlan_control_allowed(rx, ehdr)) *port_control = true; else if (check_port_control) return RX_DROP_U_NOT_PORT_CONTROL; @@ -2602,7 +2641,8 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) * whether the frame was encrypted or not, and always disallow * all other destination addresses for them. */ - if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol)) + if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol || + ieee80211_vlan_control_allowed(rx, ehdr))) return ieee80211_is_our_addr(rx->sdata, ehdr->h_dest, NULL) || ether_addr_equal(ehdr->h_dest, pae_group_addr); @@ -2626,6 +2666,16 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); bool noencrypt = !(status->flag & RX_FLAG_DECRYPTED); + cfg80211_rx_control_port(dev, skb, noencrypt, rx->link_id); + dev_kfree_skb(skb); + } else if (ieee80211_vlan_control_allowed(rx, (void *)skb_mac_header(skb))) { + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + bool noencrypt = !(status->flag & RX_FLAG_DECRYPTED); + + /* strip VLAN */ + skb_pull(skb, VLAN_HLEN); + skb->protocol = sdata->control_port_protocol; + cfg80211_rx_control_port(dev, skb, noencrypt, rx->link_id); dev_kfree_skb(skb); } else { diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1988234b6149..9b20f19bca4e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2862,7 +2862,8 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && (sdata->vif.type != NL80211_IFTYPE_OCB) && !multicast && !authorized && - (cpu_to_be16(ethertype) != sdata->control_port_protocol || + ((cpu_to_be16(ethertype) != sdata->control_port_protocol && + !ieee80211_is_vlan_control(sdata, (void *)skb->data)) || !ieee80211_is_our_addr(sdata, skb->data + ETH_ALEN, NULL)))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", @@ -6143,6 +6144,8 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; + unsigned int hdrlen = sizeof(struct ethhdr); + struct vlan_hdr *vhdr; struct sta_info *sta; struct sk_buff *skb; struct ethhdr *ehdr; @@ -6170,17 +6173,29 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, if (cookie) ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; - flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX; + flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX | + IEEE80211_TX_CTL_USE_MINRATE; + + if (vlan_id) + hdrlen += sizeof(struct vlan_hdr); skb = dev_alloc_skb(local->hw.extra_tx_headroom + - sizeof(struct ethhdr) + len); + hdrlen + len); if (!skb) return -ENOMEM; - skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr)); + skb_reserve(skb, local->hw.extra_tx_headroom + hdrlen); skb_put_data(skb, buf, len); + if (vlan_id) { + vhdr = skb_push(skb, VLAN_HLEN); + vhdr->h_vlan_encapsulated_proto = + sdata->control_port_protocol; + vhdr->h_vlan_TCI = cpu_to_be16(vlan_id & VLAN_VID_MASK); + proto = cpu_to_be16(ETH_P_8021Q); + } + ehdr = skb_push(skb, sizeof(struct ethhdr)); memcpy(ehdr->h_dest, dest, ETH_ALEN);