From 0f581eec294296d42f1ada495c5846b4ec1546a4 Mon Sep 17 00:00:00 2001 From: Seevalamuthu Mariappan Date: Mon, 15 Jun 2020 12:47:20 +0530 Subject: [PATCH 1/2] mac80211: Add GTK offload support for AP_VLAN Current implementation does not support GTK encryption for VLAN interfaces in driver/hardware since the driver is not aware AP-VLAN interfaces. This patch adds feature flag to allow group key encryption in driver/hardware. Drivers can identify VLAN interfaces from vlan_id in ieee80211_key_conf. Signed-off-by: Seevalamuthu Mariappan --- include/net/mac80211.h | 6 ++++++ net/mac80211/cfg.c | 1 + net/mac80211/debugfs.c | 1 + net/mac80211/iface.c | 8 +++++++- net/mac80211/key.c | 3 ++- net/mac80211/tx.c | 11 ++++++++++- 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f4506ec..f87d7ac 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1773,6 +1773,7 @@ enum ieee80211_key_flags { * - Temporal Authenticator Rx MIC Key (64 bits) * @icv_len: The ICV length for this key type * @iv_len: The IV length for this key type + * @vlan_id: For VLAN interfaces 1-4096, 0 for non-vlan interfaces */ struct ieee80211_key_conf { atomic64_t tx_pn; @@ -1783,6 +1784,7 @@ struct ieee80211_key_conf { s8 keyidx; u16 flags; u8 keylen; + u16 vlan_id; u8 key[0]; }; @@ -2308,6 +2310,9 @@ struct ieee80211_txq { * aggregating MPDUs with the same keyid, allowing mac80211 to keep Tx * A-MPDU sessions active while rekeying with Extended Key ID. * + * @IEEE80211_HW_VLAN_CRYPTO_CONTROL: The driver (or firmware) supports crypto + * algorithms for AP_VLAN interfaces + * * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { @@ -2360,6 +2365,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_MULTI_BSSID, IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID, IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT, + IEEE80211_HW_VLAN_CRYPTO_CONTROL, /* keep last, obviously */ NUM_IEEE80211_HW_FLAGS diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 64e807d..5e8f3a4 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -460,6 +460,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, break; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + key->conf.vlan_id = params->vlan_id; /* Keys without a station are used for TX only */ if (sta && test_sta_flag(sta, WLAN_STA_MFP)) key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 2c2e07c..006afd1 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -408,6 +408,7 @@ static const char *hw_flag_names[] = { FLAG(SUPPORTS_MULTI_BSSID), FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID), FLAG(AMPDU_KEYBORDER_SUPPORT), + FLAG(VLAN_CRYPTO_CONTROL), #undef FLAG }; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b2a2165..1f0822b 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -300,8 +300,14 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, * can only add VLANs to enabled APs */ if (iftype == NL80211_IFTYPE_AP_VLAN && - nsdata->vif.type == NL80211_IFTYPE_AP) + nsdata->vif.type == NL80211_IFTYPE_AP) { + if (ieee80211_hw_check(&local->hw, VLAN_CRYPTO_CONTROL) && + nsdata->hw_80211_encap) { + sdata->dev->netdev_ops = nsdata->dev->netdev_ops; + sdata->hw_80211_encap = true; + } sdata->bss = &nsdata->u.ap; + } } } diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 4b1c45b..96bed31 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -167,7 +167,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) goto out_unsupported; sdata = key->sdata; - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + if (!ieee80211_hw_check(&key->local->hw, VLAN_CRYPTO_CONTROL) && + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { /* * The driver doesn't know anything about VLAN interfaces. * Hence, don't send GTKs for VLAN interfaces to the driver. diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index eed6b2c..e833cb8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4184,6 +4184,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, bool authorized = false; bool multicast; unsigned char *ra = ehdr->h_dest; + struct ieee80211_key *key; if (IS_ERR(sta) || (sta && !sta->uploaded)) sta = NULL; @@ -4209,6 +4210,10 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, !atomic_read(&sdata->u.ap.num_mcast_sta)) goto out_free; + if (multicast && sdata->vif.type == NL80211_IFTYPE_AP_VLAN && + !atomic_read(&sdata->u.vlan.num_mcast_sta)) + goto out_free; + if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) goto out_free; @@ -4237,9 +4242,13 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, sta->tx_stats.packets[skb_get_queue_mapping(skb)]++; } - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + if (multicast && ieee80211_hw_check(&local->hw, VLAN_CRYPTO_CONTROL) && + (key = rcu_dereference(sdata->default_multicast_key))) + info->control.hw_key = &key->conf; sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); + } info->control.flags |= IEEE80211_TX_CTRL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -- 2.7.4