Message ID | 20220621133610.4018404-4-stijn@linux-ipv6.be |
---|---|
State | Accepted, archived |
Delegated to: | Stijn Tintel |
Headers | show |
Series | [1/4] hostapd: add config symbol to enable MBO | expand |
Hi Stijn, I am wanting to test these patches on an AP. Is this a case of applying this, configure MBO enabled, and it just works? I ask, because it looks like a daemon of some kind needs to manage the MBO transitions of the attached STA using UBUS transition requests, is that correct? On 21/6/22 20:36, Stijn Tintel wrote: > Support the use of MBO in the bss_transition_request ubus method. > > Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be> > --- > package/network/services/hostapd/README.md | 3 + > .../services/hostapd/src/src/ap/ubus.c | 61 ++++++++++++++++++- > 2 files changed, 61 insertions(+), 3 deletions(-) > > diff --git a/package/network/services/hostapd/README.md b/package/network/services/hostapd/README.md > index bd347c61dd..2150863306 100644 > --- a/package/network/services/hostapd/README.md > +++ b/package/network/services/hostapd/README.md > @@ -29,6 +29,9 @@ Initiate an 802.11v transition request. > | neighbors | array | no | BSS Transition Candidate List | > | abridged | bool | no | prefer APs in the BSS Transition Candidate List | > | dialog_token | int32 | no | identifier for the request/report transaction | > +| mbo_reason | int32 | no | MBO Transition Reason Code Attribute | > +| cell_pref | int32 | no | MBO Cellular Data Connection Preference Attribute | > +| reassoc_delay | int32 | no | MBO Re-association retry delay | > > ### example > `ubus call hostapd.wl5-fb bss_transition_request '{ "addr": "68:2F:67:8B:98:ED", "disassociation_imminent": false, "disassociation_timer": 0, "validity_period": 30, "neighbors": ["b6a7b9cbeebabf5900008064090603026a00"], "abridged": 1 }'` > diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c > index 1199098b1e..182aae7d05 100644 > --- a/package/network/services/hostapd/src/src/ap/ubus.c > +++ b/package/network/services/hostapd/src/src/ap/ubus.c > @@ -1454,7 +1454,7 @@ void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *d > static int > hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, bool abridged, > u16 disassoc_timer, u8 validity_period, u8 dialog_token, > - struct blob_attr *neighbors) > + struct blob_attr *neighbors, u8 mbo_reason, u8 cell_pref, u8 reassoc_delay) > { > struct blob_attr *cur; > struct sta_info *sta; > @@ -1462,6 +1462,8 @@ hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, > int rem; > u8 *nr = NULL; > u8 req_mode = 0; > + u8 mbo[10]; > + size_t mbo_len = 0; > > sta = ap_get_sta(hapd, addr); > if (!sta) > @@ -1513,8 +1515,37 @@ hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, > if (disassoc_imminent) > req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT; > > +#ifdef CONFIG_MBO > + u8 *mbo_pos = mbo; > + > + if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) > + return UBUS_STATUS_INVALID_ARGUMENT; > + > + if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) > + return UBUS_STATUS_INVALID_ARGUMENT; > + > + if (reassoc_delay > 65535 || (reassoc_delay && !disassoc_imminent)) > + return UBUS_STATUS_INVALID_ARGUMENT; > + > + *mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON; > + *mbo_pos++ = 1; > + *mbo_pos++ = mbo_reason; > + *mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF; > + *mbo_pos++ = 1; > + *mbo_pos++ = cell_pref; > + > + if (reassoc_delay) { > + *mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY; > + *mbo_pos++ = 2; > + WPA_PUT_LE16(mbo_pos, reassoc_delay); > + mbo_pos += 2; > + } > + > + mbo_len = mbo_pos - mbo; > +#endif > + > if (wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, validity_period, NULL, > - dialog_token, NULL, nr, nr_len, NULL, 0)) > + dialog_token, NULL, nr, nr_len, mbo_len ? mbo : NULL, mbo_len)) > return UBUS_STATUS_UNKNOWN_ERROR; > > return 0; > @@ -1528,6 +1559,11 @@ enum { > BSS_TR_NEIGHBORS, > BSS_TR_ABRIDGED, > BSS_TR_DIALOG_TOKEN, > +#ifdef CONFIG_MBO > + BSS_TR_MBO_REASON, > + BSS_TR_CELL_PREF, > + BSS_TR_REASSOC_DELAY, > +#endif > __BSS_TR_DISASSOC_MAX > }; > > @@ -1539,6 +1575,11 @@ static const struct blobmsg_policy bss_tr_policy[__BSS_TR_DISASSOC_MAX] = { > [BSS_TR_NEIGHBORS] = { "neighbors", BLOBMSG_TYPE_ARRAY }, > [BSS_TR_ABRIDGED] = { "abridged", BLOBMSG_TYPE_BOOL }, > [BSS_TR_DIALOG_TOKEN] = { "dialog_token", BLOBMSG_TYPE_INT32 }, > +#ifdef CONFIG_MBO > + [BSS_TR_MBO_REASON] = { "mbo_reason", BLOBMSG_TYPE_INT32 }, > + [BSS_TR_CELL_PREF] = { "cell_pref", BLOBMSG_TYPE_INT32 }, > + [BSS_TR_REASSOC_DELAY] = { "reassoc_delay", BLOBMSG_TYPE_INT32 }, > +#endif > }; > > static int > @@ -1555,6 +1596,9 @@ hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj > u32 dialog_token = 1; > bool abridged; > bool da_imminent; > + u8 mbo_reason; > + u8 cell_pref; > + u8 reassoc_delay; > > blobmsg_parse(bss_tr_policy, __BSS_TR_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); > > @@ -1576,8 +1620,19 @@ hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj > da_imminent = !!(tb[BSS_TR_DA_IMMINENT] && blobmsg_get_bool(tb[BSS_TR_DA_IMMINENT])); > abridged = !!(tb[BSS_TR_ABRIDGED] && blobmsg_get_bool(tb[BSS_TR_ABRIDGED])); > > +#ifdef CONFIG_MBO > + if (tb[BSS_TR_MBO_REASON]) > + mbo_reason = blobmsg_get_u32(tb[BSS_TR_MBO_REASON]); > + > + if (tb[BSS_TR_CELL_PREF]) > + cell_pref = blobmsg_get_u32(tb[BSS_TR_CELL_PREF]); > + > + if (tb[BSS_TR_REASSOC_DELAY]) > + reassoc_delay = blobmsg_get_u32(tb[BSS_TR_REASSOC_DELAY]); > +#endif > + > return hostapd_bss_tr_send(hapd, addr, da_imminent, abridged, da_timer, valid_period, > - dialog_token, tb[BSS_TR_NEIGHBORS]); > + dialog_token, tb[BSS_TR_NEIGHBORS], mbo_reason, cell_pref, reassoc_delay); > } > #endif >
On 28/06/2022 02:05, Strontium wrote: > Hi Stijn, > > I am wanting to test these patches on an AP. Is this a case of > applying this, configure MBO enabled, and it just works? I ask, > because it looks like a daemon of some kind needs to manage the MBO > transitions of the attached STA using UBUS transition requests, is > that correct? > This patch merely adds support for MBO to the existing ubus method bss_transition_request. This method is used by [1] and [2] to steer clients between different BSSes in an ESS, but does nothing on its own. Once this patch is in OpenWrt, these daemons could be updated to make use of the new MBO attributes for improved steering. Stijn [1] https://git.openwrt.org/?p=project/usteer.git [2] https://github.com/berlin-open-wireless-lab/DAWN
diff --git a/package/network/services/hostapd/README.md b/package/network/services/hostapd/README.md index bd347c61dd..2150863306 100644 --- a/package/network/services/hostapd/README.md +++ b/package/network/services/hostapd/README.md @@ -29,6 +29,9 @@ Initiate an 802.11v transition request. | neighbors | array | no | BSS Transition Candidate List | | abridged | bool | no | prefer APs in the BSS Transition Candidate List | | dialog_token | int32 | no | identifier for the request/report transaction | +| mbo_reason | int32 | no | MBO Transition Reason Code Attribute | +| cell_pref | int32 | no | MBO Cellular Data Connection Preference Attribute | +| reassoc_delay | int32 | no | MBO Re-association retry delay | ### example `ubus call hostapd.wl5-fb bss_transition_request '{ "addr": "68:2F:67:8B:98:ED", "disassociation_imminent": false, "disassociation_timer": 0, "validity_period": 30, "neighbors": ["b6a7b9cbeebabf5900008064090603026a00"], "abridged": 1 }'` diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 1199098b1e..182aae7d05 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -1454,7 +1454,7 @@ void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *d static int hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, bool abridged, u16 disassoc_timer, u8 validity_period, u8 dialog_token, - struct blob_attr *neighbors) + struct blob_attr *neighbors, u8 mbo_reason, u8 cell_pref, u8 reassoc_delay) { struct blob_attr *cur; struct sta_info *sta; @@ -1462,6 +1462,8 @@ hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, int rem; u8 *nr = NULL; u8 req_mode = 0; + u8 mbo[10]; + size_t mbo_len = 0; sta = ap_get_sta(hapd, addr); if (!sta) @@ -1513,8 +1515,37 @@ hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, if (disassoc_imminent) req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT; +#ifdef CONFIG_MBO + u8 *mbo_pos = mbo; + + if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) + return UBUS_STATUS_INVALID_ARGUMENT; + + if (reassoc_delay > 65535 || (reassoc_delay && !disassoc_imminent)) + return UBUS_STATUS_INVALID_ARGUMENT; + + *mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON; + *mbo_pos++ = 1; + *mbo_pos++ = mbo_reason; + *mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF; + *mbo_pos++ = 1; + *mbo_pos++ = cell_pref; + + if (reassoc_delay) { + *mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY; + *mbo_pos++ = 2; + WPA_PUT_LE16(mbo_pos, reassoc_delay); + mbo_pos += 2; + } + + mbo_len = mbo_pos - mbo; +#endif + if (wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, validity_period, NULL, - dialog_token, NULL, nr, nr_len, NULL, 0)) + dialog_token, NULL, nr, nr_len, mbo_len ? mbo : NULL, mbo_len)) return UBUS_STATUS_UNKNOWN_ERROR; return 0; @@ -1528,6 +1559,11 @@ enum { BSS_TR_NEIGHBORS, BSS_TR_ABRIDGED, BSS_TR_DIALOG_TOKEN, +#ifdef CONFIG_MBO + BSS_TR_MBO_REASON, + BSS_TR_CELL_PREF, + BSS_TR_REASSOC_DELAY, +#endif __BSS_TR_DISASSOC_MAX }; @@ -1539,6 +1575,11 @@ static const struct blobmsg_policy bss_tr_policy[__BSS_TR_DISASSOC_MAX] = { [BSS_TR_NEIGHBORS] = { "neighbors", BLOBMSG_TYPE_ARRAY }, [BSS_TR_ABRIDGED] = { "abridged", BLOBMSG_TYPE_BOOL }, [BSS_TR_DIALOG_TOKEN] = { "dialog_token", BLOBMSG_TYPE_INT32 }, +#ifdef CONFIG_MBO + [BSS_TR_MBO_REASON] = { "mbo_reason", BLOBMSG_TYPE_INT32 }, + [BSS_TR_CELL_PREF] = { "cell_pref", BLOBMSG_TYPE_INT32 }, + [BSS_TR_REASSOC_DELAY] = { "reassoc_delay", BLOBMSG_TYPE_INT32 }, +#endif }; static int @@ -1555,6 +1596,9 @@ hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj u32 dialog_token = 1; bool abridged; bool da_imminent; + u8 mbo_reason; + u8 cell_pref; + u8 reassoc_delay; blobmsg_parse(bss_tr_policy, __BSS_TR_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); @@ -1576,8 +1620,19 @@ hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj da_imminent = !!(tb[BSS_TR_DA_IMMINENT] && blobmsg_get_bool(tb[BSS_TR_DA_IMMINENT])); abridged = !!(tb[BSS_TR_ABRIDGED] && blobmsg_get_bool(tb[BSS_TR_ABRIDGED])); +#ifdef CONFIG_MBO + if (tb[BSS_TR_MBO_REASON]) + mbo_reason = blobmsg_get_u32(tb[BSS_TR_MBO_REASON]); + + if (tb[BSS_TR_CELL_PREF]) + cell_pref = blobmsg_get_u32(tb[BSS_TR_CELL_PREF]); + + if (tb[BSS_TR_REASSOC_DELAY]) + reassoc_delay = blobmsg_get_u32(tb[BSS_TR_REASSOC_DELAY]); +#endif + return hostapd_bss_tr_send(hapd, addr, da_imminent, abridged, da_timer, valid_period, - dialog_token, tb[BSS_TR_NEIGHBORS]); + dialog_token, tb[BSS_TR_NEIGHBORS], mbo_reason, cell_pref, reassoc_delay); } #endif
Support the use of MBO in the bss_transition_request ubus method. Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be> --- package/network/services/hostapd/README.md | 3 + .../services/hostapd/src/src/ap/ubus.c | 61 ++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-)