diff mbox series

[2/2] wnm: Add neigh ies to bss transition mgt request

Message ID 1553178806-28307-2-git-send-email-greearb@candelatech.com
State Changes Requested
Headers show
Series [1/2] rrm: Use helper method to create neigh report ies | expand

Commit Message

Ben Greear March 21, 2019, 2:33 p.m. UTC
From: Ben Greear <greearb@candelatech.com>

If a station requests a bss transition, then send add any
configured neighbors to the response.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 src/ap/wnm_ap.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

Comments

Janusz Dziedzic March 31, 2019, 8:01 a.m. UTC | #1
czw., 21 mar 2019 o 15:33 <greearb@candelatech.com> napisał(a):
>
> From: Ben Greear <greearb@candelatech.com>
>
> If a station requests a bss transition, then send add any
> configured neighbors to the response.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
>  src/ap/wnm_ap.c | 25 ++++++++++++++++++++++++-
>  1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
> index 27c69d3..cef44ce 100644
> --- a/src/ap/wnm_ap.c
> +++ b/src/ap/wnm_ap.c
> @@ -345,8 +345,9 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
>         size_t len;
>         u8 *pos;
>         int res;
> +       struct wpabuf *buf;
>
> -       mgmt = os_zalloc(sizeof(*mgmt));
> +       mgmt = os_zalloc(IEEE80211_MAX_MMPDU_SIZE);
>         if (mgmt == NULL)
>                 return -1;
>         os_memcpy(mgmt->da, addr, ETH_ALEN);
> @@ -357,11 +358,33 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
>         mgmt->u.action.category = WLAN_ACTION_WNM;
>         mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
>         mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
> +       /* set 0x1 flag for prefered candidate list included.
> +        * see: 9.6.14.9 BSS Transition Management Request frame format
> +        */
>         mgmt->u.action.u.bss_tm_req.req_mode = 0;
>         mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
>         mgmt->u.action.u.bss_tm_req.validity_interval = 1;
>         pos = mgmt->u.action.u.bss_tm_req.variable;
>
> +       buf = wpabuf_alloc(IEEE80211_MAX_MMPDU_SIZE - sizeof(*mgmt));
> +       if (buf) {
> +               /* Grab neighbor list */
> +               /* TODO:  Maybe round-robin and only send one?
> +                * Or take load into consideration?
> +                * Maybe we should skip our own entry?
> +                */
> +               int lci = 1; /* add lci sub-element */
> +               int civic = 1; /* add civic sub-element */
> +               int lci_age = 0xffff; /* maximum age, send all */
> +               hostapd_rrm_add_neigh_report_ies(hapd, buf, NULL, lci, civic, lci_age);
> +               if (wpabuf_len(buf)) {
> +                       mgmt->u.action.u.bss_tm_req.req_mode = 0x1;
> +                       os_memcpy(pos, wpabuf_head(buf), wpabuf_len(buf));
> +                       pos += wpabuf_len(buf);
> +               }
> +               wpabuf_free(buf);
> +       }
> +
>         wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
>                    MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
>                    "validity_interval=%u",
> --
> 2.7.5

What if we have 3-4 (our bss) neighbors and we know all of them have
high loads (slow path). In such case I would setup only 1 bssid in BTM
request.
After your patch, we will have to remove_neighors before BTM req.
After we will remove them and other sta will send us neighbor report
request we will send only
one? Not sure how much this BTM is used for steering, but seems that
setting bssids form wpa_cli we had before your patch is better (or we
should not close this path), while we will not affect NRResp and could
build any BTM we need.
Maybe we should add switch for CLI BTM command - to include neighbors
or just get them from CLI?
From other side we still have BTM query (and this should base on neigh
database)?

Finally for multi AP solutions, maybe we should not handle this in
hostapd at all.
Just expose 11v/k action frames to upper layer (some manager that know
status of all APs) and also allow this manager to /send frames... Not
sure what is the best.

BR
Janusz


Janusz Dziedzic
Ben Greear March 31, 2019, 3:16 p.m. UTC | #2
On 03/31/2019 01:01 AM, Janusz Dziedzic wrote:
> czw., 21 mar 2019 o 15:33 <greearb@candelatech.com> napisał(a):
>>
>> From: Ben Greear <greearb@candelatech.com>
>>
>> If a station requests a bss transition, then send add any
>> configured neighbors to the response.
>>
>> Signed-off-by: Ben Greear <greearb@candelatech.com>
>> ---
>>  src/ap/wnm_ap.c | 25 ++++++++++++++++++++++++-
>>  1 file changed, 24 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
>> index 27c69d3..cef44ce 100644
>> --- a/src/ap/wnm_ap.c
>> +++ b/src/ap/wnm_ap.c
>> @@ -345,8 +345,9 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
>>         size_t len;
>>         u8 *pos;
>>         int res;
>> +       struct wpabuf *buf;
>>
>> -       mgmt = os_zalloc(sizeof(*mgmt));
>> +       mgmt = os_zalloc(IEEE80211_MAX_MMPDU_SIZE);
>>         if (mgmt == NULL)
>>                 return -1;
>>         os_memcpy(mgmt->da, addr, ETH_ALEN);
>> @@ -357,11 +358,33 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
>>         mgmt->u.action.category = WLAN_ACTION_WNM;
>>         mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
>>         mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
>> +       /* set 0x1 flag for prefered candidate list included.
>> +        * see: 9.6.14.9 BSS Transition Management Request frame format
>> +        */
>>         mgmt->u.action.u.bss_tm_req.req_mode = 0;
>>         mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
>>         mgmt->u.action.u.bss_tm_req.validity_interval = 1;
>>         pos = mgmt->u.action.u.bss_tm_req.variable;
>>
>> +       buf = wpabuf_alloc(IEEE80211_MAX_MMPDU_SIZE - sizeof(*mgmt));
>> +       if (buf) {
>> +               /* Grab neighbor list */
>> +               /* TODO:  Maybe round-robin and only send one?
>> +                * Or take load into consideration?
>> +                * Maybe we should skip our own entry?
>> +                */
>> +               int lci = 1; /* add lci sub-element */
>> +               int civic = 1; /* add civic sub-element */
>> +               int lci_age = 0xffff; /* maximum age, send all */
>> +               hostapd_rrm_add_neigh_report_ies(hapd, buf, NULL, lci, civic, lci_age);
>> +               if (wpabuf_len(buf)) {
>> +                       mgmt->u.action.u.bss_tm_req.req_mode = 0x1;
>> +                       os_memcpy(pos, wpabuf_head(buf), wpabuf_len(buf));
>> +                       pos += wpabuf_len(buf);
>> +               }
>> +               wpabuf_free(buf);
>> +       }
>> +
>>         wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
>>                    MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
>>                    "validity_interval=%u",
>> --
>> 2.7.5
>
> What if we have 3-4 (our bss) neighbors and we know all of them have
> high loads (slow path). In such case I would setup only 1 bssid in BTM
> request.
> After your patch, we will have to remove_neighors before BTM req.
> After we will remove them and other sta will send us neighbor report
> request we will send only
> one? Not sure how much this BTM is used for steering, but seems that
> setting bssids form wpa_cli we had before your patch is better (or we
> should not close this path), while we will not affect NRResp and could
> build any BTM we need.
> Maybe we should add switch for CLI BTM command - to include neighbors
> or just get them from CLI?
> From other side we still have BTM query (and this should base on neigh
> database)?
>
> Finally for multi AP solutions, maybe we should not handle this in
> hostapd at all.
> Just expose 11v/k action frames to upper layer (some manager that know
> status of all APs) and also allow this manager to /send frames... Not
> sure what is the best.

I was thinking we should also have a priority setting in the neigh DB,
so then when we send the neigh report, we can add the IE that specifies
the neighbor that is 'best' for the neighbor.

I did not see any way to add neighbors before my patch, can you show
the commands you use to implement this without my patch?

And in general, you probably do want this to be handled by a manager
that has better over-all insight.  If you had a sniffer on all APs,
you could probably know RSSI to the requesting station for all APs,
and then you could steer the station to the AP with good RSSI (as well
as take load into account and such).  In general, if you have an AP
with good RSSI and moderate load, that would be a better choice than
a very lightly loaded AP with poor RSSI.

Are there any open-source managers for hostapd APs?

Thanks,
Ben
Janusz Dziedzic April 1, 2019, 11:16 a.m. UTC | #3
niedz., 31 mar 2019 o 17:17 Ben Greear <greearb@candelatech.com> napisał(a):
>
>
>
> On 03/31/2019 01:01 AM, Janusz Dziedzic wrote:
> > czw., 21 mar 2019 o 15:33 <greearb@candelatech.com> napisał(a):
> >>
> >> From: Ben Greear <greearb@candelatech.com>
> >>
> >> If a station requests a bss transition, then send add any
> >> configured neighbors to the response.
> >>
> >> Signed-off-by: Ben Greear <greearb@candelatech.com>
> >> ---
> >>  src/ap/wnm_ap.c | 25 ++++++++++++++++++++++++-
> >>  1 file changed, 24 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
> >> index 27c69d3..cef44ce 100644
> >> --- a/src/ap/wnm_ap.c
> >> +++ b/src/ap/wnm_ap.c
> >> @@ -345,8 +345,9 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
> >>         size_t len;
> >>         u8 *pos;
> >>         int res;
> >> +       struct wpabuf *buf;
> >>
> >> -       mgmt = os_zalloc(sizeof(*mgmt));
> >> +       mgmt = os_zalloc(IEEE80211_MAX_MMPDU_SIZE);
> >>         if (mgmt == NULL)
> >>                 return -1;
> >>         os_memcpy(mgmt->da, addr, ETH_ALEN);
> >> @@ -357,11 +358,33 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
> >>         mgmt->u.action.category = WLAN_ACTION_WNM;
> >>         mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
> >>         mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
> >> +       /* set 0x1 flag for prefered candidate list included.
> >> +        * see: 9.6.14.9 BSS Transition Management Request frame format
> >> +        */
> >>         mgmt->u.action.u.bss_tm_req.req_mode = 0;
> >>         mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
> >>         mgmt->u.action.u.bss_tm_req.validity_interval = 1;
> >>         pos = mgmt->u.action.u.bss_tm_req.variable;
> >>
> >> +       buf = wpabuf_alloc(IEEE80211_MAX_MMPDU_SIZE - sizeof(*mgmt));
> >> +       if (buf) {
> >> +               /* Grab neighbor list */
> >> +               /* TODO:  Maybe round-robin and only send one?
> >> +                * Or take load into consideration?
> >> +                * Maybe we should skip our own entry?
> >> +                */
> >> +               int lci = 1; /* add lci sub-element */
> >> +               int civic = 1; /* add civic sub-element */
> >> +               int lci_age = 0xffff; /* maximum age, send all */
> >> +               hostapd_rrm_add_neigh_report_ies(hapd, buf, NULL, lci, civic, lci_age);
> >> +               if (wpabuf_len(buf)) {
> >> +                       mgmt->u.action.u.bss_tm_req.req_mode = 0x1;
> >> +                       os_memcpy(pos, wpabuf_head(buf), wpabuf_len(buf));
> >> +                       pos += wpabuf_len(buf);
> >> +               }
> >> +               wpabuf_free(buf);
> >> +       }
> >> +
> >>         wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
> >>                    MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
> >>                    "validity_interval=%u",
> >> --
> >> 2.7.5
> >
> > What if we have 3-4 (our bss) neighbors and we know all of them have
> > high loads (slow path). In such case I would setup only 1 bssid in BTM
> > request.
> > After your patch, we will have to remove_neighors before BTM req.
> > After we will remove them and other sta will send us neighbor report
> > request we will send only
> > one? Not sure how much this BTM is used for steering, but seems that
> > setting bssids form wpa_cli we had before your patch is better (or we
> > should not close this path), while we will not affect NRResp and could
> > build any BTM we need.
> > Maybe we should add switch for CLI BTM command - to include neighbors
> > or just get them from CLI?
> > From other side we still have BTM query (and this should base on neigh
> > database)?
> >
> > Finally for multi AP solutions, maybe we should not handle this in
> > hostapd at all.
> > Just expose 11v/k action frames to upper layer (some manager that know
> > status of all APs) and also allow this manager to /send frames... Not
> > sure what is the best.
>
> I was thinking we should also have a priority setting in the neigh DB,
> so then when we send the neigh report, we can add the IE that specifies
> the neighbor that is 'best' for the neighbor.
>
> I did not see any way to add neighbors before my patch, can you show
> the commands you use to implement this without my patch?
>
for btm check test_wnm.py
hapd.request("BSS_TM_REQ " + addr + "
neighbor=11:22:33:44:55:66,0x0000,81,3,7"):

> And in general, you probably do want this to be handled by a manager
> that has better over-all insight.  If you had a sniffer on all APs,
> you could probably know RSSI to the requesting station for all APs,
> and then you could steer the station to the AP with good RSSI (as well
> as take load into account and such).  In general, if you have an AP
> with good RSSI and moderate load, that would be a better choice than
> a very lightly loaded AP with poor RSSI.
>
> Are there any open-source managers for hostapd APs?
>
Probably not :)

> Thanks,
> Ben
>
>
> --
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc  http://www.candelatech.com
Ben Greear April 1, 2019, 12:39 p.m. UTC | #4
On 04/01/2019 04:16 AM, Janusz Dziedzic wrote:
> niedz., 31 mar 2019 o 17:17 Ben Greear <greearb@candelatech.com> napisał(a):
>>
>>
>>
>> On 03/31/2019 01:01 AM, Janusz Dziedzic wrote:
>>> czw., 21 mar 2019 o 15:33 <greearb@candelatech.com> napisał(a):
>>>>
>>>> From: Ben Greear <greearb@candelatech.com>
>>>>
>>>> If a station requests a bss transition, then send add any
>>>> configured neighbors to the response.
>>>>
>>>> Signed-off-by: Ben Greear <greearb@candelatech.com>
>>>> ---
>>>>  src/ap/wnm_ap.c | 25 ++++++++++++++++++++++++-
>>>>  1 file changed, 24 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
>>>> index 27c69d3..cef44ce 100644
>>>> --- a/src/ap/wnm_ap.c
>>>> +++ b/src/ap/wnm_ap.c
>>>> @@ -345,8 +345,9 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
>>>>         size_t len;
>>>>         u8 *pos;
>>>>         int res;
>>>> +       struct wpabuf *buf;
>>>>
>>>> -       mgmt = os_zalloc(sizeof(*mgmt));
>>>> +       mgmt = os_zalloc(IEEE80211_MAX_MMPDU_SIZE);
>>>>         if (mgmt == NULL)
>>>>                 return -1;
>>>>         os_memcpy(mgmt->da, addr, ETH_ALEN);
>>>> @@ -357,11 +358,33 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
>>>>         mgmt->u.action.category = WLAN_ACTION_WNM;
>>>>         mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
>>>>         mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
>>>> +       /* set 0x1 flag for prefered candidate list included.
>>>> +        * see: 9.6.14.9 BSS Transition Management Request frame format
>>>> +        */
>>>>         mgmt->u.action.u.bss_tm_req.req_mode = 0;
>>>>         mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
>>>>         mgmt->u.action.u.bss_tm_req.validity_interval = 1;
>>>>         pos = mgmt->u.action.u.bss_tm_req.variable;
>>>>
>>>> +       buf = wpabuf_alloc(IEEE80211_MAX_MMPDU_SIZE - sizeof(*mgmt));
>>>> +       if (buf) {
>>>> +               /* Grab neighbor list */
>>>> +               /* TODO:  Maybe round-robin and only send one?
>>>> +                * Or take load into consideration?
>>>> +                * Maybe we should skip our own entry?
>>>> +                */
>>>> +               int lci = 1; /* add lci sub-element */
>>>> +               int civic = 1; /* add civic sub-element */
>>>> +               int lci_age = 0xffff; /* maximum age, send all */
>>>> +               hostapd_rrm_add_neigh_report_ies(hapd, buf, NULL, lci, civic, lci_age);
>>>> +               if (wpabuf_len(buf)) {
>>>> +                       mgmt->u.action.u.bss_tm_req.req_mode = 0x1;
>>>> +                       os_memcpy(pos, wpabuf_head(buf), wpabuf_len(buf));
>>>> +                       pos += wpabuf_len(buf);
>>>> +               }
>>>> +               wpabuf_free(buf);
>>>> +       }
>>>> +
>>>>         wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
>>>>                    MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
>>>>                    "validity_interval=%u",
>>>> --
>>>> 2.7.5
>>>
>>> What if we have 3-4 (our bss) neighbors and we know all of them have
>>> high loads (slow path). In such case I would setup only 1 bssid in BTM
>>> request.
>>> After your patch, we will have to remove_neighors before BTM req.
>>> After we will remove them and other sta will send us neighbor report
>>> request we will send only
>>> one? Not sure how much this BTM is used for steering, but seems that
>>> setting bssids form wpa_cli we had before your patch is better (or we
>>> should not close this path), while we will not affect NRResp and could
>>> build any BTM we need.
>>> Maybe we should add switch for CLI BTM command - to include neighbors
>>> or just get them from CLI?
>>> From other side we still have BTM query (and this should base on neigh
>>> database)?
>>>
>>> Finally for multi AP solutions, maybe we should not handle this in
>>> hostapd at all.
>>> Just expose 11v/k action frames to upper layer (some manager that know
>>> status of all APs) and also allow this manager to /send frames... Not
>>> sure what is the best.
>>
>> I was thinking we should also have a priority setting in the neigh DB,
>> so then when we send the neigh report, we can add the IE that specifies
>> the neighbor that is 'best' for the neighbor.
>>
>> I did not see any way to add neighbors before my patch, can you show
>> the commands you use to implement this without my patch?
>>
> for btm check test_wnm.py
> hapd.request("BSS_TM_REQ " + addr + "
> neighbor=11:22:33:44:55:66,0x0000,81,3,7"):

 From what I can tell, this is hostapd sending the request to the STA
based on outside event (ie, the .py script), and it seems that it is
building the packet directly there in the .py script.

My patch is used in the case where the STA makes a request to the AP,
and then the AP answers with a TM REQ.  Before my patch, the answering
TM REQ had no neighbors, so it is mostly worthless as far as I can tell.

>> And in general, you probably do want this to be handled by a manager
>> that has better over-all insight.  If you had a sniffer on all APs,
>> you could probably know RSSI to the requesting station for all APs,
>> and then you could steer the station to the AP with good RSSI (as well
>> as take load into account and such).  In general, if you have an AP
>> with good RSSI and moderate load, that would be a better choice than
>> a very lightly loaded AP with poor RSSI.
>>
>> Are there any open-source managers for hostapd APs?
>>
> Probably not :)

Someone should get on that!  Looks like a great opportunity to learn how
to do tricky things in a distributed flaky RF environment with drivers
and firmware and radios of questionable quality up and down the stack!

Thanks,
Ben
Janusz Dziedzic April 2, 2019, 5:49 p.m. UTC | #5
pon., 1 kwi 2019 o 14:39 Ben Greear <greearb@candelatech.com> napisał(a):
>
>
>
> On 04/01/2019 04:16 AM, Janusz Dziedzic wrote:
> > niedz., 31 mar 2019 o 17:17 Ben Greear <greearb@candelatech.com> napisał(a):
> >>
> >>
> >>
> >> On 03/31/2019 01:01 AM, Janusz Dziedzic wrote:
> >>> czw., 21 mar 2019 o 15:33 <greearb@candelatech.com> napisał(a):
> >>>>
> >>>> From: Ben Greear <greearb@candelatech.com>
> >>>>
> >>>> If a station requests a bss transition, then send add any
> >>>> configured neighbors to the response.
> >>>>
> >>>> Signed-off-by: Ben Greear <greearb@candelatech.com>
> >>>> ---
> >>>>  src/ap/wnm_ap.c | 25 ++++++++++++++++++++++++-
> >>>>  1 file changed, 24 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
> >>>> index 27c69d3..cef44ce 100644
> >>>> --- a/src/ap/wnm_ap.c
> >>>> +++ b/src/ap/wnm_ap.c
> >>>> @@ -345,8 +345,9 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
> >>>>         size_t len;
> >>>>         u8 *pos;
> >>>>         int res;
> >>>> +       struct wpabuf *buf;
> >>>>
> >>>> -       mgmt = os_zalloc(sizeof(*mgmt));
> >>>> +       mgmt = os_zalloc(IEEE80211_MAX_MMPDU_SIZE);
> >>>>         if (mgmt == NULL)
> >>>>                 return -1;
> >>>>         os_memcpy(mgmt->da, addr, ETH_ALEN);
> >>>> @@ -357,11 +358,33 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
> >>>>         mgmt->u.action.category = WLAN_ACTION_WNM;
> >>>>         mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
> >>>>         mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
> >>>> +       /* set 0x1 flag for prefered candidate list included.
> >>>> +        * see: 9.6.14.9 BSS Transition Management Request frame format
> >>>> +        */
> >>>>         mgmt->u.action.u.bss_tm_req.req_mode = 0;
> >>>>         mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
> >>>>         mgmt->u.action.u.bss_tm_req.validity_interval = 1;
> >>>>         pos = mgmt->u.action.u.bss_tm_req.variable;
> >>>>
> >>>> +       buf = wpabuf_alloc(IEEE80211_MAX_MMPDU_SIZE - sizeof(*mgmt));
> >>>> +       if (buf) {
> >>>> +               /* Grab neighbor list */
> >>>> +               /* TODO:  Maybe round-robin and only send one?
> >>>> +                * Or take load into consideration?
> >>>> +                * Maybe we should skip our own entry?
> >>>> +                */
> >>>> +               int lci = 1; /* add lci sub-element */
> >>>> +               int civic = 1; /* add civic sub-element */
> >>>> +               int lci_age = 0xffff; /* maximum age, send all */
> >>>> +               hostapd_rrm_add_neigh_report_ies(hapd, buf, NULL, lci, civic, lci_age);
> >>>> +               if (wpabuf_len(buf)) {
> >>>> +                       mgmt->u.action.u.bss_tm_req.req_mode = 0x1;
> >>>> +                       os_memcpy(pos, wpabuf_head(buf), wpabuf_len(buf));
> >>>> +                       pos += wpabuf_len(buf);
> >>>> +               }
> >>>> +               wpabuf_free(buf);
> >>>> +       }
> >>>> +
> >>>>         wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
> >>>>                    MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
> >>>>                    "validity_interval=%u",
> >>>> --
> >>>> 2.7.5
> >>>
> >>> What if we have 3-4 (our bss) neighbors and we know all of them have
> >>> high loads (slow path). In such case I would setup only 1 bssid in BTM
> >>> request.
> >>> After your patch, we will have to remove_neighors before BTM req.
> >>> After we will remove them and other sta will send us neighbor report
> >>> request we will send only
> >>> one? Not sure how much this BTM is used for steering, but seems that
> >>> setting bssids form wpa_cli we had before your patch is better (or we
> >>> should not close this path), while we will not affect NRResp and could
> >>> build any BTM we need.
> >>> Maybe we should add switch for CLI BTM command - to include neighbors
> >>> or just get them from CLI?
> >>> From other side we still have BTM query (and this should base on neigh
> >>> database)?
> >>>
> >>> Finally for multi AP solutions, maybe we should not handle this in
> >>> hostapd at all.
> >>> Just expose 11v/k action frames to upper layer (some manager that know
> >>> status of all APs) and also allow this manager to /send frames... Not
> >>> sure what is the best.
> >>
> >> I was thinking we should also have a priority setting in the neigh DB,
> >> so then when we send the neigh report, we can add the IE that specifies
> >> the neighbor that is 'best' for the neighbor.
> >>
> >> I did not see any way to add neighbors before my patch, can you show
> >> the commands you use to implement this without my patch?
> >>
> > for btm check test_wnm.py
> > hapd.request("BSS_TM_REQ " + addr + "
> > neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
>
>  From what I can tell, this is hostapd sending the request to the STA
> based on outside event (ie, the .py script), and it seems that it is
> building the packet directly there in the .py script.
>
> My patch is used in the case where the STA makes a request to the AP,
> and then the AP answers with a TM REQ.  Before my patch, the answering
> TM REQ had no neighbors, so it is mostly worthless as far as I can tell.
>
So, this is for BSS TM query handling only.
Thanks for patch, seems another one will go to my tree.

BR
Janusz


> >> And in general, you probably do want this to be handled by a manager
> >> that has better over-all insight.  If you had a sniffer on all APs,
> >> you could probably know RSSI to the requesting station for all APs,
> >> and then you could steer the station to the AP with good RSSI (as well
> >> as take load into account and such).  In general, if you have an AP
> >> with good RSSI and moderate load, that would be a better choice than
> >> a very lightly loaded AP with poor RSSI.
> >>
> >> Are there any open-source managers for hostapd APs?
> >>
> > Probably not :)
>
> Someone should get on that!  Looks like a great opportunity to learn how
> to do tricky things in a distributed flaky RF environment with drivers
> and firmware and radios of questionable quality up and down the stack!
>
> Thanks,
> Ben
>
>
> --
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc  http://www.candelatech.com



--
Janusz Dziedzic
Janusz Dziedzic April 3, 2019, 9:33 a.m. UTC | #6
wt., 2 kwi 2019 o 19:49 Janusz Dziedzic <janusz.dziedzic@gmail.com> napisał(a):
>
> pon., 1 kwi 2019 o 14:39 Ben Greear <greearb@candelatech.com> napisał(a):
<cut>

BTW, in case I already send neighbor report response to the station
and after that get info that one of the AP bssid I send goes down
(someone just switch off this AP) is there option I can send
Neighbor Report Response again without request from station side?

BR
Janusz
Ben Greear April 3, 2019, 12:37 p.m. UTC | #7
On 04/03/2019 02:33 AM, Janusz Dziedzic wrote:
> wt., 2 kwi 2019 o 19:49 Janusz Dziedzic <janusz.dziedzic@gmail.com> napisał(a):
>>
>> pon., 1 kwi 2019 o 14:39 Ben Greear <greearb@candelatech.com> napisał(a):
> <cut>
>
> BTW, in case I already send neighbor report response to the station
> and after that get info that one of the AP bssid I send goes down
> (someone just switch off this AP) is there option I can send
> Neighbor Report Response again without request from station side?

Yes, hostap_cli has an option to send neigh reports I think.

Thanks,
Ben

>
> BR
> Janusz
>
Jouni Malinen April 7, 2019, 1:50 p.m. UTC | #8
On Thu, Mar 21, 2019 at 07:33:26AM -0700, greearb@candelatech.com wrote:
> If a station requests a bss transition, then send add any
> configured neighbors to the response.

Why? What would make those neighbors good candidates for the particular
station? I don't think this should be done without some tracking of how
the particular station is visible to the neighbors and how loaded the
channels are for each of the neighbors, i.e., this would require close
coordination between all the neighboring APs.
Ben Greear April 7, 2019, 8:23 p.m. UTC | #9
On 04/07/2019 06:50 AM, Jouni Malinen wrote:
> On Thu, Mar 21, 2019 at 07:33:26AM -0700, greearb@candelatech.com wrote:
>> If a station requests a bss transition, then send add any
>> configured neighbors to the response.
>
> Why? What would make those neighbors good candidates for the particular
> station? I don't think this should be done without some tracking of how
> the particular station is visible to the neighbors and how loaded the
> channels are for each of the neighbors, i.e., this would require close
> coordination between all the neighboring APs.

A controller can keep a close eye on everything and set/remove neighbors
from each hostapd as it deems necessary.

I don't think this is something that individual hostapd will be able to
manage themselves, but it would be nice to have hostapd handle sending
the messages once it is properly configured.

Thanks,
Ben
Ben Greear April 9, 2019, 5:54 p.m. UTC | #10
On 4/7/19 1:23 PM, Ben Greear wrote:
> 
> 
> On 04/07/2019 06:50 AM, Jouni Malinen wrote:
>> On Thu, Mar 21, 2019 at 07:33:26AM -0700, greearb@candelatech.com wrote:
>>> If a station requests a bss transition, then send add any
>>> configured neighbors to the response.
>>
>> Why? What would make those neighbors good candidates for the particular
>> station? I don't think this should be done without some tracking of how
>> the particular station is visible to the neighbors and how loaded the
>> channels are for each of the neighbors, i.e., this would require close
>> coordination between all the neighboring APs.
> 
> A controller can keep a close eye on everything and set/remove neighbors
> from each hostapd as it deems necessary.
> 
> I don't think this is something that individual hostapd will be able to
> manage themselves, but it would be nice to have hostapd handle sending
> the messages once it is properly configured.

After some more thinking on this, I would tend to agree that my initial approach
is too simplistic because different STAs requesting to the same AP should likely
get different answers (ie, one STA is better for Neigh-1 and another STA is better
for Neigh-2.

For a simple case, where we have no triangulation and X APs in an area, then
a simple controller could poke some info in the the neigh DB so each hostapd
would be up to date on how many STA are connected to each AP, for instance.

Would you be interested in a patch that allowed adding that to the neigh
DB and then (if neigh is so flagged), add the least-used AP(s)
to the response automatically?

Thanks,
Ben
diff mbox series

Patch

diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
index 27c69d3..cef44ce 100644
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -345,8 +345,9 @@  static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
 	size_t len;
 	u8 *pos;
 	int res;
+	struct wpabuf *buf;
 
-	mgmt = os_zalloc(sizeof(*mgmt));
+	mgmt = os_zalloc(IEEE80211_MAX_MMPDU_SIZE);
 	if (mgmt == NULL)
 		return -1;
 	os_memcpy(mgmt->da, addr, ETH_ALEN);
@@ -357,11 +358,33 @@  static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
 	mgmt->u.action.category = WLAN_ACTION_WNM;
 	mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
 	mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
+	/* set 0x1 flag for prefered candidate list included.
+	 * see: 9.6.14.9 BSS Transition Management Request frame format
+	 */
 	mgmt->u.action.u.bss_tm_req.req_mode = 0;
 	mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
 	mgmt->u.action.u.bss_tm_req.validity_interval = 1;
 	pos = mgmt->u.action.u.bss_tm_req.variable;
 
+	buf = wpabuf_alloc(IEEE80211_MAX_MMPDU_SIZE - sizeof(*mgmt));
+	if (buf) {
+		/* Grab neighbor list */
+		/* TODO:  Maybe round-robin and only send one?
+		 * Or take load into consideration?
+		 * Maybe we should skip our own entry?
+		 */
+		int lci = 1; /* add lci sub-element */
+		int civic = 1; /* add civic sub-element */
+		int lci_age = 0xffff; /* maximum age, send all */
+		hostapd_rrm_add_neigh_report_ies(hapd, buf, NULL, lci, civic, lci_age);
+		if (wpabuf_len(buf)) {
+			mgmt->u.action.u.bss_tm_req.req_mode = 0x1;
+			os_memcpy(pos, wpabuf_head(buf), wpabuf_len(buf));
+			pos += wpabuf_len(buf);
+		}
+		wpabuf_free(buf);
+	}
+
 	wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
 		   MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
 		   "validity_interval=%u",