From patchwork Tue Feb 6 14:15:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sabrina Dubroca X-Patchwork-Id: 1896762 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=XVKAE18K; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TW7zf53pqz23hb for ; Fri, 9 Feb 2024 07:35:58 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=wsBho+t3wi/HUdwNuE6EgofAgl9ZdkrDLMB4M8f8d38=; b=XVKAE18KT2pPzc ylIulTahVP8Ot9s4X5BT/G0UbFNyJBrNluQUmPFdM/6w9u+8Ck6x05SzLMT04WtpsASlGnygeuoZZ fODxoDJPk/FjW/bO9hHldkGObSVwA6ssyh36pF1LXHBmf02n0H5GxxhqCwEzHwNHRmmDJe3P2s9P+ yrzwLbJXihNy88wV3TlZbNpVKT5gTPiJoVKcuzxIqu3wkttukXHv6lDj5YPzyl5UjHT4MbCSvMVeg MDdtJoN3mbZa1MaTOPRs31HcXpV7R4hgMnrhr3mbgqncoowWJEjauC6OuUhEivPHAjQAj7GyKDiZo eWpGs+RxdM4B14T+s8jg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rYB7W-0000000EsHR-1R2x; Thu, 08 Feb 2024 20:35:42 +0000 Received: from us-smtp-delivery-44.mimecast.com ([205.139.111.44]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rXMEX-00000007pws-1BGv for hostap@lists.infradead.org; Tue, 06 Feb 2024 14:15:35 +0000 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-492-HDRNBrz2P4GS2hJCCKm_Ug-1; Tue, 06 Feb 2024 09:15:22 -0500 X-MC-Unique: HDRNBrz2P4GS2hJCCKm_Ug-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id B317D811E79; Tue, 6 Feb 2024 14:15:21 +0000 (UTC) Received: from hog.localdomain (unknown [10.39.192.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id C86FC2166B31; Tue, 6 Feb 2024 14:15:20 +0000 (UTC) From: Sabrina Dubroca To: hostap@lists.infradead.org Cc: Sabrina Dubroca , Davide Caratti , Beniamino Galvani , Emeel Hakim Subject: [PATCH] add new macsec offload modes to abstract device-level details Date: Tue, 6 Feb 2024 15:15:03 +0100 Message-ID: <60dcc64858ca4e5d68af054a3a5f41cecd6df630.1707160280.git.sd@queasysnail.net> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: queasysnail.net X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240206_061533_496170_FE6380B3 X-CRM114-Status: GOOD ( 17.28 ) X-Spam-Score: -0.7 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Currently, users have to guess which offload mode their hardware provides, as the kernel doesn't expose this information. Add an "on" mode which requires offload (either to mac or phy) and a "prefer" mode which allows fallback to SW when offload (either to mac or phy) is unavailable. Content analysis details: (-0.7 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [205.139.111.44 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Mailman-Approved-At: Thu, 08 Feb 2024 12:35:41 -0800 X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Currently, users have to guess which offload mode their hardware provides, as the kernel doesn't expose this information. Add an "on" mode which requires offload (either to mac or phy) and a "prefer" mode which allows fallback to SW when offload (either to mac or phy) is unavailable. Also rename the existing modes to string values to make the config file a bit clearer. Signed-off-by: Sabrina Dubroca Reviewed-by: Emeel Hakim --- hostapd/config_file.c | 32 ++++++++++--- hostapd/hostapd.conf | 8 ++-- src/ap/ap_config.h | 4 +- src/common/ieee802_1x_defs.h | 10 ++++ src/drivers/driver.h | 4 +- src/drivers/driver_macsec_linux.c | 73 +++++++++++++++++++++++++----- wpa_supplicant/config.c | 36 ++++++++++++++- wpa_supplicant/config_file.c | 8 +++- wpa_supplicant/config_ssid.h | 4 +- wpa_supplicant/wpa_supplicant.conf | 10 ++-- 10 files changed, 152 insertions(+), 37 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 1af083917052..7c00398dcc01 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2435,6 +2435,29 @@ static int get_u16(const char *pos, int line, u16 *ret_val) } #endif /* CONFIG_IEEE80211BE */ +#ifdef CONFIG_MACSEC +const char *macsec_offload_strings[NUM_CONFIG_MACSEC_OFFLOAD_MODES] = { + "off", + "on", + "mac", + "phy", + "prefer", +}; +static int parse_macsec_offload(struct hostapd_bss_config *bss, const char *val) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(macsec_offload_strings); i++) { + if (os_strcmp(macsec_offload_strings[i], val) == 0) { + bss->macsec_offload = i; + return 0; + } + } + + return 1; +} +#endif /* CONFIG_MACSEC */ + static int hostapd_config_fill(struct hostapd_config *conf, struct hostapd_bss_config *bss, @@ -4816,15 +4839,12 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "macsec_replay_window") == 0) { bss->macsec_replay_window = atoi(pos); } else if (os_strcmp(buf, "macsec_offload") == 0) { - int macsec_offload = atoi(pos); - - if (macsec_offload < 0 || macsec_offload > 2) { + if (parse_macsec_offload(bss, pos)) { wpa_printf(MSG_ERROR, - "Line %d: invalid macsec_offload (%d): '%s'.", - line, macsec_offload, pos); + "Line %d: invalid macsec_offload: '%s'.", + line, pos); return 1; } - bss->macsec_offload = macsec_offload; } else if (os_strcmp(buf, "macsec_port") == 0) { int macsec_port = atoi(pos); diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 13576499a358..368e0c3622ed 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1174,9 +1174,11 @@ eapol_key_index_workaround=0 # This setting applies only when MACsec is in use, i.e., # - macsec_policy is enabled # - the key server has decided to enable MACsec -# 0 = MACSEC_OFFLOAD_OFF (default) -# 1 = MACSEC_OFFLOAD_PHY -# 2 = MACSEC_OFFLOAD_MAC +# off = don't offload (default) +# mac = request offload to the MAC +# phy = request offload to the PHY +# on = request offload (to either MAC or PHY) +# prefer = try to offload (to either MAC or PHY), fall back to software # # macsec_port: IEEE 802.1X/MACsec port # Port component of the SCI diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index de02ddafda77..5ce68b8d0b73 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -863,9 +863,7 @@ struct hostapd_bss_config { * - macsec_policy is enabled * - the key server has decided to enable MACsec * - * 0 = MACSEC_OFFLOAD_OFF (default) - * 1 = MACSEC_OFFLOAD_PHY - * 2 = MACSEC_OFFLOAD_MAC + * Values: enum macsec_offload_modes */ int macsec_offload; diff --git a/src/common/ieee802_1x_defs.h b/src/common/ieee802_1x_defs.h index e7acff108eb3..ea964e1dd338 100644 --- a/src/common/ieee802_1x_defs.h +++ b/src/common/ieee802_1x_defs.h @@ -83,4 +83,14 @@ enum confidentiality_offset { #define DEFAULT_PRIO_GROUP_CA_MEMBER 0x70 #define DEFAULT_PRIO_NOT_KEY_SERVER 0xFF +enum macsec_offload_modes { + CONFIG_MACSEC_OFFLOAD_OFF, + CONFIG_MACSEC_OFFLOAD_ON, + CONFIG_MACSEC_OFFLOAD_MAC, + CONFIG_MACSEC_OFFLOAD_PHY, + CONFIG_MACSEC_OFFLOAD_PREFER, + NUM_CONFIG_MACSEC_OFFLOAD_MODES, +}; +extern const char *macsec_offload_strings[NUM_CONFIG_MACSEC_OFFLOAD_MODES]; + #endif /* IEEE802_1X_DEFS_H */ diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 4974bbdc8711..e018aabcf8ed 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4662,9 +4662,7 @@ struct wpa_driver_ops { /** * set_offload - Set MACsec hardware offload * @priv: Private driver interface data - * @offload: 0 = MACSEC_OFFLOAD_OFF - * 1 = MACSEC_OFFLOAD_PHY - * 2 = MACSEC_OFFLOAD_MAC + * @offload: enum macsec_offload_modes * Returns: 0 on success, -1 on failure (or if not supported) */ int (*set_offload)(void *priv, u8 offload); diff --git a/src/drivers/driver_macsec_linux.c b/src/drivers/driver_macsec_linux.c index c867154981e9..3124104f4aad 100644 --- a/src/drivers/driver_macsec_linux.c +++ b/src/drivers/driver_macsec_linux.c @@ -78,7 +78,7 @@ struct macsec_drv_data { bool replay_protect_set; #ifdef LIBNL_HAS_OFFLOAD - enum macsec_offload offload; + enum macsec_offload_modes offload; bool offload_set; #endif /* LIBNL_HAS_OFFLOAD */ @@ -237,26 +237,77 @@ static int try_commit(struct macsec_drv_data *drv) drv->replay_window); } + if (drv->encoding_sa_set) { + wpa_printf(MSG_DEBUG, DRV_PREFIX + "%s: try_commit encoding_sa=%d", + drv->ifname, drv->encoding_sa); + rtnl_link_macsec_set_encoding_sa(drv->link, drv->encoding_sa); + } + + /* must be last */ #ifdef LIBNL_HAS_OFFLOAD if (drv->offload_set) { + int offload_value; + wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: try_commit offload=%d", drv->ifname, drv->offload); - rtnl_link_macsec_set_offload(drv->link, drv->offload); - } -#endif /* LIBNL_HAS_OFFLOAD */ + if (drv->offload == CONFIG_MACSEC_OFFLOAD_PREFER || + drv->offload == CONFIG_MACSEC_OFFLOAD_ON) { + /* try MAC, then PHY, and also OFF (only for PREFER) */ + wpa_printf(MSG_DEBUG, DRV_PREFIX + "%s: attempting MACSEC_OFFLOAD_MAC", + drv->ifname); + rtnl_link_macsec_set_offload(drv->link, MACSEC_OFFLOAD_MAC); + if (rtnl_link_add(drv->sk, drv->link, 0) >= 0) + goto end; + + wpa_printf(MSG_DEBUG, DRV_PREFIX + "%s: attempting MACSEC_OFFLOAD_PHY", + drv->ifname); + rtnl_link_macsec_set_offload(drv->link, MACSEC_OFFLOAD_PHY); + if (rtnl_link_add(drv->sk, drv->link, 0) >= 0) + goto end; + + if (drv->offload == CONFIG_MACSEC_OFFLOAD_ON) { + wpa_printf(MSG_DEBUG, DRV_PREFIX + "%s: offload was requested but couldn't be set", + drv->ifname); + return -1; + } - if (drv->encoding_sa_set) { - wpa_printf(MSG_DEBUG, DRV_PREFIX - "%s: try_commit encoding_sa=%d", - drv->ifname, drv->encoding_sa); - rtnl_link_macsec_set_encoding_sa(drv->link, drv->encoding_sa); + wpa_printf(MSG_DEBUG, DRV_PREFIX + "%s: attempting MACSEC_OFFLOAD_OFF", + drv->ifname); + rtnl_link_macsec_set_offload(drv->link, MACSEC_OFFLOAD_OFF); + if (rtnl_link_add(drv->sk, drv->link, 0) >= 0) + goto end; + + return -1; + } + + switch (drv->offload) { + case CONFIG_MACSEC_OFFLOAD_MAC: + offload_value = MACSEC_OFFLOAD_MAC; + break; + case CONFIG_MACSEC_OFFLOAD_PHY: + offload_value = MACSEC_OFFLOAD_PHY; + break; + default: + offload_value = MACSEC_OFFLOAD_OFF; + break; + } + rtnl_link_macsec_set_offload(drv->link, offload_value); } +#endif /* LIBNL_HAS_OFFLOAD */ err = rtnl_link_add(drv->sk, drv->link, 0); if (err < 0) return err; +#ifdef LIBNL_HAS_OFFLOAD +end: +#endif /* LIBNL_HAS_OFFLOAD */ drv->protect_frames_set = false; drv->encrypt_set = false; drv->replay_protect_set = false; @@ -476,9 +527,7 @@ static int macsec_drv_set_replay_protect(void *priv, bool enabled, /** * macsec_drv_set_offload - Set offload status * @priv: Private driver interface data - * @offload: 0 = MACSEC_OFFLOAD_OFF - * 1 = MACSEC_OFFLOAD_PHY - * 2 = MACSEC_OFFLOAD_MAC + * @offload: see enum macsec_offload_modes * Returns: 0 on success, -1 on failure (or if not supported) */ static int macsec_drv_set_offload(void *priv, u8 offload) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index fca4320a19f2..e8dc14c4fa13 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2280,6 +2280,30 @@ static int wpa_config_parse_mka_ckn(const struct parse_data *data, return 0; } +const char *macsec_offload_strings[NUM_CONFIG_MACSEC_OFFLOAD_MODES] = { + "off", + "on", + "mac", + "phy", + "prefer", +}; +static int wpa_config_parse_macsec_offload(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(macsec_offload_strings); i++) { + if (os_strcmp(macsec_offload_strings[i], value) == 0) { + ssid->macsec_offload = i; + return 0; + } + } + + wpa_printf(MSG_ERROR, "Line %d: Invalid macsec_offload: '%s'.", + line, value); + return -1; +} #ifndef NO_CONFIG_WRITE @@ -2301,6 +2325,16 @@ static char * wpa_config_write_mka_ckn(const struct parse_data *data, return wpa_config_write_string_hex(ssid->mka_ckn, ssid->mka_ckn_len); } +static char * wpa_config_write_macsec_offload(const struct parse_data *data, + struct wpa_ssid *ssid) +{ + const char *str = macsec_offload_strings[ssid->macsec_offload]; + + if (ssid->macsec_offload >= ARRAY_SIZE(macsec_offload_strings)) + return NULL; + return wpa_config_write_string_ascii((const u8 *)str, strlen(str)); +} + #endif /* NO_CONFIG_WRITE */ #endif /* CONFIG_MACSEC */ @@ -2694,7 +2728,7 @@ static const struct parse_data ssid_fields[] = { { INT_RANGE(macsec_integ_only, 0, 1) }, { INT_RANGE(macsec_replay_protect, 0, 1) }, { INT(macsec_replay_window) }, - { INT_RANGE(macsec_offload, 0, 2) }, + { FUNC_KEY(macsec_offload) }, { INT_RANGE(macsec_port, 1, 65534) }, { INT_RANGE(mka_priority, 0, 255) }, { INT_RANGE(macsec_csindex, 0, 1) }, diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 4db85f9c07e1..80e40e47c97e 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -663,6 +663,12 @@ static void write_mka_ckn(FILE *f, struct wpa_ssid *ssid) os_free(value); } +static void write_macsec_offload(FILE *f, struct wpa_ssid *ssid) +{ + if (ssid->macsec_offload < ARRAY_SIZE(macsec_offload_strings)) + fprintf(f, "\tmacsecoffload=%s\n", macsec_offload_strings[ssid->macsec_offload]); +} + #endif /* CONFIG_MACSEC */ @@ -814,7 +820,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT(macsec_integ_only); INT(macsec_replay_protect); INT(macsec_replay_window); - INT(macsec_offload); + write_macsec_offload(f, ssid); INT(macsec_port); INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER); INT(macsec_csindex); diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index ff045380ec96..c9d0ea195eed 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -934,9 +934,7 @@ struct wpa_ssid { * This setting applies only when MACsec is in use, i.e., * - the key server has decided to enable MACsec * - * 0 = MACSEC_OFFLOAD_OFF (default) - * 1 = MACSEC_OFFLOAD_PHY - * 2 = MACSEC_OFFLOAD_MAC + * Values: macsec_offload_modes */ int macsec_offload; diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 743f2a323e0e..74a6002cc01b 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -1150,13 +1150,13 @@ fast_reauth=1 # 1..2^32-1: number of packets that could be misordered # # macsec_offload - Enable MACsec hardware offload -# # This setting applies only when MACsec is in use, i.e., # - the key server has decided to enable MACsec -# -# 0 = MACSEC_OFFLOAD_OFF (default) -# 1 = MACSEC_OFFLOAD_PHY -# 2 = MACSEC_OFFLOAD_MAC +# off = don't offload (default) +# mac = request offload to the MAC +# phy = request offload to the PHY +# on = request offload (to either MAC or PHY) +# prefer = try to offload (to either MAC or PHY), fall back to software # # macsec_port: IEEE 802.1X/MACsec port # Port component of the SCI