mac80211: introduce MBSSID support in AP mode
v14 cover mac80211: introduce MBSSID support in AP mode
Changes since v13:
- remove EWMA support since mt7915 does not support it
- fix OOB issue in ieee80211_assign_beacon/cfg80211_beacon_dup accessing new->mbssid_ies
- fix concurrency issue accessing beacon_data->mbssid_ies in ieee80211_assign_beacon() and ieee80211_beacon_get_template()
- fix locking issue ieee80211_csa_finish
John Crispin (1):
mac80211: MBSSID channel switch
Lorenzo Bianconi (2):
mac80211: MBSSID beacon handling in AP mode
mac80211: update bssid_indicator in ieee80211_assign_beacon
include/net/mac80211.h | 2 + net/mac80211/cfg.c | 128 +++++++++++++++++++++++++++++++++---- net/mac80211/ieee80211_i.h | 15 +++++ net/mac80211/tx.c | 24 ++++++- 4 files changed, 153 insertions(+), 16 deletions(-)
Signature · 1 line
2.35.1
PATCH v14 1/3 mac80211: MBSSID beacon handling in AP mode
Add new fields in struct beacon_data to store all MBSSID elements. Generate a beacon template which includes all MBSSID elements. Move CSA offset to reflect the MBSSID element length.
--- include/net/mac80211.h | 2 + net/mac80211/cfg.c | 99 +++++++++++++++++++++++++++++++++----- net/mac80211/ieee80211_i.h | 15 ++++++ net/mac80211/tx.c | 24 ++++++++- 4 files changed, 126 insertions(+), 14 deletions(-)
include/net/mac80211.h +2 -0
@@ -4931,12 +4931,14 @@ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets);* @cntdwn_counter_offs: array of IEEE80211_MAX_CNTDWN_COUNTERS_NUM offsets * to countdown counters. This array can contain zero values which * should be ignored. +* @mbssid_off: position of the multiple bssid element */ struct ieee80211_mutable_offsets {u16 tim_offset;u16 tim_length;u16 cntdwn_counter_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM ]; +u16 mbssid_off; };/**
net/mac80211/cfg.c +87 -12
190 lines not on this page · raw message
net/mac80211/ieee80211_i.h +15 -0
@@ -257,6 +257,7 @@ struct beacon_data {struct ieee80211_meshconf_ie *meshconf;u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM ];u8 cntdwn_current_counter; +struct cfg80211_mbssid_elems *mbssid_ies;struct rcu_head rcu_head; };
@@ -1078,6 +1079,20 @@ ieee80211_vif_get_shift(struct ieee80211_vif *vif)return shift; } +static inline int +ieee80211_get_mbssid_beacon_len (struct cfg80211_mbssid_elems *elems) +{ +int i, len =0 ; + +if (!elems) +return 0 ; + +for (i =0 ; i < elems->cnt; i++) + len += elems->elem[i].len; + +return len; +} +enum {IEEE80211_RX_MSG =1 ,IEEE80211_TX_STATUS_MSG =2 ,
net/mac80211/tx.c +22 -2
@@ -5042,6 +5042,19 @@ ieee80211_beacon_get_finish(struct ieee80211_hw *hw,IEEE80211_TX_CTL_FIRST_FRAGMENT ; } +static void +ieee80211_beacon_add_mbssid (struct sk_buff *skb,struct beacon_data *beacon) +{ +int i; + +if (!beacon->mbssid_ies) +return ; + +for (i =0 ; i < beacon->mbssid_ies->cnt; i++) +skb_put_data (skb, beacon->mbssid_ies->elem[i].data, + beacon->mbssid_ies->elem[i].len); +} +static struct sk_buff * ieee80211_beacon_get_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -5055,6 +5068,7 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw,struct ieee80211_if_ap *ap = &sdata->u.ap;struct sk_buff *skb =NULL ;u16 csa_off_base =0 ; +int mbssid_len;if (beacon->cntdwn_counter_offsets[0 ]) {if (!is_template)
@@ -5064,11 +5078,12 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw, }/* headroom, head length, -* tail length and maximum TIM length +* tail length, maximum TIM length and multiple BSSID length */ + mbssid_len =ieee80211_get_mbssid_beacon_len (beacon->mbssid_ies); skb =dev_alloc_skb (local->tx_headroom + beacon->head_len + beacon->tail_len +256 + - local->hw.extra_beacon_tailroom); + local->hw.extra_beacon_tailroom + mbssid_len);if (!skb)return NULL ;
@@ -5082,6 +5097,11 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw, offs->tim_length = skb->len - beacon->head_len; offs->cntdwn_counter_offs[0 ] = beacon->cntdwn_counter_offsets[0 ]; +if (mbssid_len) { +ieee80211_beacon_add_mbssid (skb, beacon); + offs->mbssid_off = skb->len - mbssid_len; + } +/* for AP the csa offsets are from tail */ csa_off_base = skb->len; }
Signature · 1 line
2.35.1
PATCH v14 2/3 mac80211: MBSSID channel switch
In reply to Lorenzo BianconiFrom: John Crispin <[email protected]>
Trigger ieee80211_csa_finish() on the non-transmitting interfaces when channel switch concludes on the transmitting interface.
--- net/mac80211/cfg.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
net/mac80211/cfg.c +24 -2
@@ -3251,9 +3251,31 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)void ieee80211_csa_finish (struct ieee80211_vif *vif) {struct ieee80211_sub_if_data *sdata =vif_to_sdata (vif); +struct ieee80211_local *local = sdata->local; -ieee80211_queue_work (&sdata->local->hw, - &sdata->csa_finalize_work); +rcu_read_lock (); + +if (vif->mbssid_tx_vif == vif) { +/* Trigger ieee80211_csa_finish() on the non-transmitting +* interfaces when channel switch is received on +* transmitting interface +*/ +struct ieee80211_sub_if_data *iter; + +list_for_each_entry_rcu (iter, &local->interfaces, list) { +if (!ieee80211_sdata_running (iter)) +continue ; + +if (iter == sdata || iter->vif.mbssid_tx_vif != vif) +continue ; + +ieee80211_queue_work (&iter->local->hw, + &iter->csa_finalize_work); + } + } +ieee80211_queue_work (&local->hw, &sdata->csa_finalize_work); + +rcu_read_unlock (); }EXPORT_SYMBOL (ieee80211_csa_finish);
Signature · 1 line
2.35.1
PATCH v14 3/3 mac80211: update bssid_indicator in ieee80211_assign_beacon
In reply to Lorenzo BianconiUpdate bssid_indicator in ieee80211_bss_conf according to the number of bssid in the set.
--- net/mac80211/cfg.c | 3 +++ 1 file changed, 3 insertions(+)
net/mac80211/cfg.c +3 -0
@@ -1071,6 +1071,9 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, new->mbssid_ies = (struct cfg80211_mbssid_elems *)pos; pos +=struct_size (new->mbssid_ies, elem, mbssid->cnt);ieee80211_copy_mbssid_beacon (pos, new->mbssid_ies, mbssid); +/* update bssid_indicator */ + sdata->vif.bss_conf.bssid_indicator = +ilog2 (__roundup_pow_of_two (mbssid->cnt +1 )); }if (csa) {
Signature · 1 line
2.35.1
Re: [PATCH v14 mac80211-next 1/3] mac80211: MBSSID beacon handling in AP mode
In reply to Lorenzo BianconiQuoted 4 lines · Lorenzo Bianconi
Add new fields in struct
beacon_datato store all MBSSID elements. Generate a beacon template which includes all MBSSID elements. Move CSA offset to reflect the MBSSID element length.
Quoted 376 lines
Co-developed-by Aloka Dixit <[email protected]>Signed-off-by Aloka Dixit <[email protected]>Co-developed-by John Crispin <[email protected]>Signed-off-by John Crispin <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- include/net/mac80211.h | 2 + net/mac80211/cfg.c | 99 +++++++++++++++++++++++++++++++++--- -- net/mac80211/ieee80211_i.h | 15 ++++++ net/mac80211/tx.c | 24 ++++++++- 4 files changed, 126 insertions(+), 14 deletions(-)include/net/mac80211.h +0
-0@@ -4931,12 +4931,14 @@ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets); * @cntdwn_counter_offs: array of IEEE80211_MAX_CNTDWN_COUNTERS_NUMoffsets
* to countdown counters. This array can contain zero values
which
* should be ignored.
+ * @mbssid_off: position of the multiple bssid element */
structieee80211_mutable_offsets{include/net/mac80211.h +1
-0u16 tim_offset;u16 tim_length;u16 cntdwn_counter_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM ]; +u16 mbssid_off; };/** net/mac80211/cfg.c +17
-0@@ -989,11 +989,29 @@ static int ieee80211_set_ftm_responder_params(return 0 ; } +static int +ieee80211_copy_mbssid_beacon (u8 *pos,struct cfg80211_mbssid_elems *dst, +struct cfg80211_mbssid_elems *src) +{ +int i, offset =0 ; + +for (i =0 ; i < src->cnt; i++) { +memcpy (pos + offset, src->elem[i].data, src- >elem[i].len); + dst->elem[i].len = src->elem[i].len; + dst->elem[i].data = pos + offset; + offset += dst->elem[i].len; + } + dst->cnt = src->cnt; + +return offset; +} + static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, struct cfg80211_beacon_data *params, const struct ieee80211_csa_settings *csa, const struct
ieee80211_color_change_settings*cca)
{net/mac80211/cfg.c +12
-0+struct cfg80211_mbssid_elems *mbssid =NULL ;struct beacon_data *new, *old;int new_head_len, new_tail_len;int size, err;@@ -1019,8 +1037,19 @@ static int ieee80211_assign_beacon(structieee80211_sub_if_data *sdata, else new_tail_len = old->tail_len; +/* new or old multiple BSSID elements? */ size =sizeof (*new) + new_head_len + new_tail_len; +if (params->mbssid_ies) { + mbssid = params->mbssid_ies; + size +=struct_size (new->mbssid_ies, elem, mbssid- >cnt); + size +=ieee80211_get_mbssid_beacon_len (mbssid); + }else if (old && old->mbssid_ies) { + mbssid = old->mbssid_ies; + size +=struct_size (new->mbssid_ies, elem, mbssid- >cnt); + size +=ieee80211_get_mbssid_beacon_len (mbssid); + } +net/mac80211/cfg.c +9
-1new =kzalloc (size,GFP_KERNEL );if (!new)return -ENOMEM ;@@ -1029,12 +1058,20 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,/* * pointers go into the block we allocated, -* memory is | beacon_data | head | tail | +* memory is | beacon_data | head | tail | mbssid_ies */ new->head = ((u8 *) new) +sizeof (*new); new->tail = new->head + new_head_len; new->head_len = new_head_len; new->tail_len = new_tail_len; +/* copy in optional mbssid_ies */ +if (mbssid) { +u8 *pos = new->tail + new->tail_len; + + new->mbssid_ies = (struct cfg80211_mbssid_elems *)pos; + pos +=struct_size (new->mbssid_ies, elem, mbssid->cnt); +ieee80211_copy_mbssid_beacon (pos, new->mbssid_ies, mbssid); + }net/mac80211/cfg.c +5
-2if (csa) { new->cntdwn_current_counter = csa->count;@@ -1332,8 +1369,11 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)mutex_unlock (&local->mtx); -kfree (sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon =NULL ; +if (sdata->u.ap.next_beacon) { +kfree (sdata->u.ap.next_beacon->mbssid_ies); +kfree (sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon =NULL ; + }/* turn off carrier for this interface and dependent VLANs */ net/mac80211/cfg.c +0
-0list_for_each_entry (vlan, &sdata->u.ap.vlans, u.vlan.list)@@ -3130,12 +3170,24 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon) len = beacon->head_len + beacon->tail_len + beacon-Quoted 1 line
beacon_ies_len+net/mac80211/cfg.c +0
-1beacon->proberesp_ies_len + beacon->assocresp_ies_len + - beacon->probe_resp_len + beacon->lci_len + beacon-Quoted 1 line
civicloc_len;net/mac80211/cfg.c +1
-0+ beacon->probe_resp_len + beacon->lci_len + beacon-Quoted 1 line
civicloc_len+net/mac80211/cfg.c +5
-0+ieee80211_get_mbssid_beacon_len (beacon->mbssid_ies); new_beacon =kzalloc (sizeof (*new_beacon) + len,GFP_KERNEL );if (!new_beacon)return NULL ; +if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { + new_beacon->mbssid_ies = + kzalloc(struct_size(new_beacon->mbssid_ies, + elem, beacon->mbssid_ies-Quoted 1 line
cnt),
net/mac80211/cfg.c +11
-0+ GFP_KERNEL); +if (!new_beacon->mbssid_ies) { +kfree (new_beacon); +return NULL ; + } + } + pos = (u8 *)(new_beacon +1 );if (beacon->head_len) { new_beacon->head_len = beacon->head_len;@@ -3173,6 +3225,10 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon) memcpy(pos, beacon->probe_resp, beacon- >probe_resp_len); pos += beacon->probe_resp_len; } +if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) + pos += ieee80211_copy_mbssid_beacon(pos, + new_beacon- >mbssid_ies, + beacon-Quoted 1 line
mbssid_ies);net/mac80211/cfg.c +5
-2/* might copy -1, meaning no changes requested */ new_beacon->ftm_responder = beacon->ftm_responder;@@ -3222,8 +3278,11 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP: err =ieee80211_assign_beacon (sdata, sdata- >u.ap.next_beacon,NULL ,NULL ); -kfree (sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon =NULL ; +if (sdata->u.ap.next_beacon) { +kfree (sdata->u.ap.next_beacon->mbssid_ies); +kfree (sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon =NULL ; + }net/mac80211/cfg.c +5
-1if (err <0 )return err;@@ -3378,8 +3437,12 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata, if ((params->n_counter_offsets_beacon >IEEE80211_MAX_CNTDWN_COUNTERS_NUM ) || (params->n_counter_offsets_presp > -IEEE80211_MAX_CNTDWN_COUNTERS_NUM )) + IEEE80211_MAX_CNTDWN_COUNTERS_NUM)) { +kfree (sdata->u.ap.next_beacon->mbssid_ies); +kfree (sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon =NULL ;return -EINVAL ; + } csa.counter_offsets_beacon = params-Quoted 1 line
counter_offsets_beacon;csa.counter_offsets_presp = params-
Quoted 1 line
counter_offsets_presp;net/mac80211/cfg.c +2
-0@@ -3389,7 +3452,9 @@ static int ieee80211_set_csa_beacon(structieee80211_sub_if_data *sdata, err =ieee80211_assign_beacon (sdata, ¶ms- >beacon_csa, &csa, NULL);if (err <0 ) { +kfree (sdata->u.ap.next_beacon->mbssid_ies);kfree (sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon =NULL ;return err;net/mac80211/cfg.c +5
-2} *changed |= err;@@ -3479,8 +3544,11 @@ static int ieee80211_set_csa_beacon(structieee80211_sub_if_data *sdata, static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata) { sdata->vif.color_change_active = false; -kfree (sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon =NULL ; +if (sdata->u.ap.next_beacon) { +kfree (sdata->u.ap.next_beacon->mbssid_ies); +kfree (sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon =NULL ; + }net/mac80211/cfg.c +5
-2cfg80211_color_change_aborted_notify (sdata->dev); }@@ -4218,8 +4286,11 @@ ieee80211_set_after_color_change_beacon(structieee80211_sub_if_data *sdata, ret =ieee80211_assign_beacon (sdata, sdata- >u.ap.next_beacon,NULL ,NULL ); -kfree (sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon =NULL ; +if (sdata->u.ap.next_beacon) { +kfree (sdata->u.ap.next_beacon->mbssid_ies); +kfree (sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon =NULL ; + }net/mac80211/cfg.c +5
-1if (ret <0 )return ret;@@ -4262,7 +4333,11 @@ ieee80211_set_color_change_beacon(structieee80211_sub_if_data *sdata, err =ieee80211_assign_beacon (sdata, ¶ms- >beacon_color_change,NULL , &color_change);if (err <0 ) { -kfree (sdata->u.ap.next_beacon); +if (sdata->u.ap.next_beacon) { +kfree (sdata->u.ap.next_beacon- >mbssid_ies); +kfree (sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon =NULL ; + }net/mac80211/cfg.c +0
-0return err; } *changed |= err;net/mac80211/ieee80211_i.h +15
-0@@ -257,6 +257,7 @@ struct beacon_data {struct ieee80211_meshconf_ie *meshconf;u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM ];u8 cntdwn_current_counter; +struct cfg80211_mbssid_elems *mbssid_ies;struct rcu_head rcu_head; };@@ -1078,6 +1079,20 @@ ieee80211_vif_get_shift(struct ieee80211_vif *vif)return shift; } +static inline int +ieee80211_get_mbssid_beacon_len (struct cfg80211_mbssid_elems *elems) +{ +int i, len =0 ; + +if (!elems) +return 0 ; + +for (i =0 ; i < elems->cnt; i++) + len += elems->elem[i].len; + +return len; +} +enum {IEEE80211_RX_MSG =1 ,net/mac80211/ieee80211_i.h +0
-0IEEE80211_TX_STATUS_MSG = 2,net/mac80211/tx.c +13
-0@@ -5042,6 +5042,19 @@ ieee80211_beacon_get_finish(structieee80211_hw *hw,IEEE80211_TX_CTL_FIRST_FRAGMENT ; } +static void +ieee80211_beacon_add_mbssid (struct sk_buff *skb,struct beacon_data *beacon) +{ +int i; + +if (!beacon->mbssid_ies) +return ; + +for (i =0 ; i < beacon->mbssid_ies->cnt; i++) +skb_put_data (skb, beacon->mbssid_ies->elem[i].data, + beacon->mbssid_ies->elem[i].len); +} + static struct sk_buff *ieee80211_beacon_get_ap(struct
ieee80211_hw*hw,net/mac80211/tx.c +1
-0struct ieee80211_vif *vif,@@ -5055,6 +5068,7 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw, struct ieee80211_if_ap *ap = &sdata->u.ap;struct sk_buff *skb =NULL ;u16 csa_off_base =0 ; +int mbssid_len;if (beacon->cntdwn_counter_offsets[0 ]) {net/mac80211/tx.c +3
-2if (!is_template)@@ -5064,11 +5078,12 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw, }/* headroom, head length, -* tail length and maximum TIM length +* tail length, maximum TIM length and multiple BSSID length */ + mbssid_len =ieee80211_get_mbssid_beacon_len (beacon- >mbssid_ies); skb =dev_alloc_skb (local->tx_headroom + beacon->head_len + beacon->tail_len +256 + - local->hw.extra_beacon_tailroom); + local->hw.extra_beacon_tailroom + mbssid_len);net/mac80211/tx.c +5
-0if (!skb)return NULL ;@@ -5082,6 +5097,11 @@ ieee80211_beacon_get_ap(struct ieee80211_hw *hw, offs->tim_length = skb->len - beacon->head_len; offs->cntdwn_counter_offs[0 ] = beacon- >cntdwn_counter_offsets[0]; +if (mbssid_len) { +ieee80211_beacon_add_mbssid (skb, beacon); + offs->mbssid_off = skb->len - mbssid_len; + } +/* for AP the csa offsets are from tail */ net/mac80211/tx.c +0
-0csa_off_base = skb->len; }
Re: [PATCH v14 mac80211-next 1/3] mac80211: MBSSID beacon handling in AP mode
In reply to Lorenzo BianconiQuoted 10 lines · Lorenzo Bianconi
Add new fields in struct
beacon_datato store all MBSSID elements. Generate a beacon template which includes all MBSSID elements. Move CSA offset to reflect the MBSSID element length.Co-developed-by Aloka Dixit <[email protected]>Signed-off-by Aloka Dixit <[email protected]>Co-developed-by John Crispin <[email protected]>Signed-off-by John Crispin <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>---
Hi Lorenzo,
Looks like you removed the EMA portion from this ptch. Can you please fold that in as well from v13. Thanks.
Re: [PATCH v14 mac80211-next 1/3] mac80211: MBSSID beacon handling in AP mode
Quoted 12 lines · Lorenzo Bianconi
Quoted 10 lines
Add new fields in struct
beacon_datato store all MBSSID elements. Generate a beacon template which includes all MBSSID elements. Move CSA offset to reflect the MBSSID element length.Co-developed-by Aloka Dixit <[email protected]>Signed-off-by Aloka Dixit <[email protected]>Co-developed-by John Crispin <[email protected]>Signed-off-by John Crispin <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>---
Quoted 5 lines
Hi Lorenzo,
Looks like you removed the EMA portion from this ptch. Can you please fold that in as well from v13. Thanks.
Hi Aloka,
I remove the EMA part from the series since it was a bit convoluted and I was not able to test it since mtk fw does not support it for the moment. I guess you can add it on top of the current series when it is merged.
Regards,
Lorenzo