policy: only send preferred candidate with transition request

Only send the preferred candidate with a BSS transition request.
Otherwise, unsuitable candidates might be included in the neighbor-list
of a transition request.

Signed-off-by: David Bauer <mail@david-bauer.net>
This commit is contained in:
David Bauer
2022-05-05 00:33:52 +02:00
parent f88ac23903
commit 444b233b05
4 changed files with 36 additions and 13 deletions

View File

@@ -736,7 +736,7 @@ usteer_local_node_process_bss_tm_queries(struct uloop_timeout *timeout)
if (!si) if (!si)
continue; continue;
usteer_ubus_bss_transition_request(si, query->dialog_token, false, false, validity_period); usteer_ubus_bss_transition_request(si, query->dialog_token, false, false, validity_period, NULL);
} }
/* Free pending queries we can not handle */ /* Free pending queries we can not handle */

View File

@@ -114,7 +114,7 @@ is_better_candidate(struct sta_info *si_cur, struct sta_info *si_new)
static struct sta_info * static struct sta_info *
find_better_candidate(struct sta_info *si_ref, struct uevent *ev, uint32_t required_criteria, uint64_t max_age) find_better_candidate(struct sta_info *si_ref, struct uevent *ev, uint32_t required_criteria, uint64_t max_age)
{ {
struct sta_info *si; struct sta_info *si, *candidate = NULL;
struct sta *sta = si_ref->sta; struct sta *sta = si_ref->sta;
uint32_t reasons; uint32_t reasons;
@@ -143,10 +143,11 @@ find_better_candidate(struct sta_info *si_ref, struct uevent *ev, uint32_t requi
ev->select_reasons = reasons; ev->select_reasons = reasons;
} }
return si; if (candidate && si->signal > candidate->signal)
candidate = si;
} }
return NULL; return candidate;
} }
int int
@@ -297,25 +298,26 @@ usteer_roam_sm_start_scan(struct sta_info *si, struct uevent *ev)
usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, ev); usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, ev);
} }
static bool static struct sta_info *
usteer_roam_sm_found_better_node(struct sta_info *si, struct uevent *ev, enum roam_trigger_state next_state) usteer_roam_sm_found_better_node(struct sta_info *si, struct uevent *ev, enum roam_trigger_state next_state)
{ {
uint64_t max_age = 2 * config.roam_scan_interval; uint64_t max_age = 2 * config.roam_scan_interval;
struct sta_info *candidate;
if (max_age > current_time - si->roam_scan_start) if (max_age > current_time - si->roam_scan_start)
max_age = current_time - si->roam_scan_start; max_age = current_time - si->roam_scan_start;
if (find_better_candidate(si, ev, (1 << UEV_SELECT_REASON_SIGNAL), max_age)) { candidate = find_better_candidate(si, ev, (1 << UEV_SELECT_REASON_SIGNAL), max_age);
if (candidate)
usteer_roam_set_state(si, next_state, ev); usteer_roam_set_state(si, next_state, ev);
return true;
}
return false; return candidate;
} }
static bool static bool
usteer_roam_trigger_sm(struct usteer_local_node *ln, struct sta_info *si) usteer_roam_trigger_sm(struct usteer_local_node *ln, struct sta_info *si)
{ {
struct sta_info *candidate;
struct uevent ev = { struct uevent ev = {
.si_cur = si, .si_cur = si,
}; };
@@ -357,7 +359,12 @@ usteer_roam_trigger_sm(struct usteer_local_node *ln, struct sta_info *si)
break; break;
case ROAM_TRIGGER_SCAN_DONE: case ROAM_TRIGGER_SCAN_DONE:
usteer_ubus_bss_transition_request(si, 1, false, false, 100); candidate = usteer_roam_sm_found_better_node(si, &ev, ROAM_TRIGGER_SCAN_DONE);
/* Kick back in case no better node is found */
if (!candidate)
usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, &ev);
usteer_ubus_bss_transition_request(si, 1, false, false, 100, candidate->node);
si->kick_time = current_time; si->kick_time = current_time;
usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, &ev); usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, &ev);
break; break;

19
ubus.c
View File

@@ -611,6 +611,16 @@ usteer_add_nr_entry(struct usteer_node *ln, struct usteer_node *node)
return true; return true;
} }
static void
usteer_ubus_disassoc_add_neighbor(struct sta_info *si, struct usteer_node *node)
{
void *c;
c = blobmsg_open_array(&b, "neighbors");
usteer_add_nr_entry(si->node, node);
blobmsg_close_array(&b, c);
}
static void static void
usteer_ubus_disassoc_add_neighbors(struct sta_info *si) usteer_ubus_disassoc_add_neighbors(struct sta_info *si)
{ {
@@ -646,7 +656,8 @@ int usteer_ubus_bss_transition_request(struct sta_info *si,
uint8_t dialog_token, uint8_t dialog_token,
bool disassoc_imminent, bool disassoc_imminent,
bool abridged, bool abridged,
uint8_t validity_period) uint8_t validity_period,
struct usteer_node *target_node)
{ {
struct usteer_local_node *ln = container_of(si->node, struct usteer_local_node, node); struct usteer_local_node *ln = container_of(si->node, struct usteer_local_node, node);
@@ -656,7 +667,11 @@ int usteer_ubus_bss_transition_request(struct sta_info *si,
blobmsg_add_u8(&b, "disassociation_imminent", disassoc_imminent); blobmsg_add_u8(&b, "disassociation_imminent", disassoc_imminent);
blobmsg_add_u8(&b, "abridged", abridged); blobmsg_add_u8(&b, "abridged", abridged);
blobmsg_add_u32(&b, "validity_period", validity_period); blobmsg_add_u32(&b, "validity_period", validity_period);
usteer_ubus_disassoc_add_neighbors(si); if (!target_node) {
usteer_ubus_disassoc_add_neighbors(si);
} else {
usteer_ubus_disassoc_add_neighbor(si, target_node);
}
return ubus_invoke(ubus_ctx, ln->obj_id, "bss_transition_request", b.head, NULL, 0, 100); return ubus_invoke(ubus_ctx, ln->obj_id, "bss_transition_request", b.head, NULL, 0, 100);
} }

View File

@@ -336,7 +336,8 @@ int usteer_ubus_bss_transition_request(struct sta_info *si,
uint8_t dialog_token, uint8_t dialog_token,
bool disassoc_imminent, bool disassoc_imminent,
bool abridged, bool abridged,
uint8_t validity_period); uint8_t validity_period,
struct usteer_node *target_node);
struct sta *usteer_sta_get(const uint8_t *addr, bool create); struct sta *usteer_sta_get(const uint8_t *addr, bool create);
struct sta_info *usteer_sta_info_get(struct sta *sta, struct usteer_node *node, bool *create); struct sta_info *usteer_sta_info_get(struct sta *sta, struct usteer_node *node, bool *create);