Loading include/net/cfg80211.h +8 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,9 @@ /* Indicate backport support for supported AKM advertisement per interface*/ #define CFG80211_IFTYPE_AKM_SUITES_SUPPORT 1 /* Indicate backport support for key configuration for Beacon protection*/ #define CFG80211_BIGTK_CONFIGURATION_SUPPORT 1 /** * DOC: Introduction * Loading Loading @@ -3018,6 +3021,8 @@ struct cfg80211_update_owe_info { * @set_default_key: set the default key on an interface * * @set_default_mgmt_key: set the default management frame key on an interface * @set_default_beacon_key: set the default Beacon frame key on an interface * * @set_rekey_data: give the data necessary for GTK rekeying to the driver * Loading Loading @@ -3340,6 +3345,9 @@ struct cfg80211_ops { int (*set_default_mgmt_key)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); int (*set_default_beacon_key)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); int (*start_ap)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings); Loading include/uapi/linux/nl80211.h +33 −0 Original line number Diff line number Diff line Loading @@ -4425,6 +4425,10 @@ enum nl80211_key_default_types { * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags * attributes, specifying what a key should be set as default as. * See &enum nl80211_key_default_types. * @NL80211_KEY_MODE: the mode from enum nl80211_key_mode. * Defaults to @NL80211_KEY_RX_TX. * @NL80211_KEY_DEFAULT_BEACON: flag indicating default Beacon frame key * * @__NL80211_KEY_AFTER_LAST: internal * @NL80211_KEY_MAX: highest key attribute */ Loading @@ -4438,6 +4442,8 @@ enum nl80211_key_attributes { NL80211_KEY_DEFAULT_MGMT, NL80211_KEY_TYPE, NL80211_KEY_DEFAULT_TYPES, NL80211_KEY_MODE, NL80211_KEY_DEFAULT_BEACON, /* keep last */ __NL80211_KEY_AFTER_LAST, Loading Loading @@ -5392,6 +5398,26 @@ enum nl80211_feature_flags { * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching * (set/del PMKSA operations) in AP mode. * * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports * filtering of sched scan results using band specific RSSI thresholds. * * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power * to a station. * * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in * station mode (SAE password is passed as part of the connect command). * * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev * with VLAN tagged frames and separate VLAN-specific netdevs added using * vconfig similarly to the Ethernet case. * * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL) * feature, which prevents bufferbloat by using the expected transmission * time to limit the amount of data buffered in the hardware. * * @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection * and can receive key configuration for BIGTK using key indexes 6 and 7. * * @NUM_NL80211_EXT_FEATURES: number of extended features. * @MAX_NL80211_EXT_FEATURES: highest extended feature index. */ Loading Loading @@ -5431,6 +5457,13 @@ enum nl80211_ext_feature_index { NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS, NL80211_EXT_FEATURE_AP_PMKSA_CACHING, NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD, NL80211_EXT_FEATURE_EXT_KEY_ID, NL80211_EXT_FEATURE_STA_TX_PWR, NL80211_EXT_FEATURE_SAE_OFFLOAD, NL80211_EXT_FEATURE_VLAN_OFFLOAD, NL80211_EXT_FEATURE_AQL, NL80211_EXT_FEATURE_BEACON_PROTECTION, /* add new features before the definition below */ NUM_NL80211_EXT_FEATURES, Loading net/wireless/nl80211.c +46 −12 Original line number Diff line number Diff line Loading @@ -855,7 +855,7 @@ struct key_parse { struct key_params p; int idx; int type; bool def, defmgmt; bool def, defmgmt, defbeacon; bool def_uni, def_multi; }; Loading @@ -870,12 +870,13 @@ static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key, k->def = !!tb[NL80211_KEY_DEFAULT]; k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON]; if (k->def) { k->def_uni = true; k->def_multi = true; } if (k->defmgmt) if (k->defmgmt || k->defbeacon) k->def_multi = true; if (tb[NL80211_KEY_IDX]) Loading Loading @@ -987,14 +988,17 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) if (err) return err; if (k->def && k->defmgmt) { GENL_SET_ERR_MSG(info, "key with def && defmgmt is invalid"); if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) + (k->defbeacon ? 1 : 0) > 1) { GENL_SET_ERR_MSG(info, "key with multiple default flags is invalid"); return -EINVAL; } if (k->defmgmt) { if (k->defmgmt || k->defbeacon) { if (k->def_uni || !k->def_multi) { GENL_SET_ERR_MSG(info, "defmgmt key must be mcast"); GENL_SET_ERR_MSG(info, "defmgmt/defbeacon key must be mcast"); return -EINVAL; } } Loading @@ -1006,14 +1010,20 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) "defmgmt key idx not 4 or 5"); return -EINVAL; } } else if (k->defbeacon) { if (k->idx < 6 || k->idx > 7) { GENL_SET_ERR_MSG(info, "defbeacon key idx not 6 or 7"); return -EINVAL; } } else if (k->def) { if (k->idx < 0 || k->idx > 3) { GENL_SET_ERR_MSG(info, "def key idx not 0-3"); return -EINVAL; } } else { if (k->idx < 0 || k->idx > 5) { GENL_SET_ERR_MSG(info, "key idx not 0-5"); if (k->idx < 0 || k->idx > 7) { GENL_SET_ERR_MSG(info, "key idx not 0-7"); return -EINVAL; } } Loading Loading @@ -3492,10 +3502,16 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) void *hdr; struct sk_buff *msg; if (info->attrs[NL80211_ATTR_KEY_IDX]) if (info->attrs[NL80211_ATTR_KEY_IDX]) { key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); if (key_idx > 5 && !wiphy_ext_feature_isset( &rdev->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION)) return -EINVAL; } if (key_idx > 5) if (key_idx > 7) return -EINVAL; if (info->attrs[NL80211_ATTR_MAC]) Loading Loading @@ -3572,7 +3588,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) return -EINVAL; /* only support setting default key */ if (!key.def && !key.defmgmt) if (!key.def && !key.defmgmt && !key.defbeacon) return -EINVAL; wdev_lock(dev->ieee80211_ptr); Loading @@ -3596,7 +3612,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) #ifdef CONFIG_CFG80211_WEXT dev->ieee80211_ptr->wext.default_key = key.idx; #endif } else { } else if (key.defmgmt) { if (key.def_uni || !key.def_multi) { err = -EINVAL; goto out; Loading @@ -3618,6 +3634,24 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) #ifdef CONFIG_CFG80211_WEXT dev->ieee80211_ptr->wext.default_mgmt_key = key.idx; #endif } else if (key.defbeacon) { if (key.def_uni || !key.def_multi) { err = -EINVAL; goto out; } if (!rdev->ops->set_default_beacon_key) { err = -EOPNOTSUPP; goto out; } err = nl80211_key_allowed(dev->ieee80211_ptr); if (err) goto out; err = rdev_set_default_beacon_key(rdev, dev, key.idx); if (err) goto out; } out: Loading net/wireless/rdev-ops.h +13 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,19 @@ rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev, return ret; } static inline int rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev, struct net_device *netdev, u8 key_index) { int ret; trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, key_index); ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev, key_index); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } static inline int rdev_start_ap(struct cfg80211_registered_device *rdev, struct net_device *dev, struct cfg80211_ap_settings *settings) Loading net/wireless/sme.c +9 −2 Original line number Diff line number Diff line Loading @@ -1087,9 +1087,16 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, * Delete all the keys ... pairwise keys can't really * exist any more anyway, but default keys might. */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) if (rdev->ops->del_key) { int max_key_idx = 5; if (wiphy_ext_feature_isset( wdev->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION)) max_key_idx = 7; for (i = 0; i <= max_key_idx; i++) rdev_del_key(rdev, dev, i, false, NULL); } rdev_set_qos_map(rdev, dev, NULL); Loading Loading
include/net/cfg80211.h +8 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,9 @@ /* Indicate backport support for supported AKM advertisement per interface*/ #define CFG80211_IFTYPE_AKM_SUITES_SUPPORT 1 /* Indicate backport support for key configuration for Beacon protection*/ #define CFG80211_BIGTK_CONFIGURATION_SUPPORT 1 /** * DOC: Introduction * Loading Loading @@ -3018,6 +3021,8 @@ struct cfg80211_update_owe_info { * @set_default_key: set the default key on an interface * * @set_default_mgmt_key: set the default management frame key on an interface * @set_default_beacon_key: set the default Beacon frame key on an interface * * @set_rekey_data: give the data necessary for GTK rekeying to the driver * Loading Loading @@ -3340,6 +3345,9 @@ struct cfg80211_ops { int (*set_default_mgmt_key)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); int (*set_default_beacon_key)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); int (*start_ap)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings); Loading
include/uapi/linux/nl80211.h +33 −0 Original line number Diff line number Diff line Loading @@ -4425,6 +4425,10 @@ enum nl80211_key_default_types { * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags * attributes, specifying what a key should be set as default as. * See &enum nl80211_key_default_types. * @NL80211_KEY_MODE: the mode from enum nl80211_key_mode. * Defaults to @NL80211_KEY_RX_TX. * @NL80211_KEY_DEFAULT_BEACON: flag indicating default Beacon frame key * * @__NL80211_KEY_AFTER_LAST: internal * @NL80211_KEY_MAX: highest key attribute */ Loading @@ -4438,6 +4442,8 @@ enum nl80211_key_attributes { NL80211_KEY_DEFAULT_MGMT, NL80211_KEY_TYPE, NL80211_KEY_DEFAULT_TYPES, NL80211_KEY_MODE, NL80211_KEY_DEFAULT_BEACON, /* keep last */ __NL80211_KEY_AFTER_LAST, Loading Loading @@ -5392,6 +5398,26 @@ enum nl80211_feature_flags { * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching * (set/del PMKSA operations) in AP mode. * * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports * filtering of sched scan results using band specific RSSI thresholds. * * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power * to a station. * * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in * station mode (SAE password is passed as part of the connect command). * * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev * with VLAN tagged frames and separate VLAN-specific netdevs added using * vconfig similarly to the Ethernet case. * * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL) * feature, which prevents bufferbloat by using the expected transmission * time to limit the amount of data buffered in the hardware. * * @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection * and can receive key configuration for BIGTK using key indexes 6 and 7. * * @NUM_NL80211_EXT_FEATURES: number of extended features. * @MAX_NL80211_EXT_FEATURES: highest extended feature index. */ Loading Loading @@ -5431,6 +5457,13 @@ enum nl80211_ext_feature_index { NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS, NL80211_EXT_FEATURE_AP_PMKSA_CACHING, NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD, NL80211_EXT_FEATURE_EXT_KEY_ID, NL80211_EXT_FEATURE_STA_TX_PWR, NL80211_EXT_FEATURE_SAE_OFFLOAD, NL80211_EXT_FEATURE_VLAN_OFFLOAD, NL80211_EXT_FEATURE_AQL, NL80211_EXT_FEATURE_BEACON_PROTECTION, /* add new features before the definition below */ NUM_NL80211_EXT_FEATURES, Loading
net/wireless/nl80211.c +46 −12 Original line number Diff line number Diff line Loading @@ -855,7 +855,7 @@ struct key_parse { struct key_params p; int idx; int type; bool def, defmgmt; bool def, defmgmt, defbeacon; bool def_uni, def_multi; }; Loading @@ -870,12 +870,13 @@ static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key, k->def = !!tb[NL80211_KEY_DEFAULT]; k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON]; if (k->def) { k->def_uni = true; k->def_multi = true; } if (k->defmgmt) if (k->defmgmt || k->defbeacon) k->def_multi = true; if (tb[NL80211_KEY_IDX]) Loading Loading @@ -987,14 +988,17 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) if (err) return err; if (k->def && k->defmgmt) { GENL_SET_ERR_MSG(info, "key with def && defmgmt is invalid"); if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) + (k->defbeacon ? 1 : 0) > 1) { GENL_SET_ERR_MSG(info, "key with multiple default flags is invalid"); return -EINVAL; } if (k->defmgmt) { if (k->defmgmt || k->defbeacon) { if (k->def_uni || !k->def_multi) { GENL_SET_ERR_MSG(info, "defmgmt key must be mcast"); GENL_SET_ERR_MSG(info, "defmgmt/defbeacon key must be mcast"); return -EINVAL; } } Loading @@ -1006,14 +1010,20 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) "defmgmt key idx not 4 or 5"); return -EINVAL; } } else if (k->defbeacon) { if (k->idx < 6 || k->idx > 7) { GENL_SET_ERR_MSG(info, "defbeacon key idx not 6 or 7"); return -EINVAL; } } else if (k->def) { if (k->idx < 0 || k->idx > 3) { GENL_SET_ERR_MSG(info, "def key idx not 0-3"); return -EINVAL; } } else { if (k->idx < 0 || k->idx > 5) { GENL_SET_ERR_MSG(info, "key idx not 0-5"); if (k->idx < 0 || k->idx > 7) { GENL_SET_ERR_MSG(info, "key idx not 0-7"); return -EINVAL; } } Loading Loading @@ -3492,10 +3502,16 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) void *hdr; struct sk_buff *msg; if (info->attrs[NL80211_ATTR_KEY_IDX]) if (info->attrs[NL80211_ATTR_KEY_IDX]) { key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); if (key_idx > 5 && !wiphy_ext_feature_isset( &rdev->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION)) return -EINVAL; } if (key_idx > 5) if (key_idx > 7) return -EINVAL; if (info->attrs[NL80211_ATTR_MAC]) Loading Loading @@ -3572,7 +3588,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) return -EINVAL; /* only support setting default key */ if (!key.def && !key.defmgmt) if (!key.def && !key.defmgmt && !key.defbeacon) return -EINVAL; wdev_lock(dev->ieee80211_ptr); Loading @@ -3596,7 +3612,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) #ifdef CONFIG_CFG80211_WEXT dev->ieee80211_ptr->wext.default_key = key.idx; #endif } else { } else if (key.defmgmt) { if (key.def_uni || !key.def_multi) { err = -EINVAL; goto out; Loading @@ -3618,6 +3634,24 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) #ifdef CONFIG_CFG80211_WEXT dev->ieee80211_ptr->wext.default_mgmt_key = key.idx; #endif } else if (key.defbeacon) { if (key.def_uni || !key.def_multi) { err = -EINVAL; goto out; } if (!rdev->ops->set_default_beacon_key) { err = -EOPNOTSUPP; goto out; } err = nl80211_key_allowed(dev->ieee80211_ptr); if (err) goto out; err = rdev_set_default_beacon_key(rdev, dev, key.idx); if (err) goto out; } out: Loading
net/wireless/rdev-ops.h +13 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,19 @@ rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev, return ret; } static inline int rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev, struct net_device *netdev, u8 key_index) { int ret; trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, key_index); ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev, key_index); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } static inline int rdev_start_ap(struct cfg80211_registered_device *rdev, struct net_device *dev, struct cfg80211_ap_settings *settings) Loading
net/wireless/sme.c +9 −2 Original line number Diff line number Diff line Loading @@ -1087,9 +1087,16 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, * Delete all the keys ... pairwise keys can't really * exist any more anyway, but default keys might. */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) if (rdev->ops->del_key) { int max_key_idx = 5; if (wiphy_ext_feature_isset( wdev->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION)) max_key_idx = 7; for (i = 0; i <= max_key_idx; i++) rdev_del_key(rdev, dev, i, false, NULL); } rdev_set_qos_map(rdev, dev, NULL); Loading