diff mbox

[RFC,2/2] nl80211: implement beacon change notifier

Message ID 20171109094024.9085-2-sergey.matyukevich.os@quantenna.com (mailing list archive)
State RFC
Delegated to: Johannes Berg
Headers show

Commit Message

Sergey Matyukevich Nov. 9, 2017, 9:40 a.m. UTC
From: Vasily Ulyanov <vulyanov@quantenna.com>

Notify user-space listeners about beacon data change.

Signed-off-by: Vasily Ulyanov <vulyanov@quantenna.com>
---
 net/wireless/nl80211.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

Comments

Johannes Berg Nov. 13, 2017, 9:30 a.m. UTC | #1
On Thu, 2017-11-09 at 12:40 +0300, Sergey Matyukevich wrote:
> From: Vasily Ulyanov <vulyanov@quantenna.com>
> 
> Notify user-space listeners about beacon data change.

What would this be needed for, and why couldn't you just directly talk
to hostapd/wpa_s?

johannes
Sergey Matyukevich Nov. 13, 2017, noon UTC | #2
Hello Johannes and all,

> > From: Vasily Ulyanov <vulyanov@quantenna.com>
> >
> > Notify user-space listeners about beacon data change.
> 
> What would this be needed for, and why couldn't you just directly talk
> to hostapd/wpa_s?

I apologize for email duplication, but it looks like reply from Vasily
has been rejected due to Outlook issues. While we choose between mutt
and gnus, here I briefly repeat the rationale behind these RFC patches.

The nl80211 get_beacon callback appears to be useful in the case when
userspace software needs to retrieve current operational parameters of
AP including HT/VHT IEs. In fact we considered two implementation options:
to implement this functionality either in hostapd (extending its
hostapd_cli interface) or in kernel (adding nl80211 call).

We decided to try nl80211 since there was a stub for NL80211_CMD_GET_BEACON
operation. Beacon change notifier was introduced due to the following reason:
if anyone is interested in AP operational params, then he might be also
interested to know when those params are changed.

Regards,
Sergey
Johannes Berg Nov. 13, 2017, 12:22 p.m. UTC | #3
Hi,

> I apologize for email duplication, but it looks like reply from Vasily
> has been rejected due to Outlook issues. While we choose between mutt
> and gnus, here I briefly repeat the rationale behind these RFC patches.

:)

> The nl80211 get_beacon callback appears to be useful in the case when
> userspace software needs to retrieve current operational parameters of
> AP including HT/VHT IEs.

Do you have any usage in mind though? I can't really see where this
would really make sense, rather than getting direct hooks for the bits
you needed in hostapd.

For example, if you care about the channel bandwidth changing, wouldn't
it be more efficient to just add a signal to hostapd rather than
listening to beacon updates and parsing, etc.?

johannes
Sergey Matyukevich Nov. 15, 2017, 3:35 p.m. UTC | #4
Hello Johannes,

> > The nl80211 get_beacon callback appears to be useful in the case when
> > userspace software needs to retrieve current operational parameters of
> > AP including HT/VHT IEs.
> 
> Do you have any usage in mind though? I can't really see where this
> would really make sense, rather than getting direct hooks for the bits
> you needed in hostapd.
> 
> For example, if you care about the channel bandwidth changing, wouldn't
> it be more efficient to just add a signal to hostapd rather than
> listening to beacon updates and parsing, etc.?

In our case, we are experimenting with applications running along with
hostapd and enabling band steering and client roaming functionality.
As I mentioned, various approaches are being examined, including
both pure nl80211-based approach as well as adding direct hooks
to hostapd.

Regards,
Sergey
Johannes Berg Nov. 27, 2017, 12:02 p.m. UTC | #5
On Wed, 2017-11-15 at 18:35 +0300, Sergey Matyukevich wrote:

> In our case, we are experimenting with applications running along with
> hostapd and enabling band steering and client roaming functionality.
> As I mentioned, various approaches are being examined, including
> both pure nl80211-based approach as well as adding direct hooks
> to hostapd.

To be honest, I'm torn on this.

On the one hand, I think it's fairly reasonable functionality, but on
the other hand I'm not sure we should encourage such separate
approaches - it seems to me that will lead to a lot of fragmentation
and much harder debuggability for upstream where these things get used.

It's also a bunch of code we have to maintain, for nothing that seems
of use to the community - since it's the sort of flexibility explicitly
designed for non-public code (otherwise it could just be part of
hostapd; actually it could even if it were non-public, at least in
theory, unless you're planning it as a value-add thing to go with an
open source hostapd ...).

So while I don't want to stop you entirely in your tracks with this,
I'd really prefer you explore other options regarding where to put your
client steering functionality, perhaps even working on hostapd.

johannes
Sergey Matyukevich Dec. 5, 2017, 8:31 p.m. UTC | #6
Hello Johannes,

> > In our case, we are experimenting with applications running along with
> > hostapd and enabling band steering and client roaming functionality.
> > As I mentioned, various approaches are being examined, including
> > both pure nl80211-based approach as well as adding direct hooks
> > to hostapd.
> 
> To be honest, I'm torn on this.
> 
> On the one hand, I think it's fairly reasonable functionality, but on
> the other hand I'm not sure we should encourage such separate
> approaches - it seems to me that will lead to a lot of fragmentation
> and much harder debuggability for upstream where these things get used.
> 
> It's also a bunch of code we have to maintain, for nothing that seems
> of use to the community - since it's the sort of flexibility explicitly
> designed for non-public code (otherwise it could just be part of
> hostapd; actually it could even if it were non-public, at least in
> theory, unless you're planning it as a value-add thing to go with an
> open source hostapd ...).
> 
> So while I don't want to stop you entirely in your tracks with this,
> I'd really prefer you explore other options regarding where to put your
> client steering functionality, perhaps even working on hostapd.

Well, our preferred approach for these experiments is going to be
communication with hostapd instead of kernel. One of the reasons
is that GET_CMD_BEACON is not enough. We have to enable multiple
listeners of mgmt frames as well. However that feature was rejected
earlier this year: https://patchwork.kernel.org/patch/9615697

By the way, speaking about GET_CMD_BEACON and its possible users in the
community. There is already a stub for it in nl80211 uapi headers. What
was the original idea for that ? Or was it just a placeholder added
together with SET_BEACON ?

Regards,
Sergey
Johannes Berg Dec. 19, 2017, 5 p.m. UTC | #7
Hi Sergey,

Sorry for the long delay.

On Tue, 2017-12-05 at 23:31 +0300, Sergey Matyukevich wrote:
> 
> By the way, speaking about GET_CMD_BEACON and its possible users in the
> community. There is already a stub for it in nl80211 uapi headers. What
> was the original idea for that ? Or was it just a placeholder added
> together with SET_BEACON ?

I think it was a placeholder, you can probably find it in git history.
I vaguely remember thinking - many years ago - that all the operations
should consistently support add, del, set and get, but that isn't
really all that practical.

johannes
diff mbox

Patch

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f03f9989efbc..98e52e5ffc13 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3950,6 +3950,26 @@  static int nl80211_send_beacon(struct sk_buff *msg, u32 portid,
 	return -EMSGSIZE;
 }
 
+static void nl80211_notify_beacon_change(struct net_device *dev,
+					 enum nl80211_commands cmd,
+					 struct cfg80211_beacon_data *bcn)
+{
+	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct sk_buff *msg;
+
+	msg = nlmsg_new(nl80211_beacon_size(bcn), GFP_KERNEL);
+	if (!msg)
+		return;
+
+	if (nl80211_send_beacon(msg, cmd, 0, 0, 0, bcn) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
+				NL80211_MCGRP_MLME, GFP_KERNEL);
+}
+
 static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
 					    const u8 *rates)
 {
@@ -4250,6 +4270,8 @@  static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 		wdev->ssid_len = params.ssid_len;
 		memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
 		nl80211_assign_beacon(&wdev->beacon, &new_bcn);
+		nl80211_notify_beacon_change(dev, NL80211_CMD_START_AP,
+					     &wdev->beacon);
 	}
 	wdev_unlock(wdev);
 
@@ -4317,8 +4339,11 @@  static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
 
 	wdev_lock(wdev);
 	err = rdev_change_beacon(rdev, dev, &params);
-	if (!err)
+	if (!err) {
 		nl80211_assign_beacon(&wdev->beacon, &merged_bcn);
+		nl80211_notify_beacon_change(dev, NL80211_CMD_SET_BEACON,
+					     &wdev->beacon);
+	}
 	wdev_unlock(wdev);
 
 	if (err)