From e3a089b56a2365c089f99809b111bfe3380518cd Mon Sep 17 00:00:00 2001
From: Anjan Chanda <anjan.chanda@iopsys.eu>
Date: Mon, 14 Aug 2023 14:56:53 +0200
Subject: [PATCH] show 'active_last_change' for host entry

---
 src/neigh.c |  9 +++++++--
 src/neigh.h |  1 +
 src/ubus.c  | 13 ++++++++++---
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/src/neigh.c b/src/neigh.c
index e040f94..1d42f3c 100644
--- a/src/neigh.c
+++ b/src/neigh.c
@@ -318,6 +318,7 @@ struct neigh_entry *neigh_entry_create(void *priv, uint8_t *macaddr, uint16_t st
 	if (type != NEIGH_TYPE_UNKNOWN)
 		e->type = type;
 
+	time(&e->lastchange);
 	getcurrtime(&tsp);
 	e->ageing_time = timeout;
 	timeradd_msecs(&tsp, e->ageing_time, &e->ageing_tmo);
@@ -651,6 +652,7 @@ void neigh_set_unreachable(void *nq, const char *ifname, int val)
 				//struct neigh_history_entry *he = NULL;
 
 				e->unreachable = val;
+				time(&e->lastchange);
 				err(MACFMT " marking it %sreachable\n",
 				    MAC2STR(e->macaddr), val ? "un" : "");
 
@@ -685,6 +687,7 @@ void neigh_mark_reachable(void *nq, uint8_t *macaddr, const char *ifname)
 				//struct neigh_history_entry *he = NULL;
 
 				e->unreachable = 0;
+				time(&e->lastchange);
 				err("Marking " MACFMT " reachable through %s\n",
 				    MAC2STR(e->macaddr), ifname);
 
@@ -882,10 +885,12 @@ struct neigh_entry *neigh_enqueue(void *nq, uint8_t *macaddr, uint16_t state,
 				timer_del(&e->delete_timer);
 
 			e->delete_pending = 0;
-
 			e->probing = 0;
 			e->probe_cnt = 0;
-			e->unreachable = 0;
+			if (e->unreachable) {
+				e->unreachable = 0;
+				time(&e->lastchange);
+			}
 
 			/* reset ageing timer for entry */
 			e->ageing_time = timeout;
diff --git a/src/neigh.h b/src/neigh.h
index 46f2350..6a9296b 100644
--- a/src/neigh.h
+++ b/src/neigh.h
@@ -77,6 +77,7 @@ struct neigh_entry {
 	atimer_t probing_timer;
 
 	int unreachable;		/* mark entry nonreachable */
+	time_t lastchange;		/* last time when reachable state toggled */
 	int delete_pending;
 	atimer_t delete_timer;
 	uint32_t ageing_time;           /* in msecs */
diff --git a/src/ubus.c b/src/ubus.c
index e86b995..080f1f6 100644
--- a/src/ubus.c
+++ b/src/ubus.c
@@ -382,11 +382,11 @@ int hostmngr_ubus_dump_topology(struct ubus_context *ctx, struct ubus_object *ob
 	struct blob_buf bi = {0};
 	struct blob_buf bo = {0};
 	uint32_t id;
-	int ret = 0;
+	int ret;
 
 	id = lookup_object(p->bus, topology_objname);
 	if (id == OBJECT_INVALID)
-		return UBUS_STATUS_NOT_FOUND;
+		return UBUS_STATUS_OK;
 
 	/* ubus call topology dump */
 	blob_buf_init(&bi, 0);
@@ -398,7 +398,7 @@ int hostmngr_ubus_dump_topology(struct ubus_context *ctx, struct ubus_object *ob
 	blob_buf_free(&bi);
 	blob_buf_free(&bo);
 
-	return ret;
+	return UBUS_STATUS_OK;
 }
 
 int hostmngr_ubus_show_arptable(struct ubus_context *ctx, struct ubus_object *obj,
@@ -478,8 +478,10 @@ int hostmngr_ubus_show_hosts(struct ubus_context *ctx, struct ubus_object *obj,
 			char statestr[128] = {0};
 			char ip4buf[32] = {0};
 			char *ifname = NULL;
+			char tbuf[64] = {0};
 			char *net = NULL;
 			uint16_t brport;
+			struct tm *t;
 			void *wt;
 
 			//if (e->unreachable)
@@ -489,6 +491,11 @@ int hostmngr_ubus_show_hosts(struct ubus_context *ctx, struct ubus_object *obj,
 
 			aa = blobmsg_open_table(&bb, "");
 			blobmsg_add_u8(&bb, "active", e->unreachable ? false : true);
+
+			t = localtime(&e->lastchange);
+			strftime(tbuf, sizeof(tbuf), "%Y-%m-%dT%H:%M:%S", t);
+			blobmsg_add_string(&bb, "active_last_change", tbuf);
+
 			hwaddr_ntoa(e->macaddr, macstr);
 			blobmsg_add_string(&bb, "macaddr", macstr);
 			blobmsg_add_string(&bb, "hostname", e->hostname);
-- 
GitLab