diff mbox series

[v4] nl80211: reset regdom when reloading regdb

Message ID 20210526112418.cdwkn7ed4twctimc@imap.mailbox.org (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show
Series [v4] nl80211: reset regdom when reloading regdb | expand

Commit Message

Fiona Behrens Nov. 13, 2021, 10:54 a.m. UTC
this reloads the regdom when the regulatory db is reloaded.
Without this patch the user had to change the regulatoy domain to a
different, and then reset it to the one the user is in, to have the new
regulatory db take effect

Signed-off-by: Finn Behrens <fin@nyantec.com>
---
Sorry for taking so long for a new version. The mail provider my company
is using had some major problems connecting to the LKML.
This is why I now are using my personal mail server.

 include/net/regulatory.h |  1 +
 net/wireless/reg.c       | 26 +++++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

Comments

Johannes Berg Nov. 26, 2021, 12:08 p.m. UTC | #1
Hi,

> Sorry for taking so long for a new version. The mail provider my company
> is using had some major problems connecting to the LKML.
> This is why I now are using my personal mail server.


Did you resend this? Did I lose it before? Or maybe the list lost it and
I had a copy? Confusing ...

But anyway:

> @@ -1113,6 +1116,26 @@ int reg_reload_regdb(void)
>  	regdb = db;
>  	rtnl_unlock();
>  
> +	/* reset regulatory domain */
> +	current_regdomain = get_cfg80211_regdom();


This really is just

	rcu_dereference_rtnl(cfg80211_regdomain);

so it cannot be right that you just unlocked the RTNL and are not under
RCU protection here?

I guess we can just keep the RTNL, since ...


> +	request = kzalloc(sizeof(*request), GFP_KERNEL);
> +	if (!request) {
> +		err = -ENOMEM;
> +		goto out;
> +	}
> +
> +	request->wiphy_idx = WIPHY_IDX_INVALID;
> +	request->alpha2[0] = current_regdomain->alpha2[0];
> +	request->alpha2[1] = current_regdomain->alpha2[1];
> +	request->initiator = NL80211_USER_REG_HINT_USER;
> +	request->user_reg_hint_type = NL80211_USER_REG_HINT_USER;
> +	request->reload = true;
> +
> +	rtnl_lock();

we acquire it again here anyway? Just need a new

> +	reg_process_hint(request);

out_unlock:
> +	rtnl_unlock();

label there.

> 
> @@ -2683,7 +2706,8 @@ reg_process_hint_user(struct regulatory_request *user_request)
>  
>  	treatment = __reg_process_hint_user(user_request);
>  	if (treatment == REG_REQ_IGNORE ||
> -	    treatment == REG_REQ_ALREADY_SET)
> +	    (treatment == REG_REQ_ALREADY_SET &&
> +				!user_request->reload))
>  		return REG_REQ_IGNORE;

That could use some nicer indentation :)

johannes
diff mbox series

Patch

diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index 47f06f6f5a67..0cf9335431e0 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -83,6 +83,7 @@  struct regulatory_request {
 	enum nl80211_dfs_regions dfs_region;
 	bool intersect;
 	bool processed;
+	bool reload;
 	enum environment_cap country_ie_env;
 	struct list_head list;
 };
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 0406ce7334fa..3460c0e75c6d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -133,6 +133,7 @@  static u32 reg_is_indoor_portid;
 
 static void restore_regulatory_settings(bool reset_user, bool cached);
 static void print_regdomain(const struct ieee80211_regdomain *rd);
+static void reg_process_hint(struct regulatory_request *reg_request);
 
 static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
 {
@@ -1091,6 +1092,8 @@  int reg_reload_regdb(void)
 	const struct firmware *fw;
 	void *db;
 	int err;
+	const struct ieee80211_regdomain *current_regdomain;
+	struct regulatory_request *request;
 
 	err = request_firmware(&fw, "regulatory.db", &reg_pdev->dev);
 	if (err)
@@ -1113,6 +1116,26 @@  int reg_reload_regdb(void)
 	regdb = db;
 	rtnl_unlock();
 
+	/* reset regulatory domain */
+	current_regdomain = get_cfg80211_regdom();
+
+	request = kzalloc(sizeof(*request), GFP_KERNEL);
+	if (!request) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	request->wiphy_idx = WIPHY_IDX_INVALID;
+	request->alpha2[0] = current_regdomain->alpha2[0];
+	request->alpha2[1] = current_regdomain->alpha2[1];
+	request->initiator = NL80211_USER_REG_HINT_USER;
+	request->user_reg_hint_type = NL80211_USER_REG_HINT_USER;
+	request->reload = true;
+
+	rtnl_lock();
+	reg_process_hint(request);
+	rtnl_unlock();
+
  out:
 	release_firmware(fw);
 	return err;
@@ -2683,7 +2706,8 @@  reg_process_hint_user(struct regulatory_request *user_request)
 
 	treatment = __reg_process_hint_user(user_request);
 	if (treatment == REG_REQ_IGNORE ||
-	    treatment == REG_REQ_ALREADY_SET)
+	    (treatment == REG_REQ_ALREADY_SET &&
+				!user_request->reload))
 		return REG_REQ_IGNORE;
 
 	user_request->intersect = treatment == REG_REQ_INTERSECT;