From c568a1b113ec178ce0b4072082681c4e99a70114 Mon Sep 17 00:00:00 2001
From: Jakob Olsson <jakob.olsson@iopsys.eu>
Date: Tue, 6 Dec 2022 16:49:23 +0100
Subject: [PATCH] agent_map: send policy config to returning nodes

---
 src/cmdu_validate.c | 46 +++++++++++++++++++++++++++++++++++++++++++++
 src/cmdu_validate.h |  1 +
 src/cntlr_map.c     | 36 +++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+)

diff --git a/src/cmdu_validate.c b/src/cmdu_validate.c
index c4df2780..7f394db0 100644
--- a/src/cmdu_validate.c
+++ b/src/cmdu_validate.c
@@ -104,6 +104,14 @@ static int check_supported_band_tlv(struct tlv *t)
 				sizeof(struct tlv_supported_band));
 }
 
+/* Check 1905.1 AL MAC address type TLV */
+static int check_client_assoc_event_tlv(struct tlv *t)
+{
+	/* macaddr (6 bytes) + macaddr (6 bytes) + assoc event (1 byte) */
+	return check_serialized_tlv(t,
+				sizeof(struct tlv_client_assoc_event));
+}
+
 static int check_service_tlv(struct tlv *t)
 {
 	int offset = 0;
@@ -824,3 +832,41 @@ bool validate_ap_autoconfig_response(struct cmdu_buff *cmdu, struct tlv *tv[][16
 
 	return true;
 }
+
+bool validate_topology_notification(struct cmdu_buff *cmdu, struct tlv *tv[][16])
+{
+	struct tlv_policy a_policy[] = {
+		[0] = { .type = TLV_TYPE_AL_MAC_ADDRESS_TYPE,
+				.present = TLV_PRESENT_ONE,
+				.minlen = 6,
+				.maxlen = 6,
+		},
+		[1] = { .type = MAP_TLV_CLIENT_ASSOCIATION_EVENT,
+				.present = TLV_PRESENT_OPTIONAL_MORE,
+				.minlen = 13,
+				.maxlen = 13,
+		}
+	};
+	int ret;
+	int num = 0;
+
+	trace("%s |" MACFMT "|CMDU: ap autoconfig response\n",
+		  __func__, MAC2STR(cmdu->origin));
+
+	ret = cmdu_parse_tlvs(cmdu, tv, a_policy, 2);
+	if (ret) {
+		dbg("%s: parse_tlv failed\n", __func__);
+		return false;
+	}
+
+	/* Parse SupportedRole TLV */
+	if (check_al_mac_addr_type_tlv(tv[0][0]))
+		return false;
+
+	while (tv[1][num]) {
+		if (check_client_assoc_event_tlv(tv[1][num++]))
+			return false;
+	}
+
+	return true;
+}
diff --git a/src/cmdu_validate.h b/src/cmdu_validate.h
index d173b6da..61f8052c 100644
--- a/src/cmdu_validate.h
+++ b/src/cmdu_validate.h
@@ -9,5 +9,6 @@ bool validate_topology_response(struct cmdu_buff *cmdu, struct tlv *tv_tsp[][16]
 bool validate_ap_autoconfig_wsc(struct cmdu_buff *cmdu, struct tlv *tv[][16]);
 bool validate_ap_autoconfig_search(struct cmdu_buff *cmdu, struct tlv *tv[][16]);
 bool validate_ap_autoconfig_response(struct cmdu_buff *cmdu, struct tlv *tv[][16]);
+bool validate_topology_notification(struct cmdu_buff *cmdu, struct tlv *tv[][16]);
 
 #endif	// CMDU_VALIDATE
diff --git a/src/cntlr_map.c b/src/cntlr_map.c
index a1dec516..78b270ab 100644
--- a/src/cntlr_map.c
+++ b/src/cntlr_map.c
@@ -63,6 +63,42 @@ struct map_cmdu_calltable_t {
 int handle_topology_notification(void *cntlr, struct cmdu_buff *cmdu)
 {
 	trace("%s: --->\n", __func__);
+	struct controller *c = (struct controller *) cntlr;
+	struct tlv *tv[2][16] = {0};
+	struct tlv_aladdr *aladdr_tlv;
+	uint8_t *aladdr;
+	int num = 0;
+
+	if (!validate_topology_notification(cmdu, tv)) {
+		dbg("cmdu validation: [TOPOLOGY_NOTIFICATION] failed\n");
+		return -1;
+	}
+
+	aladdr_tlv = (struct tlv_aladdr *) tv[0][0]->data;
+	aladdr = aladdr_tlv->macaddr;
+
+	if (tv[1][num]) {
+		/* client connect event*/
+	} else {
+		/* neighbor addition event */
+		struct node *n;
+		uint8_t wildcard[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+		struct node_policy *np;
+
+		np = agent_find_policy(c, aladdr);
+		if (!np)
+			return -1;
+
+		n = find_node_by_mac(c, aladdr);
+		if (!n)
+			return -1;
+
+		cmdu = cntlr_gen_policy_config_req(cntlr, aladdr, np, 0,
+						   wildcard, 1, wildcard);
+		if (!cmdu)
+			return -1;
+	}
+
 	return 0;
 }
 
-- 
GitLab