From fa6abdfad39801a1d4b30b57871f70fc75138960 Mon Sep 17 00:00:00 2001
From: Jakob Olsson <jakob.olsson@iopsys.eu>
Date: Tue, 17 Jun 2025 12:49:06 +0200
Subject: [PATCH] dynbh: more wip cleanup dump

---
 src/agent.c            |   2 -
 src/agent.h            |   1 -
 src/agent_map.c        |   2 +-
 src/config.c           |  17 ++--
 src/config.h           |  12 ++-
 src/dynbh/api          | 114 ---------------------------
 src/dynbh/dbh_config.c |  35 +++++++++
 src/dynbh/dbh_config.h |   6 +-
 src/dynbh/dbh_nl.c     | 173 +----------------------------------------
 src/dynbh/dbh_nl.h     |   8 +-
 src/dynbh/dynbh.c      |  84 ++++++++++++--------
 src/dynbh/dynbh.h      |   6 ++
 src/nl.c               |  62 ++++++++-------
 src/script/multiap     |  58 ++++++++++++++
 14 files changed, 219 insertions(+), 361 deletions(-)
 delete mode 100755 src/dynbh/api

diff --git a/src/agent.c b/src/agent.c
index 71f1dd09f..b1eb3e190 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -7898,7 +7898,6 @@ int agent_init_defaults(struct agent *a)
 #endif
 
 	a->cntlr_select.local = CONTROLLER_SELECT_LOCAL;
-	a->cntlr_select.auto_detect = CONTROLLER_SELECT_AUTODETECT;
 	a->cntlr_select.probe_int = CONTROLLER_SELECT_PROBE_INT;
 	a->cntlr_select.retry_int = CONTROLLER_SELECT_RETRY_INT;
 #ifdef AGENT_DYNAMIC_CNTRL
@@ -8143,7 +8142,6 @@ void run_agent(void *opts)
 		dynbh_publish_object(&w->priv, "dynbh");
 
 		strncpy(w->priv.al_bridge, w->cfg.al_bridge, sizeof(w->priv.al_bridge) - 1);
-		dynbh_register_nlevents(&w->priv);
 		w->has_dynbh = true;
 		INIT_LIST_HEAD(&w->priv.ethportlist);
 		get_ethportslist(&num, ifs);
diff --git a/src/agent.h b/src/agent.h
index a45d7d179..9becd879e 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -897,7 +897,6 @@ struct agent {
 	/* controller selection configuration */
 	struct {
 		bool local;
-		bool auto_detect;
 		uint16_t probe_int;
 		uint8_t retry_int;
 #ifdef AGENT_DYNAMIC_CNTRL
diff --git a/src/agent_map.c b/src/agent_map.c
index 6841ff5dd..8ba41155a 100644
--- a/src/agent_map.c
+++ b/src/agent_map.c
@@ -1267,7 +1267,7 @@ static int agent_update_controller_data(struct agent *a, struct cmdu_buff *cmdu)
 			ret = CTRL_MAC_NEW;
 #if DYNBH
 			if (!memcmp(cmdu->origin, a->almac, 6)) {
-				dynbh_unregister_nlevents(&a->priv);
+				//dynbh_unregister_nlevents(&a->priv);
 				//agent_remove_object(a, "dynbh"); TODO
 				a->has_dynbh = false;
 			}
diff --git a/src/config.c b/src/config.c
index 8da0e733c..4a0d7c7b3 100644
--- a/src/config.c
+++ b/src/config.c
@@ -2441,14 +2441,20 @@ static int agent_config_get_controller_select(struct agent_config *a,
 		return -1;
 	}
 	cscfg->local = atoi(tb[CTRL_SELECT_LOCAL]->v.string);
-
+#ifdef DYNBH
+	cscfg->discovery_mode = DYNAMIC_CNTLR_MODE_AUTO;
 	if (tb[CTRL_SELECT_ID]) {
-		cscfg->auto_detect = true;
-		if (strncmp(tb[CTRL_SELECT_ID]->v.string, "auto", 4)) {
-			cscfg->auto_detect = false;
-			hwaddr_aton(tb[CTRL_SELECT_ID]->v.string, cscfg->alid);
+		const char *mode = tb[CTRL_SELECT_ID]->v.string;
+
+		if (!strncmp(mode, "auto", 4)) {
+			cscfg->discovery_mode = DYNAMIC_CNTLR_MODE_AUTO;
+		} else if (!strncmp(mode, "disabled", 4)) {
+			cscfg->discovery_mode = DYNAMIC_CNTLR_MODE_DISABLED;
+		} else if (!strncmp(mode, "controller", 4)) {
+			cscfg->discovery_mode = DYNAMIC_CNTLR_MODE_CONTROLLER;
 		}
 	}
+#endif
 	if (tb[CTRL_SELECT_PROBE_INT])
 		cscfg->probe_int = atoi(tb[CTRL_SELECT_PROBE_INT]->v.string);
 	if (tb[CTRL_SELECT_RETRY_INT])
@@ -4088,7 +4094,6 @@ int agent_config_init(struct agent *a, struct agent_config *cfg)
 
 	if (a->cfg.cscfg) {
 		a->cntlr_select.local = a->cfg.cscfg->local;
-		a->cntlr_select.auto_detect = a->cfg.cscfg->auto_detect;
 		a->cntlr_select.probe_int = a->cfg.cscfg->probe_int;
 		a->cntlr_select.retry_int = a->cfg.cscfg->retry_int;
 #ifdef AGENT_DYNAMIC_CNTRL
diff --git a/src/config.h b/src/config.h
index d877e73f4..7b731da73 100644
--- a/src/config.h
+++ b/src/config.h
@@ -19,7 +19,11 @@
 #include <easy/if_utils.h>
 #include <wifidefs.h>
 #include <timer_impl.h>
-
+#ifdef DYNBH
+#ifdef PERSIST_CONTROLLER
+#include "dynbh/dynbh.h"
+#endif
+#endif
 struct tlv_default_8021q_settings;
 struct tlv_traffic_sep_policy;
 struct wps_credential;
@@ -180,11 +184,15 @@ struct policy_cfg {
 
 struct ctrl_select_cfg {
 	bool local;			/* true - own MAP Controller treated as the main or primary. */
-	bool auto_detect;	/* Set to true if alid of controller is not explicitly provided by config. */
 	uint16_t probe_int;	/* Time interval in seconds between controller discovery by the MAP Agent. */
 	uint8_t retry_int;	/* Num of discovery retries before taking next action. */
 #ifdef AGENT_DYNAMIC_CNTRL
 	bool autostart;		/* true - agent will try to start own controller after not finding one. */
+#endif
+#ifdef DYNBH
+#ifdef PERSIST_CONTROLLER
+	enum cntlr_discovery_mode discovery_mode;
+#endif
 #endif
 	uint8_t alid[6];	/* 1905 ALID of the device that will have the MAP Controller service */
 };
diff --git a/src/dynbh/api b/src/dynbh/api
deleted file mode 100755
index 709f5601f..000000000
--- a/src/dynbh/api
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/bin/sh
-
-. /lib/functions.sh
-. /usr/share/libubox/jshn.sh
-
-MAPFILE="/var/run/multiap/multiap.backhaul"
-
-issue_discovery() {
-	local iface="$1"
-
-	ubus list ieee1905 > /dev/null 2>&1
-
-	[ "$?" != 0 ] && return
-
-	res=$(ubus -t2 call ieee1905 buildcmdu "{\"type\":0, \"ifname\":\"${iface}\"}")
-	json_load "$res" > /dev/null 2>&1
-	json_get_var data data
-
-	[ "$data" == "" ] && return
-
-	ubus -t1 wait_for ieee1905.al.$iface > /dev/null 2>&1
-	[ "$?" != 0 ] && return
-
-	ubus call ieee1905.al.$iface cmdu "{\"dst\":\"01:80:c2:00:00:13\", \"type\":0, \"data\":\"${data}\"}"
-}
-
-
-persist_cntlr() {
-	local mode=$(uci -q get mapagent.@controller_select[0].id)
-	local brcm_setup="$(uci -q get mapagent.agent.brcm_setup)"
-
-	agent_update_acs() {
-		local section=$1
-
-		config_get device ${section} device
-		config_get type ${section} type
-		config_get ifname ${section} ifname
-
-		[ "$type" != "fronthaul" ] && return
-
-		nvram unset ${ifname}_mode > /dev/null 2>&1
-
-	}
-
-	agent_disable_bsta() {
-		local section=$1
-
-		uci set mapagent.${section}.enabled="0"
-	}
-
-	wireless_disable_bsta() {
-		local section=$1
-
-		config_get mode ${section} mode
-		config_get ifname ${section} ifname
-
-		[ "$mode" != "sta" ] && return
-
-		uci set wireless.${section}.disabled="1"
-		wpa_cli -i $ifname disable 0
-	}
-
-	[ "$mode" == "auto" ] || return
-
-	config_load "mapagent"
-	config_foreach agent_disable_bsta bsta
-	[ "$brcm_setup" = "1" ] && config_foreach agent_update_acs ap
-
-	config_load "wireless"
-	config_foreach wireless_disable_bsta wifi-iface
-	uci commit wireless
-
-	uci set mapagent.@controller_select[0].local="1"
-	uci set mapagent.@controller_select[0].id="controller"
-	uci commit mapagent
-	kill -SIGHUP `pidof mapagent`
-}
-
-
-disable_cntlr() {
-	local mode=$(uci -q get mapagent.@controller_select[0].id)
-
-	[ "$mode" == "auto" ] || return
-
-	uci set mapagent.@controller_select[0].local="0"
-	uci set mapagent.@controller_select[0].autostart="0"
-	uci set mapagent.@controller_select[0].id="disabled"
-	uci commit mapagent
-	kill -SIGHUP `pidof mapagent`
-}
-
-dhcp_discovery() {
-	local bridge=$(uci get mapagent.agent.al_bridge)
-
-	[ "$bridge" = "" ] && bridge="br-lan"
-
-	udhcpc -qn -t 1 -T1 -i $bridge > /dev/null 2>&1
-
-	echo "$?"
-}
-
-func=$1
-shift
-
-case "$func" in
-	up) up $@;;
-	down) down $@;;
-	bridge_delif) bridge_delif $@;;
-	bridge_addif) bridge_addif $@;;
-	persist_cntlr) persist_cntlr $@;;
-	disable_cntlr) disable_cntlr $@;;
-	dhcp_discovery) dhcp_discovery $@;;
-	*) exit 1;;
-esac
diff --git a/src/dynbh/dbh_config.c b/src/dynbh/dbh_config.c
index 770368930..d70739c38 100644
--- a/src/dynbh/dbh_config.c
+++ b/src/dynbh/dbh_config.c
@@ -5,6 +5,7 @@
 #include <string.h>
 
 #include "dynbh.h"
+#include "config.h"
 
 #if PERSIST_CONTROLLER
 
@@ -48,6 +49,40 @@ static int dbh_config_get_controller_select(struct dynbh_ctx *ctx,
 	return 0;
 }
 
+int dbh_config_set_controller_select(struct dynbh_ctx *cfg,
+			      enum cntlr_discovery_mode mode,
+			      bool autostart, bool local)
+{
+	struct uci_context *ctx;
+	struct uci_package *pkg;
+	struct uci_element *e;
+
+
+	ctx = uci_alloc_context();
+	if (!ctx)
+		return -1;
+
+	if (uci_load(ctx, "mapagent", &pkg)) {
+		uci_free_context(ctx);
+		return -1;
+	}
+
+	uci_foreach_element(&pkg->sections, e) {
+		struct uci_section *s = uci_to_section(e);
+
+		if (strcmp(s->type, "controller_select"))
+			continue;
+
+		set_value(ctx, pkg, s, "id", dbh_mode_to_str(mode), UCI_TYPE_STRING);
+		set_value(ctx, pkg, s, "autostart", (autostart ? "1" : "0"), UCI_TYPE_STRING);
+		set_value(ctx, pkg, s, "local", (local ? "1" : "0"), UCI_TYPE_STRING);
+	}
+
+	uci_commit(ctx, &pkg, false);
+	uci_unload(ctx, pkg);
+	uci_free_context(ctx);
+	return 0;
+}
 
 int dbh_config_load(struct dynbh_ctx *cfg)
 {
diff --git a/src/dynbh/dbh_config.h b/src/dynbh/dbh_config.h
index f6d192b64..003a8e928 100644
--- a/src/dynbh/dbh_config.h
+++ b/src/dynbh/dbh_config.h
@@ -4,10 +4,14 @@
 
 #include <uci.h>
 
+#include "dynbh.h"
 struct dynbh_ctx;
 #if PERSIST_CONTROLLER
-
+int dbh_config_set_controller_select(struct dynbh_ctx *cfg,
+			      enum cntlr_discovery_mode mode,
+			      bool autostart, bool local);
 int dbh_config_load(struct dynbh_ctx *cfg);
+
 #endif
 #endif
 #endif
\ No newline at end of file
diff --git a/src/dynbh/dbh_nl.c b/src/dynbh/dbh_nl.c
index 9b3d5866b..c2986f273 100644
--- a/src/dynbh/dbh_nl.c
+++ b/src/dynbh/dbh_nl.c
@@ -13,82 +13,17 @@
 #ifdef DYNBH
 #include "dbh_nl.h"
 
-#include <time.h>
 #include <easy/utils.h>
 #include <easy/if_utils.h>
-#include <errno.h>
-#include <libubox/list.h>
-#include <libubox/uloop.h>
-#include <linux/if_link.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <net/if.h>
 #include <netlink/attr.h>
-#include <netlink/netlink.h>
 #include <netlink/genl/genl.h>
 #include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
 #include <linux/if.h>
 
 #include "dynbh.h"
 
-struct nl_msg;
 
-
-struct dynbh_nlevent {
-	struct uloop_fd uloop;
-	void (*error_cb)(struct dynbh_nlevent *e, int error);
-	void (*event_cb)(struct dynbh_nlevent *e);
-};
-
-struct event_socket {
-	struct dynbh_nlevent ev;
-	struct nl_sock *sock;
-	int sock_bufsize;
-};
-
-static int dynbh_nlevents_cb(struct nl_msg *msg, void *arg);
-
-static void handle_error(struct dynbh_nlevent *e, int error)
-{
-	struct event_socket *ev_sock = container_of(e, struct event_socket, ev);
-
-	if (error != ENOBUFS)
-		goto err;
-
-	ev_sock->sock_bufsize *= 2;
-	if (nl_socket_set_buffer_size(ev_sock->sock, ev_sock->sock_bufsize, 0))
-		goto err;
-
-	return;
-
-err:
-	e->uloop.cb = NULL;
-	uloop_fd_delete(&e->uloop);
-}
-
-static void recv_nlevents(struct dynbh_nlevent *e)
-{
-	struct event_socket *ev_sock = container_of(e, struct event_socket, ev);
-
-	nl_recvmsgs_default(ev_sock->sock);
-}
-
-static struct event_socket rtnl_event = {
-	.ev = {
-		.uloop = {.fd = - 1, },
-		.error_cb = handle_error,
-		.event_cb = recv_nlevents,
-	},
-	.sock = NULL,
-	.sock_bufsize = 0x20000,
-};
-
-
-static int dynbh_handle_nlevents_link(struct dynbh_ctx *priv,
+int dynbh_handle_nlevents_link(struct dynbh_ctx *priv,
 				      struct nlmsghdr *hdr, bool add)
 {
 	struct ifinfomsg *ifi = nlmsg_data(hdr);
@@ -147,110 +82,4 @@ static int dynbh_handle_nlevents_link(struct dynbh_ctx *priv,
 	}
 	return NL_OK;
 }
-
-static int dynbh_nlevents_cb(struct nl_msg *msg, void *arg)
-{
-	struct nlmsghdr *hdr = nlmsg_hdr(msg);
-	struct dynbh_ctx *priv = arg;
-	int ret = NL_SKIP;
-	bool add = false;
-
-	switch (hdr->nlmsg_type) {
-	case RTM_NEWLINK:
-		add = true;
-	//case RTM_DELLINK:
-		fprintf(stderr, "%s!\n", (add ? "newlink":"dellink"));
-		ret = dynbh_handle_nlevents_link(priv, hdr, add);
-		break;
-	default:
-		break;
-	}
-
-	return ret;
-}
-
-
-static void dynbh_receive_nlevents(struct uloop_fd *u, unsigned int events)
-{
-	struct dynbh_nlevent *e = container_of(u, struct dynbh_nlevent, uloop);
-
-	if (u->error) {
-		int ret = -1;
-		socklen_t ret_len = sizeof(ret);
-
-		u->error = false;
-		if (e->error_cb &&
-		    getsockopt(u->fd, SOL_SOCKET, SO_ERROR, &ret, &ret_len) == 0) {
-			e->error_cb(e, ret);
-		}
-	}
-
-	if (e->event_cb) {
-		e->event_cb(e);
-		return;
-	}
-}
-
-int dynbh_register_nlevents(struct dynbh_ctx *priv)
-{
-	struct nl_sock *sk;
-
-	fprintf(stderr, "Opening netlink!\n");
-
-	sk = nl_socket_alloc();
-	if (!sk) {
-		fprintf(stderr, "Unable to open nl event socket: %m");
-		return -1;
-	}
-
-	if (nl_connect(sk, NETLINK_ROUTE) < 0) {
-		nl_socket_free(sk);
-		return -1;
-	}
-
-	rtnl_event.sock = sk;
-
-	if (nl_socket_set_buffer_size(rtnl_event.sock, rtnl_event.sock_bufsize, 0)) {
-		fprintf(stderr, "%s: %d\n", __func__, __LINE__);
-		goto out_err;
-	}
-
-	nl_socket_disable_seq_check(rtnl_event.sock);
-
-	nl_socket_modify_cb(rtnl_event.sock, NL_CB_VALID, NL_CB_CUSTOM,
-			    dynbh_nlevents_cb, priv);
-
-	if (nl_socket_add_memberships(rtnl_event.sock,
-				      RTNLGRP_NEIGH, RTNLGRP_LINK, 0))
-		goto out_err;
-
-	rtnl_event.ev.uloop.fd = nl_socket_get_fd(rtnl_event.sock);
-	rtnl_event.ev.uloop.cb = dynbh_receive_nlevents;
-	uloop_fd_add(&rtnl_event.ev.uloop, ULOOP_READ |
-		     ((rtnl_event.ev.error_cb) ? ULOOP_ERROR_CB : 0));
-	fprintf(stderr, "netlink success!\n");
-
-	return 0;
-
-out_err:
-	if (rtnl_event.sock) {
-		nl_socket_free(rtnl_event.sock);
-		rtnl_event.sock = NULL;
-		rtnl_event.ev.uloop.fd = -1;
-	}
-	fprintf(stderr, "netlink fail!\n");
-	return -1;
-}
-
-void dynbh_unregister_nlevents(struct dynbh_ctx *priv)
-{
-	UNUSED(priv);
-
-	if (rtnl_event.sock) {
-		uloop_fd_delete(&rtnl_event.ev.uloop);
-		rtnl_event.ev.uloop.fd = -1;
-		nl_socket_free(rtnl_event.sock);
-		rtnl_event.sock = NULL;
-	}
-}
 #endif
diff --git a/src/dynbh/dbh_nl.h b/src/dynbh/dbh_nl.h
index 617b45c1f..b1dd0bebb 100644
--- a/src/dynbh/dbh_nl.h
+++ b/src/dynbh/dbh_nl.h
@@ -2,10 +2,12 @@
 #ifndef DBH_NL_H
 #define DBH_NL_H
 
-struct dynbh_ctx;
+#include <stdbool.h>
+#include <netlink/netlink.h>
 
-int dynbh_register_nlevents(struct dynbh_ctx *priv);
-void dynbh_unregister_nlevents(struct dynbh_ctx *priv);
+struct dynbh_ctx;
 
+int dynbh_handle_nlevents_link(struct dynbh_ctx *priv,
+				      struct nlmsghdr *hdr, bool add);
 #endif
 #endif
diff --git a/src/dynbh/dynbh.c b/src/dynbh/dynbh.c
index cf621a292..67a550bd3 100644
--- a/src/dynbh/dynbh.c
+++ b/src/dynbh/dynbh.c
@@ -29,19 +29,41 @@
 #include "dbh_nl.h"
 #include "../utils/utils.h"
 
-#define DBH_MAX_ETHPORTS 16
 
 #ifndef BIT
 #define BIT(n)	(1U << (n))
 #endif
 
-#define map_plugin			IEEE1905_OBJECT_MULTIAP
 #define HEARTBEAT_PROBE_TIMEOUT 	60
 #define APCONF_MAX_RETRIES 		5
 #define APCONF_INTERVAL 		2
 
+const char *dbh_mode_to_str(enum cntlr_discovery_mode mode) {
+	switch (mode) {
+	case DYNAMIC_CNTLR_MODE_AUTO:
+		return "auto";
+	case DYNAMIC_CNTLR_MODE_DISABLED:
+		return "disabled";
+	case DYNAMIC_CNTLR_MODE_CONTROLLER:
+		return "controller";
+	default:
+		break;
+	}
+	return "unknown";
+}
+
+enum cntlr_discovery_mode dbh_str_to_mode(const char *mode) {
+	if (!strncmp(mode, "auto", 4)) {
+		return DYNAMIC_CNTLR_MODE_AUTO;
+	} else if (!strncmp(mode, "disabled", 4)) {
+		return DYNAMIC_CNTLR_MODE_DISABLED;
+	} else if (!strncmp(mode, "controller", 4)) {
+		return DYNAMIC_CNTLR_MODE_CONTROLLER;
+	}
+	return DYNAMIC_CNTLR_MODE_UNKNOWN;
+}
 
-static void issue_discovery(struct dynbh_ctx *priv, struct ethport *port)
+static void dbh_send_topo_discovery(struct dynbh_ctx *priv, struct ethport *port)
 {
 	struct agent *a = container_of(priv, struct agent, priv);
 	struct cmdu_buff *resp;
@@ -58,13 +80,13 @@ static void issue_discovery(struct dynbh_ctx *priv, struct ethport *port)
 static void bridge_delif(struct dynbh_ctx *priv, struct ethport *port)
 {
 	br_delif(priv->al_bridge, port->ifname);
-	issue_discovery(priv, port);
+	dbh_send_topo_discovery(priv, port);
 }
 
 static void bridge_addif(struct dynbh_ctx *priv, struct ethport *port)
 {
 	br_addif(priv->al_bridge, port->ifname);
-	issue_discovery(priv, port);
+	dbh_send_topo_discovery(priv, port);
 }
 
 static void i1905_modif(struct dynbh_ctx *priv, struct ethport *port, bool add)
@@ -79,7 +101,7 @@ static void i1905_modif(struct dynbh_ctx *priv, struct ethport *port, bool add)
 	uobj_id = ubus_get_object(priv->ubus_ctx, objname);
 	if ((uobj_id == WIFI_OBJECT_INVALID && !add) ||
 	    (uobj_id != WIFI_OBJECT_INVALID && add)) {
-		err("%s: error case, objid:%u add:%d objname:%s\n", __func__, uobj_id, add, objname);
+		err("%s: NOP case, objid:%u add:%d objname:%s\n", __func__, uobj_id, add, objname);
 		return;
 	}
 
@@ -116,12 +138,13 @@ static void i1905_delif(struct dynbh_ctx *priv, struct ethport *port)
 static void link_up(struct ethport *port)
 {
 	struct agent *a = container_of(port->ctx, struct agent, priv);
-	//char fmt[64] = {0};
+	char fmt[64] = {0};
 
-	agent_exec_platform_scripts("/lib/wifi/multiap bstas_down");
+	agent_exec_platform_scripts("bstas_down");
 	err("|%s:%d| port:%s\n", __func__, __LINE__, port->ifname);
-	runCmd("/lib/wifi/multiap set_uplink eth %s " MACFMT, port->ifname, MAC2STR(port->macaddr));
-	// TODO: call conditionally
+
+	snprintf(fmt, sizeof(fmt), "set_uplink eth %s" MACFMT, port->ifname, MAC2STR(port->macaddr));
+	agent_exec_platform_scripts(fmt);
 
 #ifdef AGENT_ISLAND_PREVENTION
 	if (a->cfg.island_prevention)
@@ -131,8 +154,6 @@ static void link_up(struct ethport *port)
 			__LINE__);
 	timer_set(&a->autocfg_dispatcher, 1 * 1000);
 	timestamp_update(&a->eth_connect_t);
-
-	err("|%s:%d|\n", __func__, __LINE__);
 }
 
 /**
@@ -143,24 +164,22 @@ static void link_down(struct ethport *port)
 {
 	char fmt[64] = {0};
 
-	err("|%s:%d|\n", __func__, __LINE__);
-	snprintf(fmt, sizeof(fmt), "/lib/wifi/multiap bstas_up %s", port->ifname);
-	err("|%s:%d|\n", __func__, __LINE__);
-	runCmd(fmt);
+	snprintf(fmt, sizeof(fmt), "bstas_up %s", port->ifname);
+	agent_exec_platform_scripts(fmt);
 }
 
 #ifdef PERSIST_CONTROLLER
 static void controller_discovery_persist(struct agent *a)
 {
-	err("|%s:%d|\n", __func__, __LINE__);
-	runCmd("/lib/wifi/dynbhd/api persist_cntlr");
+	agent_exec_platform_scripts("persist_cntlr");
+	dbh_config_set_controller_select(&a->priv, DYNAMIC_CNTLR_MODE_CONTROLLER, true, true);
+
 	agent_config_reload(a);
 }
 
 static void controller_discovery_disable(struct agent *a)
 {
-	err("|%s:%d|\n", __func__, __LINE__);
-	runCmd("/lib/wifi/dynbhd/api disable_cntlr");
+	dbh_config_set_controller_select(&a->priv, DYNAMIC_CNTLR_MODE_DISABLED, false, false);
 	agent_config_reload(a);
 }
 
@@ -169,7 +188,7 @@ static int controller_discovery_dhcp(void)
 	char rc[2] = {0};
 
 	err("|%s:%d|\n", __func__, __LINE__);
-	chrCmd(rc, 2, "/lib/wifi/dynbhd/api dhcp_discovery");
+	chrCmd(rc, 2, "/lib/wifi/multiap dhcp_discovery");
 
 	return atoi(rc);
 }
@@ -177,9 +196,7 @@ static int controller_discovery_dhcp(void)
 
 void delif(struct dynbh_ctx *priv, struct ethport *port)
 {
-	//runCmd("/lib/wifi/dynbhd/api bridge_delif %s", port->ifname);
 	bridge_delif(priv, port);
-	//runCmd("ubus call ieee1905 add_interface '{\"ifname\":\"%s\"}'", port->ifname);
 	i1905_addif(port->ctx, port);
 	err("brctl delif %s %s\n", port->ctx->al_bridge, port->ifname);
 }
@@ -189,10 +206,8 @@ void addif(struct ethport *port)
 	if (if_isbridge_interface(port->ifname))
 		return;
 
-	//runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname);
 	i1905_delif(port->ctx, port);
 	bridge_addif(port->ctx, port);
-	//runCmd("/lib/wifi/dynbhd/api bridge_addif %s", port->ifname);  /* add back to bridge */
 	err("cmd: brctl addif %s %s\n", port->ctx->al_bridge, port->ifname); /* add back to bridge */
 }
 
@@ -282,7 +297,6 @@ static void send_apconf_cb(atimer_t *t)
 	uint16_t mid = 0;
 
 	err("|%s:%d| sending query num %d for ifname:%s alid:"MACFMT" \n", __func__, __LINE__, (port->num_mid+1), port->ifname, MAC2STR(port->ctx->almac));
-	//runCmd("[ -n \"$(ubus list ieee1905.al.%s)\" ] || ubus call ieee1905 add_interface '{\"ifname\":\"%s\"}'", port->ifname, port->ifname);
 	i1905_addif(port->ctx, port);
 
 	//SEND AUTOCONF SEARCH
@@ -353,11 +367,14 @@ void dynbh_handle_port_down(struct dynbh_ctx *priv, struct ethport *port)
 		port->active_uplink = false;
 
 		list_for_each_entry(p, &priv->ethportlist, list) {
+			char fmt[64] = {0};
+
 			if (!p->loop)
 				continue;
 
 			addif(p);
-			runCmd("/lib/wifi/multiap set_uplink eth %s " MACFMT, p->ifname, MAC2STR(p->macaddr));
+			snprintf(fmt, sizeof(fmt), "set_uplink eth %s " MACFMT, p->ifname, MAC2STR(p->macaddr));
+			agent_exec_platform_scripts(fmt);
 #ifdef AGENT_ISLAND_PREVENTION
 			if (a->cfg.island_prevention)
 				wifiagent_toggle_fh(a, false, "all", true);
@@ -370,7 +387,7 @@ void dynbh_handle_port_down(struct dynbh_ctx *priv, struct ethport *port)
 
 		if (!found) {
 			link_down(port);
-			runCmd("/lib/wifi/multiap unset_uplink eth");
+			agent_exec_platform_scripts("unset_uplink eth");
 #ifdef AGENT_ISLAND_PREVENTION
 			if (a->cfg.island_prevention)
 				wifiagent_toggle_fh(a, false, "all", true);
@@ -468,7 +485,9 @@ int dbh_handle_autoconfig_response(struct dynbh_ctx *priv, char *ifname,
 		if (!port) {
 			err("No interface matching %s found - no action\n", ifname);
 			return -1;
-		} else if (port->active_uplink || port->loop) {
+		}
+
+		if (port->active_uplink || port->loop) {
 			err("Interface %s already known to be connected to a controller - no action\n", ifname);
 			goto out;
 		} else {
@@ -551,12 +570,13 @@ int dbh_handle_autoconfig_search(struct dynbh_ctx *priv, char *ifname, uint16_t
 	if (!port) {
 		err("No interface matching %s found - no action\n", ifname);
 		return -1;
-	} else if (port->active_uplink || port->loop) {
+	}
+
+	if (port->active_uplink || port->loop) {
 		err("Interface %s already known to be connected to a controller - no action\n", ifname);
 		goto out;
-	} else {
+	} else
 		err("Interface %s is not known to have a controller\n", ifname);
-	}
 
 
 	if (!agent_is_backhaul_type_eth()) {
diff --git a/src/dynbh/dynbh.h b/src/dynbh/dynbh.h
index 3dfc107d8..fa16d27dd 100644
--- a/src/dynbh/dynbh.h
+++ b/src/dynbh/dynbh.h
@@ -16,6 +16,7 @@ enum cntlr_discovery_mode {
 	DYNAMIC_CNTLR_MODE_AUTO,
 	DYNAMIC_CNTLR_MODE_DISABLED,
 	DYNAMIC_CNTLR_MODE_CONTROLLER,
+	DYNAMIC_CNTLR_MODE_UNKNOWN,
 };
 #endif
 
@@ -50,6 +51,11 @@ struct dynbh_ctx {
 #endif
 
 };
+#ifdef PERSIST_CONTROLLER
+const char *dbh_mode_to_str(enum cntlr_discovery_mode mode);
+enum cntlr_discovery_mode dbh_str_to_mode(const char *mode);
+#endif
+
 
 int dynbh_publish_object(struct dynbh_ctx *c, const char *objname);
 
diff --git a/src/nl.c b/src/nl.c
index acae98544..1da363579 100644
--- a/src/nl.c
+++ b/src/nl.c
@@ -23,6 +23,9 @@
 #include "agent.h"
 #include "config.h"
 #include "utils/utils.h"
+#ifdef DYNBH
+#include "dynbh/dbh_nl.h"
+#endif
 
 struct nl_msg;
 
@@ -468,43 +471,48 @@ int nl_main_cb(struct nl_msg *msg, void *arg)
 	a->ts.check_tags = false;
 
 	switch (nlh->nlmsg_type) {
-	case RTM_GETLINK:
 	case RTM_NEWLINK:
-	//case RTM_DELLINK:
-		{
-			struct ifinfomsg *ifi;
-			char ifname[16] = {0};
+#ifdef DYNBH
+		if (a->has_dynbh) {
+			fprintf(stderr, "%s!\n", (true ? "newlink":"dellink"));
+			dynbh_handle_nlevents_link(&a->priv, nlh, true);
+		}
+#endif
+	case RTM_GETLINK:
+	{
+		struct ifinfomsg *ifi;
+		char ifname[16] = {0};
 
-			ifi = NLMSG_DATA(nlh);
+		ifi = NLMSG_DATA(nlh);
 
-			if (if_indextoname(ifi->ifi_index, ifname) == NULL)
-				break;
+		if (if_indextoname(ifi->ifi_index, ifname) == NULL)
+			break;
 
-			fprintf(stderr, "ifname = %s  ifindex = %d family = %u status = %s  action = %s\n",
-			       ifname,
-			       ifi->ifi_index,
-			       ifi->ifi_family,
-			       !!(ifi->ifi_flags & IFF_UP) ? "up" : "down",
-			       nlh->nlmsg_type == RTM_GETLINK ? "RTM_GETLINK" :
-			       nlh->nlmsg_type == RTM_NEWLINK ? "RTM_NEWLINK" :
-			       "RTM_DELLINK");
+		fprintf(stderr, "ifname = %s  ifindex = %d family = %u status = %s  action = %s\n",
+			ifname,
+			ifi->ifi_index,
+			ifi->ifi_family,
+			!!(ifi->ifi_flags & IFF_UP) ? "up" : "down",
+			nlh->nlmsg_type == RTM_GETLINK ? "RTM_GETLINK" :
+			nlh->nlmsg_type == RTM_NEWLINK ? "RTM_NEWLINK" :
+			"RTM_DELLINK");
 
 /*
-			if (!(ifi->ifi_flags & IFF_UP))
-				break;
+		if (!(ifi->ifi_flags & IFF_UP))
+			break;
 */
-			ts_check_ifi(a, ifi, ifname);
+		ts_check_ifi(a, ifi, ifname);
 
-			if (!a->cfg.brcm_setup)
-				break;
+		if (!a->cfg.brcm_setup)
+			break;
 
-			if (strstr(ifname, "wds"))
-				nl_wds_checkadd_to_bridge(a, ifname, !(ifi->ifi_flags & IFF_UP));
-			else if (!strncmp(ifname, a->cfg.al_bridge, IFNAMSIZ))
-				nl_wds_start_all(a);
+		if (strstr(ifname, "wds"))
+			nl_wds_checkadd_to_bridge(a, ifname, !(ifi->ifi_flags & IFF_UP));
+		else if (!strncmp(ifname, a->cfg.al_bridge, IFNAMSIZ))
+			nl_wds_start_all(a);
 
-			break;
-		}
+		break;
+	}
 	default:
 		break;
 
diff --git a/src/script/multiap b/src/script/multiap
index abf4b2f70..f8b28eb86 100755
--- a/src/script/multiap
+++ b/src/script/multiap
@@ -1559,6 +1559,62 @@ bstas_down() {
 	config_foreach update_bstas bsta
 }
 
+persist_cntlr() {
+	local mode=$(uci -q get mapagent.@controller_select[0].id)
+	local brcm_setup="$(uci -q get mapagent.agent.brcm_setup)"
+
+	agent_update_acs() {
+		local section=$1
+
+		config_get device ${section} device
+		config_get type ${section} type
+		config_get ifname ${section} ifname
+
+		[ "$type" != "fronthaul" ] && return
+
+		nvram unset ${ifname}_mode > /dev/null 2>&1
+
+	}
+
+	agent_disable_bsta() {
+		local section=$1
+
+		uci set mapagent.${section}.enabled="0"
+	}
+
+	wireless_disable_bsta() {
+		local section=$1
+
+		config_get mode ${section} mode
+		config_get ifname ${section} ifname
+
+		[ "$mode" != "sta" ] && return
+
+		uci set wireless.${section}.disabled="1"
+		wpa_cli -i $ifname disable 0
+	}
+
+	[ "$mode" == "auto" ] || return
+
+	config_load "mapagent"
+	config_foreach agent_disable_bsta bsta
+	[ "$brcm_setup" = "1" ] && config_foreach agent_update_acs ap
+
+	config_load "wireless"
+	config_foreach wireless_disable_bsta wifi-iface
+	uci commit wireless
+}
+
+
+dhcp_discovery() {
+	local bridge="$1"
+
+	[ "$bridge" = "" -o -z $bridge ] && bridge="br-lan"
+
+	udhcpc -qn -t 1 -T1 -i $bridge > /dev/null 2>&1
+
+	echo "$?"
+}
 
 func=$1
 shift
@@ -1604,6 +1660,8 @@ case "$func" in
 	reset) reset $@;;
 	bstas_up) bstas_up $@;;
 	bstas_down) bstas_down $@;;
+	persist_cntlr) persist_cntlr $@;;
+	dhcp_discovery) dhcp_discovery $@;;
 	--help|help) usage;;
 	*) usage; exit 1;;
 esac
-- 
GitLab