diff --git a/src/acs.c b/src/acs.c index 6c014f083ec8dfc56171c2db1cf9f28cb4cc1c37..78a3aa45531493f52d9aecab6b83ed95c654ae13 100644 --- a/src/acs.c +++ b/src/acs.c @@ -18,6 +18,7 @@ #include "cntlr.h" #include "cntlr_cmdu.h" #include "utils/debug.h" +#include "utils/liblist.h" #include "wifi_dataelements.h" #include "wifi_opclass.h" @@ -364,7 +365,7 @@ void cntlr_acs_recalc(struct controller *c, bool skip_dfs) { struct node *n = NULL; - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { cntlr_acs_node_channel_recalc(n, skip_dfs); } } @@ -492,7 +493,7 @@ void cntlr_dfs_cleanup(struct controller *c) { struct node *n = NULL; - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { cntlr_dfs_node_cleanup(n); } } diff --git a/src/cntlr.c b/src/cntlr.c index 9d290cd4bcacf475b2954ede6de9eab2cd8abd65..374bceee383f018e57b86799574bb2d377a6c565 100644 --- a/src/cntlr.c +++ b/src/cntlr.c @@ -50,6 +50,7 @@ #include "timer_impl.h" #include "topology.h" #include "utils/debug.h" +#include "utils/liblist.h" #include "utils/utils.h" #include "wifi_dataelements.h" #include "wifi_opclass.h" @@ -120,6 +121,17 @@ struct node *cntlr_find_node(struct controller *c, uint8_t *macaddr) return (struct node *)entry->data; } +bool cntlr_node_is_active(struct controller *c, uint8_t *macaddr) +{ + struct macaddr_entry *entry = NULL; + + entry = mactable_lookup(c->mac_table, macaddr, MAC_ENTRY_ALID); + if (WARN_ON(!entry)) + return false; + + return (((struct node *)entry->data)->is_active); +} + /* finds radio struct from interface macaddr */ struct netif_radio *cntlr_find_radio_with_bssid(struct controller *c, uint8_t *bssid) { @@ -413,7 +425,7 @@ void cntlr_send_max_wifi_bh_hops_policy(struct controller *c) trace("%s: max_node_bh_hops %d\n", __func__, c->cfg.max_node_bh_hops); - list_for_each_entry(node, &c->nodelist, list) { + list_for_each_active_entry(node, &c->nodelist, list) { enum bh_control { BLOCK = 0x00, UNBLOCK = 0x01 @@ -562,6 +574,12 @@ struct cmdu_buff *cntlr_query_sta_metric(struct controller *c, struct sta *s) return NULL; } + if (!cntlr_node_is_active(c, s->agent_almacaddr)) { + cntlr_dbg(LOG_STA, "%s: Agent " MACFMT " is not active\n", + __func__, MAC2STR(s->agent_almacaddr)); + return NULL; + } + return cntlr_gen_sta_metric_query(c, s->agent_almacaddr, s->macaddr); } @@ -569,7 +587,7 @@ static void cntlr_get_all_sta_metrics(struct controller *c) { struct node *n = NULL; - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_entry(n, &c->nodelist, list) { /* also inactive */ struct sta *s = NULL; list_for_each_entry(s, &n->stalist, list) { @@ -1042,7 +1060,7 @@ static void cntlr_query_nodes(atimer_t *t) struct controller *c = container_of(t, struct controller, query_nodes); struct node *n = NULL; - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { struct cmdu_buff *cmdu; cmdu = cntlr_gen_bk_caps_query(c, n->almacaddr); @@ -1089,7 +1107,7 @@ bool cntlr_check_config_diff(struct controller *c, uint32_t diff) trace("agent policy config changed\n"); /* send the policy config cmdu to the marked agent */ - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { struct cmdu_buff *cmdu; int num_bk = 0; uint8_t bk_id[16 * 6] = {0}; @@ -1140,7 +1158,7 @@ bool cntlr_check_config_diff(struct controller *c, uint32_t diff) cntlr_dbg(LOG_QOS, "qos config changed\n"); /* send the policy config cmdu to the marked agent */ - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { cntlr_qos_sync_node(c, n->almacaddr); } } @@ -1152,7 +1170,7 @@ bool cntlr_check_config_diff(struct controller *c, uint32_t diff) trace("ap mld config changed\n"); /* send the ap mld config cmdu to the agent */ - list_for_each_entry(n, &c->nodelist, list) + list_for_each_active_entry(n, &c->nodelist, list) cntlr_send_ap_mld_configuration_request(c, n); } @@ -1162,7 +1180,7 @@ bool cntlr_check_config_diff(struct controller *c, uint32_t diff) trace("bsta mld config changed\n"); /* send the ap mld config cmdu to the agent */ - list_for_each_entry(n, &c->nodelist, list) + list_for_each_active_entry(n, &c->nodelist, list) cntlr_send_bsta_mld_configuration_request(c, n); } #endif @@ -1185,7 +1203,7 @@ int cntlr_sync_dyn_controller_config(struct controller *c, uint8_t *agent) send_cmdu(c, cmdu); cmdu_free(cmdu); } else { - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { if (hwaddr_equal(c->almacaddr, n->almacaddr)) continue; /* skip locally running agent */ @@ -1257,6 +1275,11 @@ static void cntlr_ageout_nodes(struct controller *c) /* Here we need to see that all nodes in nodelist */ /* and check there timestamp */ list_for_each_entry_safe(n, tmp, &c->nodelist, list) { + if (timestamp_expired(&n->last_tsp_seen, NODE_INACTIVE_TIME * 1000)) { + topology_remove_device(&c->topology, n->almacaddr); + n->is_active = false; + } + if (timestamp_expired(&n->last_tsp_seen, NODE_EXPIRE_TIME * 1000)) { list_for_each_entry_safe(r, temp, &n->radiolist, list) { @@ -1264,7 +1287,6 @@ static void cntlr_ageout_nodes(struct controller *c) } cntlr_config_del_node(n->almacaddr); - topology_remove_device(&c->topology, n->almacaddr); node_clean_stalist(c, n); cntlr_clean_radiolist(c, n); mactable_del_entry(c->mac_table, n->almacaddr, MAC_ENTRY_ALID); @@ -1283,7 +1305,7 @@ static void cntlr_renew_nodes_configuration(struct controller *c) /* When at least one running node was configured with older config, */ /* send autoconfig renew */ - list_for_each_entry(node, &c->nodelist, list) { + list_for_each_active_entry(node, &c->nodelist, list) { if (!timestamp_invalid(&node->last_config) && timestamp_less_than(&node->last_config, &c->cfg.last_change) && timestamp_greater_than(&node->last_cmdu, &c->cfg.last_change)) { @@ -1329,7 +1351,7 @@ static void combined_link_metric_periodic_collection(struct controller *c) /* AP metrics query for each agent */ /* For each agent */ - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { uint8_t *new_radiolist; struct netif_radio *r = NULL; int num_bss = 0, num_radio = 0; diff --git a/src/cntlr.h b/src/cntlr.h index 58139fdc2176b41903c19196d4f05bbfafaa2a7b..ee6b8f16f62ba20dee9a0186aee2238d3095241a 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -42,7 +42,8 @@ struct tlv_tx_linkmetric; #define LIMIT_STA_COUNT (100) #endif -#define NODE_EXPIRE_TIME 65 +#define NODE_INACTIVE_TIME 65 +#define NODE_EXPIRE_TIME (7 * 24 * 60 * 60) /* 7 days */ #define METRIC_REP_INTERVAL 10 extern const char *ubus_socket; @@ -229,6 +230,7 @@ struct uobj_struct { struct node { uint8_t almacaddr[6]; enum nodetype type; + bool is_active; int depth; /** >= 0 or -1 for unknown */ int ul_type; /** uplink type */ uint32_t est_thput_ul; /* estimated l3 throughput achievable in uplink dir */ @@ -370,6 +372,7 @@ struct sta_error_response { 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); +bool cntlr_node_is_active(struct controller *c, uint8_t *macaddr); struct node *cntlr_find_node_with_bssid(struct controller *c, uint8_t *bssid); struct netif_link *cntlr_alloc_link(struct controller *c, diff --git a/src/cntlr_cmdu.c b/src/cntlr_cmdu.c index 083cb0b84f58d2970afc8e406db5df4b8621e2a4..f5748d55bb99f6fd6e60106b32d445849b4b25f5 100644 --- a/src/cntlr_cmdu.c +++ b/src/cntlr_cmdu.c @@ -21,6 +21,7 @@ #include "config.h" #include "utils/debug.h" +#include "utils/liblist.h" #include "cntlr.h" #include "cntlr_map.h" #include "cntlr_tlv.h" @@ -1449,7 +1450,7 @@ int send_agent_list_to_all_nodes(struct controller *c) } ret = 0; - list_for_each_entry(node, &c->nodelist, list) { + list_for_each_active_entry(node, &c->nodelist, list) { memcpy(cmdu->origin, node->almacaddr, 6); if (send_cmdu(c, cmdu) == 0xffff) ret = -1; diff --git a/src/cntlr_commands_impl.c b/src/cntlr_commands_impl.c index fe91910e06a1bcfae21eece70f97577f492da79f..11790453ad4ae1388423877c97eaa63935b8d268 100644 --- a/src/cntlr_commands_impl.c +++ b/src/cntlr_commands_impl.c @@ -26,6 +26,7 @@ #include "cntlr_map.h" #include "cntlr_tlv.h" #include "config.h" +#include "utils/liblist.h" #include "utils/utils.h" #include "timer.h" #include "sta.h" @@ -1149,7 +1150,7 @@ int COMMAND(trigger_channel_clearing)(void *priv, void *args, void *out) if (!hwaddr_aton(agent, agent_mac)) return -EINVAL; - list_for_each_entry(node, &c->nodelist, list) { + list_for_each_active_entry(node, &c->nodelist, list) { if (!hwaddr_is_zero(agent_mac) && memcmp(agent_mac, node->almacaddr, 6)) continue; @@ -2336,7 +2337,7 @@ int COMMAND(query_channel_pref)(void *priv, void *args, void *out) if (hwaddr_is_zero(agent_mac)) { struct node *n = NULL; - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { cmdu = cntlr_gen_channel_preference_query(c, n->almacaddr); if (!cmdu) continue; @@ -2950,7 +2951,7 @@ static int _cntlr_status(struct controller *c, void *args, void *out, bool full) t = blobmsg_open_table(bb, ""); blobmsg_add_string(bb, "ieee1905id", hwaddrstr); blobmsg_add_u32(bb, "profile", n->map_profile); - + blobmsg_add_u32(bb, "active", n->is_active ? 1 : 0); b = blobmsg_open_array(bb, "radios"); list_for_each_entry(p, &n->radiolist, list) { diff --git a/src/cntlr_map.c b/src/cntlr_map.c index b26ba55cc82d9b3365a6f1ba0667ddce3a639b5f..88b7af19714b2cbf1b648c4ce744e83b3f901084 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -37,6 +37,7 @@ #endif #endif +#include "utils/liblist.h" #include "utils/utils.h" #include "utils/debug.h" #include "config.h" @@ -116,7 +117,7 @@ int send_dpp_cce_indication(struct controller *c, uint8_t *agent, } else { struct node *n = NULL; - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { struct cmdu_buff *cmdu; cmdu = cntlr_gen_dpp_cce_indication(c, n->almacaddr, advertise); @@ -4031,8 +4032,10 @@ int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid, } /* update the timestamp of the node */ - if (n) + if (n) { timestamp_update(&n->last_tsp_seen); + n->is_active = true; + } cmdu = cmdu_alloc_custom(cmdutype, &mid, rxif, src, tlvs, len); if (!cmdu) { @@ -4048,8 +4051,10 @@ int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid, if (!n) n = cntlr_find_node(c, origin); - if (n) + if (n) { timestamp_update(&n->last_cmdu); + n->is_active = true; + } cmdu_free(cmdu); return ret; diff --git a/src/cntlr_tlv.c b/src/cntlr_tlv.c index 1f0ec6c4ee4384059cdfdfe0ede09ef4b9507583..801b805bfd56f440d2ea78c037f2754a0d24be85 100644 --- a/src/cntlr_tlv.c +++ b/src/cntlr_tlv.c @@ -25,6 +25,7 @@ #include <wifidefs.h> +#include "utils/liblist.h" #include "utils/utils.h" #include "utils/debug.h" #include "cntlr.h" @@ -2519,7 +2520,7 @@ int cntlr_gen_agent_list_tlv(struct controller *c, struct cmdu_buff *frm, uint8_ return -1; i = 0; - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { dbg("\tagent[%d]:\n", i); /* node aladdr */ diff --git a/src/dpp.c b/src/dpp.c index 5319b6fb9a241f74b0d548ee0b10ffc4d3bac79e..f3fe8f4bb3fccd6ae4efb514f83581508522371c 100644 --- a/src/dpp.c +++ b/src/dpp.c @@ -19,6 +19,7 @@ #include "cntlr_map.h" #include "easy/utils.h" #include "utils/debug.h" +#include "utils/liblist.h" const char *dpp_frame_type2str(uint8_t type) @@ -278,7 +279,7 @@ int dpp_frame_handler(void *dpp, uint8_t *smac, enum dpp_event ev, if (proxy) { struct node *n = NULL; - list_for_each_entry(n, &c->nodelist, list) { + list_for_each_active_entry(n, &c->nodelist, list) { memcpy(resp->origin, n->almacaddr, 6); err("|%s:%d| send frame to "MACFMT"\n", __func__, __LINE__, MAC2STR(n->almacaddr)); send_cmdu(c, resp); diff --git a/src/utils/liblist.h b/src/utils/liblist.h index d5c9bc4f75e0398b0f9936e71499914f72973294..24ee5320a038c3437f8dcf5b130a294e9a1a8f5a 100644 --- a/src/utils/liblist.h +++ b/src/utils/liblist.h @@ -47,4 +47,9 @@ void merge_sort(void *priv, struct list_head *head, #define list_sort merge_sort #endif +#define list_for_each_active_entry(p, head, field) \ + for (p = list_first_entry(head, typeof(*p), field); &p->field != (head); \ + p = list_entry(p->field.next, typeof(*p), field)) \ + if (p->is_active) + #endif /* LIBLIST_H */