From a5bac33bdecfe0bdd24217fbcfefbc127079695b Mon Sep 17 00:00:00 2001 From: Anjan Chanda <anjan.chanda@genexis.eu> Date: Mon, 9 Jun 2025 17:02:32 +0200 Subject: [PATCH 1/2] update node's stalist from Topology Response --- src/cntlr.c | 21 ++++++++++++++++ src/cntlr.h | 1 + src/cntlr_map.c | 65 +++++++++++++++++++++++++++---------------------- 3 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/cntlr.c b/src/cntlr.c index f40e635b..49a9a247 100644 --- a/src/cntlr.c +++ b/src/cntlr.c @@ -521,6 +521,27 @@ struct sta *node_find_sta(struct node *n, uint8_t *macaddr) return NULL; } +void node_update_stalist(struct node *n, uint8_t *stalist, int num) +{ + struct sta *s = NULL, *tmp; + + list_for_each_entry_safe(s, tmp, &n->stalist, list) { + bool found = false; + + for (int i = 0; i < num; i++) { + if (!memcmp(s->macaddr, &stalist[i*6], 6)) { + found = true; + break; + } + } + + if (!found) { + list_del(&s->list); + n->sta_count--; + } + } +} + struct unassoc_sta_metrics *cntlr_find_usta_metric(struct controller *c, struct sta *s, uint8_t *agent_macaddr) diff --git a/src/cntlr.h b/src/cntlr.h index a7ea588a..3667a16c 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -415,6 +415,7 @@ void cntrl_send_max_wifi_bh_hops_policy(struct controller *c); void node_add_sta(struct node *n, struct sta *s); void node_del_sta(struct node *n, struct sta *s); struct sta *node_find_sta(struct node *n, uint8_t *sta_macaddr); +void node_update_stalist(struct node *n, uint8_t *stalist, int num); int cntlr_register_steer_module(struct controller *c, const char *name); int cntlr_unregister_steer_module(struct controller *c, char *name); diff --git a/src/cntlr_map.c b/src/cntlr_map.c index 4cd4022c..ad7beaee 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -566,19 +566,19 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n #endif if (tv[TOPOLOGY_RESPONSE_ASSOCIATED_CLIENTS_IDX][0]) { - struct tlv_assoc_client *tlv; - uint8_t *tv_data; + struct tlv_assoc_client *tlv = (struct tlv_assoc_client *) + tv[TOPOLOGY_RESPONSE_ASSOCIATED_CLIENTS_IDX][0]->data; + uint8_t *tv_data = (uint8_t *)tlv; int i, offset = 0; + uint8_t stas[256 * 6]; + int max_stas = sizeof(stas) / sizeof(stas[0]); + memset(stas, 0, sizeof(stas)); + int idx = 0; - tlv = (struct tlv_assoc_client *) - tv[TOPOLOGY_RESPONSE_ASSOCIATED_CLIENTS_IDX][0]->data; if (!tlv) return -1; - tv_data = (uint8_t *)tlv; - offset += 1; /* num_bss */ - for (i = 0; i < tlv->num_bss; i++) { struct netif_iface *bss_iface; uint8_t bssid[6] = {0}; @@ -597,14 +597,18 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n continue; } + if (!num_client) + continue; + for (j = 0; j < num_client; j++) { struct netif_iface *bsta_iface = NULL; uint8_t macaddr[6] = {0}; uint16_t conntime; - enum sta_state old_state; struct sta *s; memcpy(macaddr, &tv_data[offset], 6); + if (idx < max_stas) + memcpy(&stas[6*idx++], &tv_data[offset], 6); offset += 6; /* macaddr */ conntime = BUF_GET_BE16(tv_data[offset]); offset += 2; /* conntime */ @@ -613,6 +617,8 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n s = cntlr_find_sta(c->sta_table, macaddr); if (!s) { + struct cmdu_buff *txcmdu; + s = cntlr_add_sta(c, c->sta_table, macaddr); if (!s) { cntlr_dbg(LOG_STA, "%s: failed to add STA " MACFMT "\n", @@ -620,37 +626,37 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n continue; } + s->state = STA_CONNECTED; + memcpy(s->bssid, bssid, 6); + memset(s->ssid, 0, sizeof(s->ssid)); + memcpy(s->ssid, bss_iface->bss->ssid, bss_iface->bss->ssidlen); + s->ssidlen = bss_iface->bss->ssidlen; + s->de_sta->conn_time = conntime; + s->assoc_time = time(NULL) - conntime; + + node_add_sta(n, s); cntlr_dbg(LOG_STA, "%s: STA " MACFMT " connected to Node " MACFMT "\n", __func__, MAC2STR(s->macaddr), MAC2STR(n->almacaddr)); - } - old_state = s->state; - s->is_bsta = bsta_iface || bss_iface->bss->is_bbss ? true : false; - memcpy(s->bssid, bssid, 6); - memset(s->ssid, 0, sizeof(s->ssid)); - memcpy(s->ssid, bss_iface->bss->ssid, bss_iface->bss->ssidlen); - s->ssidlen = bss_iface->bss->ssidlen; - - s->de_sta->conn_time = conntime; - s->state = conntime != 0 ? STA_ASSOCIATED : STA_DISCONNECTED; - if (old_state != STA_ASSOCIATED && s->state == STA_ASSOCIATED) { - struct cmdu_buff *txcmdu; - - node_add_sta(n, s); - time(&s->assoc_time); txcmdu = cntlr_gen_client_caps_query(c, - c->almacaddr, - s->macaddr, - s->bssid); + c->almacaddr, + s->macaddr, + s->bssid); if (txcmdu) { send_cmdu(c, txcmdu); cmdu_free(txcmdu); } - } else if (old_state != STA_DISCONNECTED && s->state == STA_DISCONNECTED) { - node_del_sta(n, s); - time(&s->disassoc_time); + } else { + /* ignore conflicting STA-association from multiple Agents */ + if (memcmp(s->agent_almacaddr, n->almacaddr, 6) || + memcmp(s->bssid, bssid, 6)) { + continue; + } + + s->de_sta->conn_time = conntime; } + s->is_bsta = bsta_iface || bss_iface->bss->is_bbss ? true : false; if (bsta_iface) { memcpy(bsta_iface->upstream_bssid, bssid, 6); @@ -663,6 +669,7 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n cntlr_update_sta_steer_data(c, s); } } + node_update_stalist(n, stas, (idx <= max_stas ? idx : max_stas)); } /* Check opclass preferency age */ -- GitLab From 7c783545bb06b9edbcd537f852f9171db42cbbf3 Mon Sep 17 00:00:00 2001 From: Filip Matusiak <filip.matusiak@iopsys.eu> Date: Mon, 2 Jun 2025 16:18:32 +0200 Subject: [PATCH 2/2] Use timer to remove stale clients - Use sta timer instead of iterating over stalists every second - Only remove stations with no active node from client hashtable - Fix topology notification to properly update stalists - Remove STA from old node before adding to new one - Don't add sta with MAC unset - Free all STA upon exit --- src/cntlr.c | 142 +++++++++++++++++++++++++++++++----------------- src/cntlr.h | 5 +- src/cntlr_map.c | 75 ++++++++++++------------- src/sta.c | 74 ++++++++++++++++++++----- src/sta.h | 9 ++- 5 files changed, 198 insertions(+), 107 deletions(-) diff --git a/src/cntlr.c b/src/cntlr.c index 49a9a247..4d4f7733 100644 --- a/src/cntlr.c +++ b/src/cntlr.c @@ -231,6 +231,23 @@ struct node *cntlr_find_node_with_bssid(struct controller *c, uint8_t *bssid) return NULL; } +/* returns first found node with given STA MAC on its stalist */ +struct node *cntlr_find_node_with_sta(struct controller *c, uint8_t *stamacaddr) +{ + struct node *n = NULL; + + list_for_each_entry(n, &c->nodelist, list) { + struct sta *e = NULL; + + list_for_each_entry(e, &n->stalist, list) { + if (!memcmp(e->macaddr, stamacaddr, 6)) + return n; + } + } + + return NULL; +} + #if (EASYMESH_VERSION >= 6) bool cntlr_radio_support_ap_wifi7(struct wifi7_radio_capabilities *wifi7_caps) { @@ -482,31 +499,77 @@ void cntlr_bcn_metrics_timer_cb(atimer_t *t) } } -void node_add_sta(struct node *n, struct sta *s) +static void cntlr_freeze_sta(struct controller *c, struct sta *s) +{ + timer_del(&s->bcn_metrics_timer); + timer_del(&s->btm_req_timer); + timer_del(&s->ageout_timer); + + sta_free_assoc_frame(s); + sta_free_bcn_metrics(s); + cntlr_clean_bcnreqlist_sta(c, s); +} + +static void cntlr_remove_sta(struct controller *c, struct sta *s) +{ + struct node *n = NULL; + + do { + n = cntlr_find_node_with_sta(c, s->macaddr); + if (n) + node_del_sta(n, s); + } while (n); + + cntlr_freeze_sta(c, s); + cntlr_del_sta(c->sta_table, s); +} + +void cntlr_sta_ageout_timer_cb(atimer_t *t) +{ + trace("%s: --->\n", __func__); + + struct sta *s = container_of(t, struct sta, ageout_timer); + struct controller *c = s->cntlr; + + if (!c) + return; + + cntlr_dbg(LOG_STA, "%s: Delete STA " MACFMT " after %ds of disassociation\n", + __func__, MAC2STR(s->macaddr), c->cfg.stale_sta_timeout); + cntlr_remove_sta(c, s); +} + +int node_add_sta(struct node *n, struct sta *s) { if (WARN_ON(node_find_sta(n, s->macaddr))) { cntlr_dbg(LOG_STA, "%s: Warn! STA " MACFMT " already in node " MACFMT"\n", __func__, MAC2STR(s->macaddr), MAC2STR(n->almacaddr)); - return; + return -1; } memcpy(s->agent_almacaddr, n->almacaddr, 6); list_add(&s->list, &n->stalist); n->sta_count++; + sta_inc_ref(s); + + return 0; } -void node_del_sta(struct node *n, struct sta *s) +int node_del_sta(struct node *n, struct sta *s) { if (WARN_ON(!node_find_sta(n, s->macaddr))) { cntlr_dbg(LOG_STA, "%s: Warn! STA " MACFMT " not in node " MACFMT"\n", __func__, MAC2STR(s->macaddr), MAC2STR(n->almacaddr)); - return; + return -1; } list_del(&s->list); n->sta_count--; + sta_dec_ref(s); + + return 0; } struct sta *node_find_sta(struct node *n, uint8_t *macaddr) @@ -538,6 +601,7 @@ void node_update_stalist(struct node *n, uint8_t *stalist, int num) if (!found) { list_del(&s->list); n->sta_count--; + sta_dec_ref(s); } } } @@ -556,23 +620,6 @@ struct unassoc_sta_metrics *cntlr_find_usta_metric(struct controller *c, return NULL; } -static void cntlr_freeze_sta(struct controller *c, struct sta *s) -{ - timer_del(&s->bcn_metrics_timer); - timer_del(&s->btm_req_timer); - - sta_free_assoc_frame(s); - sta_free_bcn_metrics(s); - cntlr_clean_bcnreqlist_sta(c, s); -} - -static void cntlr_remove_sta(struct controller *c, struct node *n, struct sta *s) -{ - cntlr_freeze_sta(c, s); - node_del_sta(n, s); - cntlr_del_sta(c->sta_table, s->macaddr); -} - struct cmdu_buff *cntlr_query_sta_metric(struct controller *c, struct sta *s) { if (!c || !s) @@ -900,7 +947,7 @@ static void node_clean_stalist(struct controller *c, struct node *n) return; list_for_each_entry_safe(s, tmp, &n->stalist, list) { - cntlr_remove_sta(c, n, s); + node_del_sta(n, s); } if (WARN_ON(n->sta_count != 0)) { @@ -915,6 +962,27 @@ static void cntlr_clean_mac_hashtable(struct controller *c) mactable_flush(c->mac_table); } +static void cntlr_clean_all_sta(struct controller *c) +{ + struct hlist_node *tmp = NULL; + int i; + + for (i = 0; i < MAC_HASHTABLE_SIZE; i++) { + struct sta *s = NULL; + + if (hlist_empty(&c->sta_table[i])) + continue; + + hlist_for_each_entry_safe(s, tmp, &c->sta_table[i], hlist) { + hlist_del(&s->hlist, &c->sta_table[i]); + cntlr_freeze_sta(c, s); + cntlr_free_sta(s); + } + } + + c->num_sta = 0; +} + static void cntlr_clean_nodelist(struct controller *c) { struct node *n = NULL, *tmp; @@ -1720,34 +1788,6 @@ static void cntlr_event_handler(struct ubus_context *ctx, free(str); } -//FIXME: move to history -static void cntlr_remove_stale_sta(struct controller *c) -{ - struct node *n = NULL; - time_t curr_time; - - if (!c) - return; - - time(&curr_time); - list_for_each_entry(n, &c->nodelist, list) { - struct sta *s = NULL, *tmp; - - list_for_each_entry_safe(s, tmp, &n->stalist, list) { - if (s->state != STA_ASSOCIATED && s->disassoc_time != 0) { - if ((curr_time - s->disassoc_time) >= c->cfg.stale_sta_timeout) { - cntlr_dbg(LOG_STA, - "%s: Delete STA " MACFMT " after %ds of disassociation\n", - __func__, MAC2STR(s->macaddr), - c->cfg.stale_sta_timeout); - - cntlr_remove_sta(c, n, s); - } - } - } - } -} - static void cntlr_periodic_run(atimer_t *t) { struct controller *c = container_of(t, struct controller, heartbeat); @@ -1774,7 +1814,6 @@ static void cntlr_periodic_run(atimer_t *t) } #endif cntlr_ageout_nodes(c); - cntlr_remove_stale_sta(c); timer_set(&c->heartbeat, 1 * 1000); } @@ -1925,6 +1964,7 @@ out_exit: cntlr_clean_bcnreqlist(c); cntlr_clean_linklist(c); cntlr_clean_nodelist(c); + cntlr_clean_all_sta(c); free_topology(&c->topology); ubus_unregister_event_handler(ctx, &c->evh); cntlr_remove_object(c); diff --git a/src/cntlr.h b/src/cntlr.h index 3667a16c..d36b5d6c 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -366,6 +366,7 @@ struct node *cntlr_add_node(struct controller *c, uint8_t *almacaddr); struct node *cntlr_alloc_node(struct controller *c, uint8_t *almacaddr); struct node *cntlr_find_node(struct controller *c, uint8_t *almacaddr); struct node *cntlr_find_node_with_bssid(struct controller *c, uint8_t *bssid); +struct node *cntlr_find_node_with_sta(struct controller *c, uint8_t *stamacaddr); struct netif_link *cntlr_alloc_link(struct controller *c, uint8_t *upstream, uint8_t *downstream); @@ -412,8 +413,8 @@ int cntlr_sync_dyn_controller_config(struct controller *c, uint8_t *agent); void cntrl_send_max_wifi_bh_hops_policy(struct controller *c); -void node_add_sta(struct node *n, struct sta *s); -void node_del_sta(struct node *n, struct sta *s); +int node_add_sta(struct node *n, struct sta *s); +int node_del_sta(struct node *n, struct sta *s); struct sta *node_find_sta(struct node *n, uint8_t *sta_macaddr); void node_update_stalist(struct node *n, uint8_t *stalist, int num); diff --git a/src/cntlr_map.c b/src/cntlr_map.c index ad7beaee..e98bf2eb 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -228,25 +228,24 @@ int handle_topology_notification(void *cntlr, struct cmdu_buff *cmdu, return 0; } - bsta_iface = cntlr_find_iface_type(c, ev->macaddr, MAC_ENTRY_BSTA); - s = cntlr_find_sta(c->sta_table, ev->macaddr); - if (associated) { - struct node *old_n = NULL; - - if (!s) { + if (s) { + if (associated) { struct cmdu_buff *txcmdu; - s = cntlr_add_sta(c, c->sta_table, ev->macaddr); - if (!s) { - cntlr_dbg(LOG_STA, "%s: failed to add STA " MACFMT "\n", - __func__, MAC2STR(ev->macaddr)); - return -1; - } - time(&s->assoc_time); - s->state = STA_ASSOCIATED; memcpy(s->bssid, ev->bssid, 6); + s->state = STA_ASSOCIATED; + + if (memcmp(s->agent_almacaddr, n->almacaddr, 6)) { + /* associated to a new node - remove from the old one */ + struct node *old_n = NULL; + + old_n = cntlr_find_node(c, s->agent_almacaddr); + if (old_n) + node_del_sta(old_n, s); + } + node_add_sta(n, s); txcmdu = cntlr_gen_client_caps_query(c, c->almacaddr, s->macaddr, s->bssid); @@ -254,26 +253,31 @@ int handle_topology_notification(void *cntlr, struct cmdu_buff *cmdu, send_cmdu(c, txcmdu); cmdu_free(txcmdu); } - - goto inform_steer_plugins; - } - - /* remove sta from old-node and add to new-node */ - old_n = cntlr_find_node(c, s->agent_almacaddr); - if (old_n) { - if (node_find_sta(old_n, s->macaddr)) { + } else { + if (!memcmp(s->agent_almacaddr, n->almacaddr, 6)) { + /* disassociated from current node */ time(&s->disassoc_time); + memset(s->bssid, 0, sizeof(s->bssid)); s->state = STA_DISCONNECTED; - node_del_sta(old_n, s); } - } - if (!node_find_sta(n, ev->macaddr)) { + node_del_sta(n, s); + } + } else { /* unknown sta */ + if (associated) { struct cmdu_buff *txcmdu; + s = cntlr_add_sta(c, c->sta_table, ev->macaddr); + if (!s) { + cntlr_dbg(LOG_STA, "%s: failed to add STA " MACFMT "\n", + __func__, MAC2STR(ev->macaddr)); + return -1; + } + time(&s->assoc_time); - s->state = STA_ASSOCIATED; memcpy(s->bssid, ev->bssid, 6); + s->state = STA_ASSOCIATED; + node_add_sta(n, s); txcmdu = cntlr_gen_client_caps_query(c, c->almacaddr, s->macaddr, s->bssid); @@ -281,34 +285,27 @@ int handle_topology_notification(void *cntlr, struct cmdu_buff *cmdu, send_cmdu(c, txcmdu); cmdu_free(txcmdu); } - } - } else { - if (!s) { + } else { cntlr_dbg(LOG_STA, "Ignore unknown STA " MACFMT " disassoc event\n", MAC2STR(ev->macaddr)); return 0; } - - if (node_find_sta(n, ev->macaddr)) { - time(&s->disassoc_time); - s->state = STA_DISCONNECTED; - node_del_sta(n, s); - } } + bsta_iface = cntlr_find_iface_type(c, ev->macaddr, MAC_ENTRY_BSTA); s->is_bsta = bsta_iface || bh ? true : false; cntlr_info(LOG_STA, "%s: STA " MACFMT " %s Node " MACFMT"\n", __func__, MAC2STR(s->macaddr), s->state == STA_ASSOCIATED ? "associated to" : "disconnected from", MAC2STR(s->agent_almacaddr)); - } -inform_steer_plugins: - if (s) { cntlr_update_sta_steer_data(c, s); + } + if (s) { + /* Inform steering plugins */ c->inform_cmdu_type = CMDU_TYPE_TOPOLOGY_NOTIFICATION; c->inform_sta_num = 1; memset(c->inform_stalist, 0, sizeof(c->inform_stalist)); @@ -571,7 +568,7 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n uint8_t *tv_data = (uint8_t *)tlv; int i, offset = 0; uint8_t stas[256 * 6]; - int max_stas = sizeof(stas) / sizeof(stas[0]); + int max_stas = sizeof(stas) / 6; memset(stas, 0, sizeof(stas)); int idx = 0; diff --git a/src/sta.c b/src/sta.c index 9782d552..2ef03adb 100644 --- a/src/sta.c +++ b/src/sta.c @@ -15,6 +15,7 @@ #include <easy/easy.h> #include <wifidefs.h> +#include "cntlr.h" #include "steer_module.h" #include "timer.h" #include "utils/debug.h" @@ -23,6 +24,7 @@ extern void cntlr_bcn_metrics_timer_cb(atimer_t *t); extern void cntlr_btm_req_timer_cb(atimer_t *t); +extern void cntlr_sta_ageout_timer_cb(atimer_t *t); struct sta *cntlr_find_sta(struct hlist_head *table, uint8_t *macaddr) { @@ -53,6 +55,7 @@ static struct sta *sta_alloc(uint8_t *macaddr) memcpy(s->macaddr, macaddr, 6); timer_init(&s->bcn_metrics_timer, cntlr_bcn_metrics_timer_cb); timer_init(&s->btm_req_timer, cntlr_btm_req_timer_cb); + timer_init(&s->ageout_timer, cntlr_sta_ageout_timer_cb); time(&s->lookup_time); s->de_sta = (struct wifi_sta_element *)(s + 1); @@ -101,9 +104,9 @@ struct sta *cntlr_add_sta(void *cntlr, struct hlist_head *table, uint8_t *macadd if (least_used_sta) { cntlr_dbg(LOG_STA, "%s: remove least used STA " MACFMT - " to add new STA " MACFMT "\n", __func__, - MAC2STR(least_used_sta->de_sta->macaddr), - MAC2STR(macaddr)); + " to add new STA " MACFMT "\n", __func__, + MAC2STR(least_used_sta->de_sta->macaddr), + MAC2STR(macaddr)); node_remove_sta(c, n, least_used_sta); } else { @@ -112,6 +115,10 @@ struct sta *cntlr_add_sta(void *cntlr, struct hlist_head *table, uint8_t *macadd } } #endif + if (WARN_ON(hwaddr_is_zero(macaddr))) { + /* should never happen */ + return NULL; + } s = sta_alloc(macaddr); if (!s) @@ -125,24 +132,39 @@ struct sta *cntlr_add_sta(void *cntlr, struct hlist_head *table, uint8_t *macadd return s; } -void cntlr_del_sta(struct hlist_head *table, uint8_t *macaddr) +void cntlr_del_sta_hash(struct hlist_head *table, uint8_t *macaddr) { + int idx; struct hlist_node *tmp = NULL; struct sta *s = NULL; - int idx; + bool found = false; idx = sta_hash(macaddr); - if (hlist_empty(&table[idx])) - return; - - hlist_for_each_entry_safe(s, tmp, &table[idx], hlist) { - if (!memcmp(s->macaddr, macaddr, 6)) { - hlist_del(&s->hlist, &table[idx]); - s->cntlr = NULL; - sta_free(s); - return; + if (!hlist_empty(&table[idx])) { + hlist_for_each_entry_safe(s, tmp, &table[idx], hlist) { + if (!memcmp(s->macaddr, macaddr, 6)) { + hlist_del(&s->hlist, &table[idx]); + found = true; + } } } + + if (!found) { + cntlr_warn(LOG_STA, "%s: STA " MACFMT " not found in table\n", + __func__, MAC2STR(macaddr)); + } +} + +void cntlr_free_sta(struct sta *del) +{ + del->cntlr = NULL; + sta_free(del); +} + +void cntlr_del_sta(struct hlist_head *table, struct sta *del) +{ + cntlr_del_sta_hash(table, del->macaddr); + cntlr_free_sta(del); } int sta_link_metrics_process(struct sta *s) @@ -191,3 +213,27 @@ void sta_free_assoc_frame(struct sta *s) free(s->de_sta->reassoc_frame); s->de_sta->reassoc_framelen = 0; } + +int sta_inc_ref(struct sta *s) +{ + s->nref++; + + if (timer_pending(&s->ageout_timer)) + timer_del(&s->ageout_timer); + + return s->nref; +} + +int sta_dec_ref(struct sta *s) +{ + struct controller *c = s->cntlr; + + if (WARN_ON(s->nref == 0)) + return 0; + + s->nref--; + if (s->nref == 0) + timer_set(&s->ageout_timer, c->cfg.stale_sta_timeout * 1000); + + return s->nref; +} diff --git a/src/sta.h b/src/sta.h index 244691f1..29b6271b 100644 --- a/src/sta.h +++ b/src/sta.h @@ -48,6 +48,8 @@ struct sta { time_t assoc_time; time_t disassoc_time; uint16_t disassoc_reason; + atimer_t ageout_timer; + uint8_t nref; /* num of nodes STA is associated to */ struct wifi_sta_element *de_sta; @@ -73,10 +75,15 @@ struct sta { struct sta *cntlr_find_sta(struct hlist_head *table, uint8_t *macaddr); struct sta *cntlr_add_sta(void *cntlr, struct hlist_head *table, uint8_t *macaddr); -void cntlr_del_sta(struct hlist_head *table, uint8_t *macaddr); +void cntlr_free_sta(struct sta *s); +void cntlr_del_sta_hash(struct hlist_head *table, uint8_t *macaddr); +void cntlr_del_sta(struct hlist_head *table, struct sta *del); int sta_link_metrics_process(struct sta *s); void sta_free_bcn_metrics(struct sta *s); void sta_free_usta_metrics(struct sta *s); void sta_free_assoc_frame(struct sta *s); + +int sta_inc_ref(struct sta *s); +int sta_dec_ref(struct sta *s); #endif /* STA_H */ -- GitLab