From b456984731b1e6c485fb828e22288bf1cc706420 Mon Sep 17 00:00:00 2001 From: Kamil Zulewski <kamil.zulewski@iopsys.eu> Date: Fri, 19 May 2023 16:01:07 +0200 Subject: [PATCH] Limiting length of Wi-Fi BH links chains * Don't send BH BSS WSC TLV for nodes exceeding max_node_bh_hops limit --- src/cntlr.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cntlr.h | 2 ++ src/cntlr_cmdu.c | 4 ++++ src/cntlr_ubus.c | 9 ++++--- src/cntlr_ubus.h | 4 ++-- 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/cntlr.c b/src/cntlr.c index c419a367..2be39cfd 100644 --- a/src/cntlr.c +++ b/src/cntlr.c @@ -915,6 +915,67 @@ struct sta *cntlr_add_sta(struct controller *c, uint8_t *macaddr) return s; } +bool is_bh_bss_allowed_on_node(struct controller *c, uint8_t *al_mac) +{ + bool bh_bss_allowed = false; + bool is_root_node = false; + + if (c->cfg.max_node_bh_hops == 0) { + dbg("%s: No Max Node BH Hops limitation configured, \ + BH BSS allowed on all nodes.\n", __func__); + + return true; + } + + if (hwaddr_is_zero(c->almac)) { + err("%s: unknown controller AL mac\n", __func__); + return true; + } + + is_root_node = hwaddr_equal(c->almac, al_mac); + + switch (c->cfg.max_node_bh_hops) { + case 1: { + /* BH BSS allowed only on root node */ + bh_bss_allowed = is_root_node; + + } break; + case 2: { + /* BH BSS allowed on root node and immediate neighbors */ + if (is_root_node) { + bh_bss_allowed = true; + } else { + struct ieee1905_neighbor_dyn_array neighbors = { 0 }; + int i; + + if (!cntrl_get_ieee1905_neighbors(c, &neighbors)) { + err("%s: unsuccessfull ieee1905 neighbors ubus call.\n", __func__); + return true; + } + + for (i = 0; i < neighbors.neighbors_size; ++i) { + if (neighbors.neighbors[i].is_immediate && + hwaddr_equal(neighbors.neighbors[i].al_mac, al_mac)) { + bh_bss_allowed = true; + break; + } + } + + free(neighbors.neighbors); + } + } break; + default: { + /* For 3 and higher values BH BSS allowed on all nodes currently */ + bh_bss_allowed = true; + } break; + } + + info("%s: BH BSS allowed on node[" MACFMT "]: %s\n", __func__, + MAC2STR(al_mac), bh_bss_allowed ? "yes" : "no"); + + return bh_bss_allowed; +} + static void forall_node_get_sta_metrics(struct controller *c) { struct sta *s = NULL; @@ -2103,3 +2164,4 @@ out_exit: uloop_done(); free(c); } + diff --git a/src/cntlr.h b/src/cntlr.h index e7510ba4..fed6570a 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -422,4 +422,6 @@ int cntlr_sync_dyn_controller_config(struct controller *c, uint8_t *agent); void cntlr_load_steer_modules(struct controller *c); void cntlr_unload_steer_modules(struct controller *c); +bool is_bh_bss_allowed_on_node(struct controller *c, uint8_t *al_mac); + #endif /* CNTLR_H */ diff --git a/src/cntlr_cmdu.c b/src/cntlr_cmdu.c index 24cc9051..2cc11ec0 100644 --- a/src/cntlr_cmdu.c +++ b/src/cntlr_cmdu.c @@ -635,6 +635,10 @@ struct cmdu_buff *cntlr_gen_ap_autoconfig_wsc(struct controller *c, if (cred->band != e_band) continue; + if (cred->mode == AP_WIFI_BBSS && + !is_bh_bss_allowed_on_node(c, rx_cmdu->origin)) + continue; + /* Will return non-zero if band did not match OR on failure */ cntlr_gen_wsc(c, resp, cred, msg, msglen, e_band, e_auth); } diff --git a/src/cntlr_ubus.c b/src/cntlr_ubus.c index 11a20d55..54836316 100644 --- a/src/cntlr_ubus.c +++ b/src/cntlr_ubus.c @@ -3733,8 +3733,8 @@ static void ieee1905_cb_get_neighbors(struct ubus_request *req, int type, [NEIGHBOR_ARRAY] = { .name = "neighbors", .type = BLOBMSG_TYPE_ARRAY }, }; struct blob_attr *tb[POLICY_LEN]; - struct ieee1905_neighbor_array *output_array = - (struct ieee1905_neighbor_array *)req->priv; + struct ieee1905_neighbor_dyn_array *output_array = + (struct ieee1905_neighbor_dyn_array *)req->priv; blobmsg_parse(policy, POLICY_LEN, tb, blob_data(msg), blob_len(msg)); @@ -3784,7 +3784,7 @@ static void ieee1905_cb_get_neighbors(struct ubus_request *req, int type, } int cntrl_get_ieee1905_neighbors(struct controller *c, - struct ieee1905_neighbor_array *neighbors) + struct ieee1905_neighbor_dyn_array *neighbors) { uint32_t obj; int ret; @@ -3798,5 +3798,8 @@ int cntrl_get_ieee1905_neighbors(struct controller *c, ieee1905_cb_get_neighbors, neighbors); + if (neighbors->neighbors_size > 0 && !neighbors->neighbors) + ret = -1; + return ret; } diff --git a/src/cntlr_ubus.h b/src/cntlr_ubus.h index 6acbb3fc..223e0dd3 100644 --- a/src/cntlr_ubus.h +++ b/src/cntlr_ubus.h @@ -38,12 +38,12 @@ struct ieee1905_neighbor { bool is_immediate; }; -struct ieee1905_neighbor_array { +struct ieee1905_neighbor_dyn_array { struct ieee1905_neighbor *neighbors; uint32_t neighbors_size; }; int cntrl_get_ieee1905_neighbors(struct controller *c, - struct ieee1905_neighbor_array *neighbors); + struct ieee1905_neighbor_dyn_array *neighbors); #endif /* CNTLR_UBUS_H */ -- GitLab