Search Linux Wireless

Re: [PATCH v7 1/2] wifi: cfg80211: Add short_beacon_tail/head/period

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2023-08-10 at 19:35 +1000, Bassem Dawood wrote:
> From: Kieran Frewen <kieran.frewen@xxxxxxxxxxxxxx>
> 
> Support variables to handle short beacon period and adding a
> separate tail/head for them. Also, add short beacon period,
> head and tail attributes for user configuration.

So I'm confused by this commit - maybe the commit log should have more
words ;-)

> +++ b/include/net/cfg80211.h
> @@ -1211,8 +1211,13 @@ struct cfg80211_rnr_elems {
>   *	or %NULL if not changed
>   * @tail: tail portion of beacon (after TIM IE)
>   *	or %NULL if not changed
> + * @short_head: head portion of short beacon or %NULL if not changed
> + * @short_tail: short tail portion of beacon (after TIM IE)
> + *	or %NULL if not changed
>   * @head_len: length of @head
>   * @tail_len: length of @tail
> + * @short_head_len: length of @short_head
> + * @short_tail_len: length of @short_tail
>   * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL
>   * @beacon_ies_len: length of beacon_ies in octets
>   * @proberesp_ies: extra information element(s) to add into Probe Response
> @@ -1241,6 +1246,7 @@ struct cfg80211_beacon_data {
>  	unsigned int link_id;
>  
>  	const u8 *head, *tail;
> +	const u8 *short_head, *short_tail;

All of this makes me think that for S1G you need _both_ short and
regular beacons. Similar to what FILS discovery frames did elsewhere.
Which makes a lot of sense, I guess, though arguably we could go the
route that FILS did, with "fils_discovery" in struct
cfg80211_ap_settings. See also Aloka's recent commits, which now pass
the whole struct on updates, though I'm thinking we might change that
again:

https://lore.kernel.org/linux-wireless/1912863dcd17aa50b09d1ddfc889478eb323f901.camel@xxxxxxxxxxxxxxxx/T/#m86511f184d40ab36221f4ceae066900233ceb84e

However, then we have this:

> +++ b/net/wireless/nl80211.c
> @@ -230,13 +230,19 @@ static int validate_beacon_head(const struct nlattr *attr,
>  	const struct element *elem;
>  	const struct ieee80211_mgmt *mgmt = (void *)data;
>  	unsigned int fixedlen, hdrlen;
> -	bool s1g_bcn;
> +	bool s1g_bcn = false;
> +	bool s1g_short_bcn = false;
>  
>  	if (len < offsetofend(typeof(*mgmt), frame_control))
>  		goto err;
>  
>  	s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control);
> -	if (s1g_bcn) {
> +	s1g_short_bcn = ieee80211_is_s1g_short_beacon(mgmt->frame_control);
> +	if (s1g_short_bcn) {
> +		fixedlen = offsetof(struct ieee80211_ext,
> +				    u.s1g_short_beacon.variable);
> +		hdrlen = offsetof(struct ieee80211_ext, u.s1g_short_beacon);
> +	} else if (s1g_bcn) {

which all makes it look like you can put a short beacon into
NL80211_ATTR_BEACON_HEAD, but that _shouldn't_ be true?

So maybe this was just a (bad) shortcut, and you really should refactor
this function into two (that can call some common code, of course) that
gets put into the policy?

Because detecting which kind of beacon you get passed rather than
validating that you get passed the right type isn't really validation,
I'd think?

Never mind that the 

> 	if (len < offsetofend(typeof(*mgmt), frame_control))

check is probably somewhat wrong anyway? Or, well, no it's not wrong
because you're checking for 2 bytes anyway, but it reads wrong because
you're checking typeof(*mgmt) which is mgmt, not ext ...

Put some kind of comment/BUILD_BUG at least? But if it's split, maybe it
won't be needed, depends how you split it.

>  	if (attrs[NL80211_ATTR_BEACON_HEAD]) {
> +		struct ieee80211_mgmt *mgmt;
> +
>  		bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
>  		bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
>  		if (!bcn->head_len)
>  			return -EINVAL;
> +
> +		mgmt = (void *)bcn->head;
> +		if (ieee80211_is_s1g_beacon(mgmt->frame_control) && !is_s1g_band)
> +			return -EINVAL;
> +		else if (ieee80211_is_beacon(mgmt->frame_control) && is_s1g_band)
> +			return -EINVAL;

But then again ... here you _do_ allow an S1G beacon in the
NL80211_ATTR_BEACON_HEAD, so I'm even more confused ...

Hmm.

I guess maybe you have long and short beacons, but they're _both_ ext
format? Really the comments/commit messages/etc. could make all that
clearer for all those who are not intimately familiar with the S1G spec.

> @@ -5944,6 +6002,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
>  		nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
>  	params->dtim_period =
>  		nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
> +	params->short_beacon_period = 1;
> +	if (info->attrs[NL80211_ATTR_SHORT_BEACON_PERIOD])
> +		params->short_beacon_period =
> +			nla_get_u16(info->attrs[NL80211_ATTR_SHORT_BEACON_PERIOD]);

Probably should reject that too on !s1g_band, and why is the default
value 1? Your documentation doesn't even say what unit it is:

> + * @NL80211_ATTR_SHORT_BEACON_PERIOD: (u16) period for S1G long beacon

(and it also talks about long beacon which is probably not right)

So I'd think it's also in TU, but then 1 doesn't make any sense...

> @@ -6237,7 +6284,8 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
>  	if (!wdev->links[link_id].ap.beacon_interval)
>  		return -EINVAL;
>  
> -	err = nl80211_parse_beacon(rdev, info->attrs, &params, info->extack);
> +	err = nl80211_parse_beacon(rdev, info->attrs, &params, info->extack,
> +		wdev->links[link_id].ap.chandef.chan->band == NL80211_BAND_S1GHZ);

Unrelated, but somewhere in here I hope we don't allow S1G and MLO to
coexist ... :-)

(So link_id should always be 0 for S1G here.)

johannes




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux