Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7e0104c authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

mac80211: support separate default keys



Add support for split default keys (unicast
and multicast) in mac80211.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent dbd2fd65
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -300,7 +300,7 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

	ieee80211_set_default_key(sdata, key_idx);
	ieee80211_set_default_key(sdata, key_idx, uni, multi);

	return 0;
}
+21 −16
Original line number Diff line number Diff line
@@ -274,7 +274,8 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
	debugfs_remove_recursive(key->debugfs.dir);
	key->debugfs.dir = NULL;
}
void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)

void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
{
	char buf[50];
	struct ieee80211_key *key;
@@ -282,25 +283,29 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
	if (!sdata->debugfs.dir)
		return;

	/* this is running under the key lock */
	lockdep_assert_held(&sdata->local->key_mtx);

	key = sdata->default_key;
	if (key) {
	if (sdata->default_unicast_key) {
		key = sdata->default_unicast_key;
		sprintf(buf, "../keys/%d", key->debugfs.cnt);
		sdata->debugfs.default_key =
			debugfs_create_symlink("default_key",
		sdata->debugfs.default_unicast_key =
			debugfs_create_symlink("default_unicast_key",
					       sdata->debugfs.dir, buf);
	} else
		ieee80211_debugfs_key_remove_default(sdata);
	} else {
		debugfs_remove(sdata->debugfs.default_unicast_key);
		sdata->debugfs.default_unicast_key = NULL;
	}

void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
{
	if (!sdata)
		return;

	debugfs_remove(sdata->debugfs.default_key);
	sdata->debugfs.default_key = NULL;
	if (sdata->default_multicast_key) {
		key = sdata->default_multicast_key;
		sprintf(buf, "../keys/%d", key->debugfs.cnt);
		sdata->debugfs.default_multicast_key =
			debugfs_create_symlink("default_multicast_key",
					       sdata->debugfs.dir, buf);
	} else {
		debugfs_remove(sdata->debugfs.default_multicast_key);
		sdata->debugfs.default_multicast_key = NULL;
	}
}

void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
+2 −6
Original line number Diff line number Diff line
@@ -4,8 +4,7 @@
#ifdef CONFIG_MAC80211_DEBUGFS
void ieee80211_debugfs_key_add(struct ieee80211_key *key);
void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_key_add_mgmt_default(
	struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_key_remove_mgmt_default(
@@ -17,10 +16,7 @@ static inline void ieee80211_debugfs_key_add(struct ieee80211_key *key)
{}
static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
{}
static inline void ieee80211_debugfs_key_add_default(
	struct ieee80211_sub_if_data *sdata)
{}
static inline void ieee80211_debugfs_key_remove_default(
static inline void ieee80211_debugfs_key_update_default(
	struct ieee80211_sub_if_data *sdata)
{}
static inline void ieee80211_debugfs_key_add_mgmt_default(
+3 −2
Original line number Diff line number Diff line
@@ -557,7 +557,7 @@ struct ieee80211_sub_if_data {
	unsigned int fragment_next;

	struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
	struct ieee80211_key *default_key;
	struct ieee80211_key *default_unicast_key, *default_multicast_key;
	struct ieee80211_key *default_mgmt_key;

	u16 sequence_number;
@@ -595,7 +595,8 @@ struct ieee80211_sub_if_data {
	struct {
		struct dentry *dir;
		struct dentry *subdir_stations;
		struct dentry *default_key;
		struct dentry *default_unicast_key;
		struct dentry *default_multicast_key;
		struct dentry *default_mgmt_key;
	} debugfs;
#endif
+26 −19
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
EXPORT_SYMBOL_GPL(ieee80211_key_removed);

static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
					int idx)
					int idx, bool uni, bool multi)
{
	struct ieee80211_key *key = NULL;

@@ -187,18 +187,19 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
	if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
		key = sdata->keys[idx];

	rcu_assign_pointer(sdata->default_key, key);
	if (uni)
		rcu_assign_pointer(sdata->default_unicast_key, key);
	if (multi)
		rcu_assign_pointer(sdata->default_multicast_key, key);

	if (key) {
		ieee80211_debugfs_key_remove_default(key->sdata);
		ieee80211_debugfs_key_add_default(key->sdata);
	}
	ieee80211_debugfs_key_update_default(sdata);
}

void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx)
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
			       bool uni, bool multi)
{
	mutex_lock(&sdata->local->key_mtx);
	__ieee80211_set_default_key(sdata, idx);
	__ieee80211_set_default_key(sdata, idx, uni, multi);
	mutex_unlock(&sdata->local->key_mtx);
}

@@ -215,10 +216,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)

	rcu_assign_pointer(sdata->default_mgmt_key, key);

	if (key) {
		ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
		ieee80211_debugfs_key_add_mgmt_default(key->sdata);
	}
	ieee80211_debugfs_key_update_default(sdata);
}

void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
@@ -236,7 +234,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
				    struct ieee80211_key *old,
				    struct ieee80211_key *new)
{
	int idx, defkey, defmgmtkey;
	int idx;
	bool defunikey, defmultikey, defmgmtkey;

	if (new)
		list_add(&new->list, &sdata->key_list);
@@ -257,17 +256,24 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
		else
			idx = new->conf.keyidx;

		defkey = old && sdata->default_key == old;
		defunikey = old && sdata->default_unicast_key == old;
		defmultikey = old && sdata->default_multicast_key == old;
		defmgmtkey = old && sdata->default_mgmt_key == old;

		if (defkey && !new)
			__ieee80211_set_default_key(sdata, -1);
		if (defunikey && !new)
			__ieee80211_set_default_key(sdata, -1, true, false);
		if (defmultikey && !new)
			__ieee80211_set_default_key(sdata, -1, false, true);
		if (defmgmtkey && !new)
			__ieee80211_set_default_mgmt_key(sdata, -1);

		rcu_assign_pointer(sdata->keys[idx], new);
		if (defkey && new)
			__ieee80211_set_default_key(sdata, new->conf.keyidx);
		if (defunikey && new)
			__ieee80211_set_default_key(sdata, new->conf.keyidx,
						    true, false);
		if (defmultikey && new)
			__ieee80211_set_default_key(sdata, new->conf.keyidx,
						    false, true);
		if (defmgmtkey && new)
			__ieee80211_set_default_mgmt_key(sdata,
							 new->conf.keyidx);
@@ -509,11 +515,12 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)

	mutex_lock(&sdata->local->key_mtx);

	ieee80211_debugfs_key_remove_default(sdata);
	ieee80211_debugfs_key_remove_mgmt_default(sdata);

	list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
		__ieee80211_key_free(key);

	ieee80211_debugfs_key_update_default(sdata);

	mutex_unlock(&sdata->local->key_mtx);
}
Loading