linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Alvin Šipraga" <alvin@pqrs.dk>
To: Johannes Berg <johannes@sipsolutions.net>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: "Alvin Šipraga" <alsi@bang-olufsen.dk>,
	linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH v2 next 1/2] wifi: nl80211: emit CMD_START_AP on multicast group when an AP is started
Date: Sat, 28 Jan 2023 13:58:43 +0100	[thread overview]
Message-ID: <20230128125844.2407135-1-alvin@pqrs.dk> (raw)

From: Alvin Šipraga <alsi@bang-olufsen.dk>

Userspace processes such as network daemons may wish to be informed when
any AP interface is brought up on the system, for example to initiate a
(re)configuration of IP settings or to start a DHCP server.

Currently nl80211 does not broadcast any such event on its multicast
groups, leaving userspace only two options:

1. the process must be the one that actually issued the
   NL80211_CMD_START_AP request, so that it can react on the response to
   that request;

2. the process must react to RTM_NEWLINK events indicating a change in
   carrier state, and may query for further information about the AP and
   react accordingly.

Option (1) is robust, but it does not cover all scenarios. It is easy to
imagine a situation where this is not the case (e.g. hostapd +
systemd-networkd).

Option (2) is not robust, because RTM_NEWLINK events may be silently
discarded by the linkwatch logic (cf. linkwatch_fire_event()).
Concretely, consider a scenario in which the carrier state flip-flops in
the following way:

 ^ carrier state (high/low = carrier/no carrier)
 |
 |        _______      _______ ...
 |       |       |    |
 | ______| "foo" |____| "bar"             (SSID in "quotes")
 |
 +-------A-------B----C---------> time

If the time interval between (A) and (C) is less than 1 second, then
linkwatch may emit only a single RTM_NEWLINK event indicating carrier
gain.

This is problematic because it is possible that the network
configuration that should be applied is a function of the AP's
properties such as SSID (cf. SSID= in systemd.network(5)). As
illustrated in the above diagram, it may be that the AP with SSID "bar"
ends up being configured as though it had SSID "foo".

Address the above issue by having nl80211 emit an NL80211_CMD_START_AP
message on the MLME nl80211 multicast group. This allows for arbitrary
processes to be reliably informed.

Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
---
v1 -> v2: add MLO link ID to the event per Johannes' comments
---
 net/wireless/nl80211.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 64cf6110ce9d..7370ddf84fd3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5770,6 +5770,42 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
 	}
 }
 
+static void nl80211_send_ap_started(struct wireless_dev *wdev,
+				    unsigned int link_id)
+{
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_START_AP);
+	if (!hdr)
+		goto out;
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
+	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+			      NL80211_ATTR_PAD) ||
+	    (wdev->u.ap.ssid_len &&
+	     nla_put(msg, NL80211_ATTR_SSID, wdev->u.ap.ssid_len,
+		     wdev->u.ap.ssid)) ||
+	    (wdev->valid_links &&
+	     nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)))
+		goto out;
+
+	genlmsg_end(msg, hdr);
+
+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
+				NL80211_MCGRP_MLME, GFP_KERNEL);
+	return;
+out:
+	nlmsg_free(msg);
+}
+
 static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6050,6 +6086,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 
 		if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
 			wdev->conn_owner_nlportid = info->snd_portid;
+
+		nl80211_send_ap_started(wdev, link_id);
 	}
 out_unlock:
 	wdev_unlock(wdev);
-- 
2.39.0


             reply	other threads:[~2023-01-28 12:59 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-28 12:58 Alvin Šipraga [this message]
2023-01-28 12:58 ` [PATCH v2 next 2/2] wifi: nl80211: add MLO_LINK_ID to CMD_STOP_AP event Alvin Šipraga

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230128125844.2407135-1-alvin@pqrs.dk \
    --to=alvin@pqrs.dk \
    --cc=alsi@bang-olufsen.dk \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=johannes@sipsolutions.net \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).