diff --git a/src/cntlr.c b/src/cntlr.c index 7297fa1a3e8990554cefa124d14b6788bbcf0586..89fd3582624032b28488f2530fb6db8eb4fc4e4d 100644 --- a/src/cntlr.c +++ b/src/cntlr.c @@ -477,6 +477,71 @@ static int forall_node_update_neighbors(struct controller *c) } #endif + +void cntrl_send_max_wifi_bh_hops_policy(struct controller *c) +{ + struct node *node; + + if (c->cfg.max_node_bh_hops == 0) + return; + + + trace("%s: max_node_bh_hops %d\n", + __func__, c->cfg.max_node_bh_hops); + + list_for_each_entry(node, &c->nodelist, list) { + enum bh_control { + BLOCK = 0x00, + UNBLOCK = 0x01 + } bh_control = UNBLOCK; + struct bh_topology_dev *bh_topo_dev = + find_bh_topology_device(node->alid); + struct netif_radio *radio; + + if (!bh_topo_dev) { + err("%s: device not found in bh topo model, logical error.\n", __func__); + continue; + } + + if (bh_topo_dev->bh_info.level_in_tree == UNKNOWN_TREE_LEVEL) { + warn("%s: Level in BH treee unknown for: " MACFMT "\n", __func__, MAC2STR(node->alid)); + continue; + } + + if (c->cfg.max_node_bh_hops <= bh_topo_dev->bh_info.wifi_hops_from_root) + bh_control = BLOCK; + + list_for_each_entry(radio, &node->radiolist, list) { + struct netif_iface *iface; + + list_for_each_entry(iface, &radio->iflist, list) { + /* cppcheck-suppress uninitvar */ + if (iface->bss->is_bbss) { + const uint8_t NO_VALIDITY_PERIOD = 0; + uint8_t ALL_BSTAS[6] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + uint16_t mid; + + trace("%s: sending BH assoc_mode %s, node al_mac: " MACFMT + ", wifi_hops_from_root: %d, bssid: " MACFMT"\n", + __func__, + bh_control ? "UNBLOCK" : "BLOCK", + MAC2STR(node->alid), + bh_topo_dev->bh_info.wifi_hops_from_root, + MAC2STR(iface->bss->bssid)); + + cntlr_send_client_assoc_ctrl_request( + c, node->alid, iface->bss->bssid, + bh_control, NO_VALIDITY_PERIOD, 1, + ALL_BSTAS, &mid); + } + } + } + } +} + + void cntlr_update_sta_steer_counters(struct controller *c, uint8_t *sta_mac, uint8_t *src_bssid, diff --git a/src/cntlr.h b/src/cntlr.h index 570d0eae9dfb1dae733ad62084f6b38b01e7e112..d7383758dd50d41ad6cb3e1fb28ddbffc6807e02 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -419,5 +419,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); +void cntrl_send_max_wifi_bh_hops_policy(struct controller *c); #endif /* CNTLR_H */ diff --git a/src/cntlr_map.c b/src/cntlr_map.c index 7c3c718300d141b2e0d6c9302d2049618a0110da..49b0c7cc0e78e9790fe2d7ff62d11a666d16047c 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -637,7 +637,14 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n /* When all topology responses collected, build topology tree. */ if (!is_bh_topology_valid() && c->num_nodes == bh_topology_devs_number()) { + build_bh_topology_tree(c->almac); + + /* Send BH policy only when max_node_bh_hops is configured. */ + if (c->cfg.max_node_bh_hops != 0) { + /* Requires valid bBSS netif_iface info */ + cntrl_send_max_wifi_bh_hops_policy(c); + } } return 0; diff --git a/src/config.c b/src/config.c index 4cdecc83060d61824886a5c698ec1b6304a1fb73..9634e2c2c56ddbe56c734d4540c35347b260969f 100644 --- a/src/config.c +++ b/src/config.c @@ -632,6 +632,7 @@ static int cntlr_config_get_base(struct controller_config *c, CNTLR_DEFAULT_PCP, CNTLR_ENABLE_TS, CNTLR_PROFILE, + CNTRL_MAX_NODE_BH_HOPS, NUM_CNTLR_ATTRS }; @@ -648,6 +649,7 @@ static int cntlr_config_get_base(struct controller_config *c, [CNTLR_DEFAULT_PCP] = { .name = "default_pcp", .type = UCI_TYPE_STRING }, [CNTLR_ENABLE_TS] = { .name = "enable_ts", .type = UCI_TYPE_STRING }, [CNTLR_PROFILE] = { .name = "profile", .type = UCI_TYPE_STRING }, + [CNTRL_MAX_NODE_BH_HOPS] = { .name = "max_node_bh_hops", .type = UCI_TYPE_STRING }, }; struct uci_option *tb[NUM_CNTLR_ATTRS]; @@ -734,6 +736,13 @@ static int cntlr_config_get_base(struct controller_config *c, c->enable_ts = !!atoi(val); } + if (tb[CNTRL_MAX_NODE_BH_HOPS]) { + const char *val = tb[CNTRL_MAX_NODE_BH_HOPS]->v.string; + const int max_hops = atoi(val); + + c->max_node_bh_hops = (max_hops > 0) ? max_hops : 0; + } + return 0; } diff --git a/src/config.h b/src/config.h index c057daa2e79e9d28b49cb5fb68777a26cff4937b..a7e8b85aaa3df725f43b9e557edc4081792fcac8 100644 --- a/src/config.h +++ b/src/config.h @@ -167,6 +167,7 @@ struct controller_config { unsigned int default_pcp; int map_profile; bool enable_ts; + unsigned int max_node_bh_hops; #if (EASYMESH_VERSION > 2) char *dpp_uri_file; #endif