mac80211: Support BIGTK configuration for Beacon protection
[openwrt/staging/blogic.git] / net / mac80211 / key.c
index 54934eff4ac14356ad7d638e1add90230b537284..6354491c5a099377ab6986cdcb3dd32d12d23fb4 100644 (file)
@@ -407,6 +407,31 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
        mutex_unlock(&sdata->local->key_mtx);
 }
 
+static void
+__ieee80211_set_default_beacon_key(struct ieee80211_sub_if_data *sdata, int idx)
+{
+       struct ieee80211_key *key = NULL;
+
+       assert_key_lock(sdata->local);
+
+       if (idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS &&
+           idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
+           NUM_DEFAULT_BEACON_KEYS)
+               key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
+
+       rcu_assign_pointer(sdata->default_beacon_key, key);
+
+       ieee80211_debugfs_key_update_default(sdata);
+}
+
+void ieee80211_set_default_beacon_key(struct ieee80211_sub_if_data *sdata,
+                                     int idx)
+{
+       mutex_lock(&sdata->local->key_mtx);
+       __ieee80211_set_default_beacon_key(sdata, idx);
+       mutex_unlock(&sdata->local->key_mtx);
+}
+
 static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
                                  struct sta_info *sta,
                                  bool pairwise,
@@ -415,7 +440,7 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
 {
        int idx;
        int ret = 0;
-       bool defunikey, defmultikey, defmgmtkey;
+       bool defunikey, defmultikey, defmgmtkey, defbeaconkey;
 
        /* caller must provide at least one old/new */
        if (WARN_ON(!new && !old))
@@ -480,6 +505,9 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
                defmgmtkey = old &&
                        old == key_mtx_dereference(sdata->local,
                                                sdata->default_mgmt_key);
+               defbeaconkey = old &&
+                       old == key_mtx_dereference(sdata->local,
+                                                  sdata->default_beacon_key);
 
                if (defunikey && !new)
                        __ieee80211_set_default_key(sdata, -1, true, false);
@@ -487,6 +515,8 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
                        __ieee80211_set_default_key(sdata, -1, false, true);
                if (defmgmtkey && !new)
                        __ieee80211_set_default_mgmt_key(sdata, -1);
+               if (defbeaconkey && !new)
+                       __ieee80211_set_default_beacon_key(sdata, -1);
 
                rcu_assign_pointer(sdata->keys[idx], new);
                if (defunikey && new)
@@ -498,6 +528,9 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
                if (defmgmtkey && new)
                        __ieee80211_set_default_mgmt_key(sdata,
                                                         new->conf.keyidx);
+               if (defbeaconkey && new)
+                       __ieee80211_set_default_beacon_key(sdata,
+                                                          new->conf.keyidx);
        }
 
        if (old)
@@ -515,7 +548,9 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
        struct ieee80211_key *key;
        int i, j, err;
 
-       if (WARN_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS))
+       if (WARN_ON(idx < 0 ||
+                   idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
+                   NUM_DEFAULT_BEACON_KEYS))
                return ERR_PTR(-EINVAL);
 
        key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
@@ -978,6 +1013,7 @@ static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata,
        sdata->crypto_tx_tailroom_pending_dec = 0;
 
        ieee80211_debugfs_key_remove_mgmt_default(sdata);
+       ieee80211_debugfs_key_remove_beacon_default(sdata);
 
        list_for_each_entry_safe(key, tmp, &sdata->key_list, list) {
                ieee80211_key_replace(key->sdata, key->sta,