From e4074ecd8e64eb1ad3d46df48c9ea7a73c8bfbf6 Mon Sep 17 00:00:00 2001
From: Kamil Zulewski <kamil.zulewski@iopsys.eu>
Date: Tue, 14 Nov 2023 14:05:33 +0100
Subject: [PATCH] Save configuration timestamps, renew config when needed

---
 src/cntlr.c     | 30 ++++++++++++++++++++++++++++++
 src/cntlr.h     |  3 +++
 src/cntlr_map.c |  9 +++++++++
 src/config.c    |  4 ++++
 src/config.h    |  1 +
 5 files changed, 47 insertions(+)

diff --git a/src/cntlr.c b/src/cntlr.c
index 42e4d7dc..d8b227b9 100644
--- a/src/cntlr.c
+++ b/src/cntlr.c
@@ -1784,6 +1784,33 @@ static void cntlr_signal_periodic_run(atimer_t *t)
 	timer_set(&c->signal_handler, 1 * 1000);
 }
 
+static void renew_nodes_configuration(struct controller *c)
+{
+	trace("%s: --->\n", __func__);
+	struct node *node = NULL;
+
+	/* When at least one running node was configured with older config, */
+	/* send autoconfig renew */
+	list_for_each_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)) {
+			uint8_t multicast_addr[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x13};
+			struct cmdu_buff *cmdu =
+				cntlr_gen_ap_autoconfig_renew(c, multicast_addr);
+
+			dbg("Found possibly unconfigured node: "MACFMT"\n", MAC2STR(node->alid));
+
+			if (cmdu) {
+				dbg("Sending AP_AUTOCONFIGURATION_RENEW\n");
+				send_cmdu(c, cmdu);
+				cmdu_free(cmdu);
+			}
+
+			break;
+		}
+	}
+}
 
 static void combined_link_metric_periodic_collection(struct controller *c)
 {
@@ -1888,6 +1915,7 @@ static void cntlr_periodic_run(atimer_t *t)
 
 	forall_node_get_sta_metrics(c);
 
+
 	/* TODO: */
 	//forall_node_get_usta_metrics(c);
 
@@ -1897,6 +1925,8 @@ static void cntlr_periodic_run(atimer_t *t)
 	/* Call AP metrics query and 1905 link metrics query for data collection */
 	combined_link_metric_periodic_collection(c);
 
+	renew_nodes_configuration(c);
+
 	timer_set(&c->heartbeat, 10 * 1000);
 }
 
diff --git a/src/cntlr.h b/src/cntlr.h
index 97adc870..ebe6e424 100644
--- a/src/cntlr.h
+++ b/src/cntlr.h
@@ -276,6 +276,9 @@ struct node {
 	struct node_policy *np;
 	uint8_t ap_cap;
 	uint8_t map_profile;		   /** profile info of agent node */
+	struct timespec	last_config;       /** timestamp of most-recent config sent to agent */
+	struct timespec last_cmdu;         /** timestamp of last CMDU received from agent */
+
 	struct list_head radiolist;        /** list of netif_radio */
 	struct list_head stalist;
 	struct list_head list;
diff --git a/src/cntlr_map.c b/src/cntlr_map.c
index b473ff20..53f6604f 100644
--- a/src/cntlr_map.c
+++ b/src/cntlr_map.c
@@ -1248,6 +1248,9 @@ int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_buff *rx_cmdu,
 
 	cmdu_free(cmdu);
 
+	n->last_config = c->cfg.last_change;
+
+
 	np = agent_find_policy(c, rx_cmdu->origin);
 	if (!np) {
 		dbg("|%s:%d| missing node policy for node almac:" MACFMT \
@@ -4071,6 +4074,12 @@ int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid,
 	if (f[idx].debug)
 		ret = f[idx].debug(c, cmdu, n);
 
+	if (!n)
+		n = cntlr_find_node(c, origin);
+
+	if (n)
+		timestamp_update(&n->last_cmdu);
+
 	//TODO: check ret
 
 	cmdu_free(cmdu);
diff --git a/src/config.c b/src/config.c
index 078657f3..319135d7 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1862,6 +1862,10 @@ uint8_t cntlr_config_reload(struct controller_config *cfg)
 	/* get bitmap of what sections changed */
 	diff = cntlr_config_diff(cfg, &old);
 
+	if (diff & CONFIG_DIFF_CREDENTIALS || diff & CONFIG_DIFF_VLAN)
+		timestamp_update(&cfg->last_change);
+
+
 	/* clean old lists */
 	clean_cred_list(&old);
 	clean_agent_policies(&old); /* cleans nodelist */
diff --git a/src/config.h b/src/config.h
index c81dffe6..6f4d0919 100644
--- a/src/config.h
+++ b/src/config.h
@@ -238,6 +238,7 @@ struct controller_config {
 	struct list_head dpp_cntlrlist;
 	struct qos_control_config qos;
 #endif
+	struct timespec	last_change;		/* timestamp of most recent config change */
 };
 
 struct controller;
-- 
GitLab