diff --git a/src/Makefile b/src/Makefile
index 86b626e99f7df0678da0f39e21fc883b07fbc1b5..226a4c81952ebbf5dca308950a9cc487acc96b18 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,10 +1,10 @@
 CC ?= gcc
-EXECS = mapagent dynbh/dynbhd
+EXECS = mapagent #dynbh/dynbhd
 CFLAGS+=-I. -Iutils -D_GNU_SOURCE -DCONFIG_ALL_RADIOS #DEBUG=1
 CFLAGS+= -ggdb3 -Wall -Werror
 CFLAGS += -I/usr/include/libnl3
 
-CFLAGS += -DVENDOR_EXTENSION
+CFLAGS += -DVENDOR_EXTENSION -DDYNBH
 
 ifeq (,$(findstring EASYMESH_VERSION,$(CFLAGS)))
 $(info EASYMESH_VERSION is not set. Build for 6)
@@ -47,7 +47,10 @@ AGENT_OBJS = \
 	dppfrag.o \
 	dpphandler.o \
 	qos.o \
-	unasta.o
+	unasta.o \
+	dynbh/dynbh.o \
+	dynbh/dbh_nl.o \
+	dynbh/dbh_config.o
 
 ifneq (,$(findstring VENDOR_EXTENSION,$(CFLAGS)))
 AGENT_OBJS += extension.o
@@ -82,8 +85,8 @@ all: $(EXECS) extensions
 mapagent: $(OBJS) $(AGENT_OBJS)
 	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
 
-dynbh/dynbhd: $(OBJS) dynbh/dynbh.o dynbh/dbh_nl.o dynbh/dbh_config.o
-	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+#dynbh/dynbhd: $(OBJS) dynbh/dynbh.o dynbh/dbh_nl.o dynbh/dbh_config.o
+#	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
 
 extensions:
 	@echo "$(plugin_subdirs)"
diff --git a/src/agent.c b/src/agent.c
index 89a0439a05b8d6d7b58ff7ecc80543c41314161e..d109f4ddebbc21172aef4979df31ed59849b0c88 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -51,6 +51,12 @@
 #include "backhaul.h"
 #include "backhaul_blacklist.h"
 #include "config.h"
+#ifdef DYNBH
+#ifdef PERSIST_CONTROLLER
+#include "dynbh/dbh_config.h"
+#endif
+#include "dynbh/dynbh.h"
+#endif
 #if (EASYMESH_VERSION >= 3)
 #ifdef USE_LIBDPP
 #include "dpp.h"
@@ -471,14 +477,14 @@ void wifiagent_log_cntlrinfo(struct agent *a)
 	agent_notify_event(a, "map.agent", ev);
 }
 
-int ubus_call_object_args(struct agent *a, wifi_object_t wobj,
+int ubus_call_object_args(struct ubus_context *ctx, wifi_object_t wobj,
 			  struct blob_buf *bb, const char *method,
 			  void (*response_cb)(struct ubus_request *, int, struct blob_attr *),
 			  void *priv)
 {
 	int ret;
 
-	ret = ubus_invoke(a->ubus_ctx, wobj, method, bb->head,
+	ret = ubus_invoke(ctx, wobj, method, bb->head,
 				response_cb, priv, 2 * 1000);
 	if (ret) {
 		err("Failed to get '%s' (ret = %d)\n", method, ret);
@@ -488,7 +494,7 @@ int ubus_call_object_args(struct agent *a, wifi_object_t wobj,
 	return 0;
 }
 
-int ubus_call_object(struct agent *a, wifi_object_t wobj,
+int ubus_call_object(struct ubus_context *ctx, wifi_object_t wobj,
 		const char *method,
 		void (*response_cb)(struct ubus_request *, int, struct blob_attr *),
 		void *priv)
@@ -497,7 +503,7 @@ int ubus_call_object(struct agent *a, wifi_object_t wobj,
 	int ret;
 
 	blob_buf_init(&bb, 0);
-	ret = ubus_invoke(a->ubus_ctx, wobj, method, bb.head,
+	ret = ubus_invoke(ctx, wobj, method, bb.head,
 				response_cb, priv, 2 * 1000);
 	if (ret) {
 		err("Failed to get '%s' (ret = %d)\n", method, ret);
@@ -4257,7 +4263,7 @@ static void uobj_add_event_handler(void *agent, struct blob_attr *msg)
 		if (ret)
 			return;
 
-		ubus_call_object(a, ieee1905_obj, "info", parse_i1905_info, a);
+		ubus_call_object(a->ubus_ctx, ieee1905_obj, "info", parse_i1905_info, a);
 	} else if (!strncmp(path, "wpa_supplicant.", 15)) {
 		char *ifname = path + 15;
 
@@ -5798,7 +5804,7 @@ static int init_wifi_radios(struct agent *a)
 		}
 
 		dbg("%s: getting radio:%s status\n", __func__, re->name);
-		ret = ubus_call_object(a, r_wobj, "status", parse_radio, re);
+		ret = ubus_call_object(a->ubus_ctx, r_wobj, "status", parse_radio, re);
 
 		/* Get fresh opclass preferences after scan */
 		wifi_radio_update_opclass_preferences(a, re, 1);
@@ -6797,7 +6803,7 @@ int agent_init_interfaces(struct agent *a)
 		return -1;
 	}
 
-	ubus_call_object(a, ieee1905_obj, "info", parse_i1905_info, a);
+	ubus_call_object(a->ubus_ctx, ieee1905_obj, "info", parse_i1905_info, a);
 
 	ret = init_wifi_radios(a);
 	if (ret || list_empty(&a->radiolist)) {
@@ -6897,7 +6903,7 @@ int agent_init_interfaces(struct agent *a)
 			continue;
 		}
 
-		ret = ubus_call_object(a, uobj_id, "status", fn_parser, fn);
+		ret = ubus_call_object(a->ubus_ctx, uobj_id, "status", fn_parser, fn);
 		if (ret) {
 			err("Failed to get '%s' (ret = %d) name:%s\n", "status", ret, objname);
 			timer_set(&a->init_ifaces_scheduler,
@@ -6917,8 +6923,8 @@ int agent_init_interfaces(struct agent *a)
 		if (band)
 			blobmsg_add_u32(&bb, "band", band);
 #endif
-		ubus_call_object_args(a, uobj_id, &bb, "stats", parse_ap_stats, bss);
-		ubus_call_object_args(a, uobj_id, &bb, "dump_beacon", parse_beacon_params, bss);
+		ubus_call_object_args(a->ubus_ctx, uobj_id, &bb, "stats", parse_ap_stats, bss);
+		ubus_call_object_args(a->ubus_ctx, uobj_id, &bb, "dump_beacon", parse_beacon_params, bss);
 		blob_buf_free(&bb);
 	}
 
@@ -6986,7 +6992,7 @@ int agent_init_interfaces(struct agent *a)
 							objname, b->name);
 			continue;
 		}
-		ret = ubus_call_object(a, uobj_id, "status", bk_parser, bn);
+		ret = ubus_call_object(a->ubus_ctx, uobj_id, "status", bk_parser, bn);
 		if (ret) {
 			err("Failed to get '%s' (ret = %d) name:%s\n", "status", ret, objname);
 			timer_set(&a->init_ifaces_scheduler,
@@ -7168,7 +7174,7 @@ static void agent_fetch_ap_stats(struct agent *a)
 			if (band)
 				blobmsg_add_u32(&bb, "band", band);
 #endif
-			ubus_call_object_args(a, uobj_id, &bb, "stats", parse_ap_stats, bss);
+			ubus_call_object_args(a->ubus_ctx, uobj_id, &bb, "stats", parse_ap_stats, bss);
 			blob_buf_free(&bb);
 		}
 	}
@@ -7224,7 +7230,7 @@ static void agent_radio_stats_cb(atimer_t *t)
 		if (r_wobj == WIFI_OBJECT_INVALID)
 			continue;
 
-		ubus_call_object(a, r_wobj, "stats", parse_radio_stats, re);
+		ubus_call_object(a->ubus_ctx, r_wobj, "stats", parse_radio_stats, re);
 	}
 
 	timer_set(&a->radio_stats_scheduler, RADIO_STATS_TIMER);
@@ -7414,15 +7420,18 @@ static void agent_dispatch_autoconfig(atimer_t *t)
 
 	list_for_each_entry(re, &a->radiolist, list) {
 		struct cmdu_buff *cmdu;
+		uint8_t ieee1905band;
 
 		if (!a->active_cntlr) {
 			trace("|%s:%d| No active Controller present!\n", __func__, __LINE__);
 			re->state = AUTOCFG_ACTIVE;
 		}
 
-		cmdu = agent_gen_ap_autoconfig_search(a, re, 0x02);
+		ieee1905band = wifi_band_to_ieee1905band(re->band);
+		cmdu = agent_gen_ap_autoconfig_search(a, ieee1905band, 0x02);
 		if (!cmdu)
 			continue;
+
 		trace("|%s:%d| Sending Autoconfig Search for radio %s(%s)\n",
 				__func__, __LINE__, re->name,
 				(re->band == BAND_2 ? "2.4GHz" : "5GHz"));
@@ -8116,6 +8125,23 @@ void run_agent(void *opts)
 
 	timestamp_update(&w->start_t);
 
+#ifdef DYNBH
+#ifdef PERSIST_CONTROLLER
+	dbh_config_load(priv);
+#endif
+	int num = 0;
+	char ifs[16][16] = {0};
+	int i;
+
+	memcpy(w->priv.almac, w->almac, 6);
+	w->priv.ubus_ctx = ctx;
+	strncpy(w->priv.al_bridge, w->cfg.al_bridge, sizeof(w->priv.al_bridge) - 1);
+	INIT_LIST_HEAD(&w->priv.ethportlist);
+	get_ethportslist(&num, ifs);
+	for (i = 0; i < num; i++)
+		alloc_ethport_search(&w->priv, ifs[i]);
+#endif
+
 	uloop_run();
 
 /* out_and_exit: */
diff --git a/src/agent.h b/src/agent.h
index d68738db7b1de65ec61e59eb37cf5b8a880c8c1a..758b5b2bb2940fc6171c2e126d41e8bf351cfd1c 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -24,6 +24,7 @@
 #include <stdbool.h>
 #include <wifidefs.h>
 
+#include "dynbh/dynbh.h"
 #include "utils/allmac.h"
 #include "utils/debug.h"
 #include "config.h"
@@ -962,6 +963,9 @@ struct agent {
 	atimer_t dpp_legacy_timeout;
 #endif
 	/* dynamic backhaul */
+#ifdef DYNBH
+	struct dynbh_ctx priv;
+#endif
 	atimer_t dynbh_scheduler;
 	bool dynbh_upgrade_ongoing; /* when true upgrade attempt ongoing */
 	int dynbh_attempts; /* number of upgrade attempts since connection */
@@ -1070,7 +1074,11 @@ int prepare_tunneled_message(void *agent, const char *ifname,
 		uint8_t protocol, const char *framestr);
 int wifi_mod_bridge(struct agent *a, struct netif_bk *bk, bool add);
 uint32_t ubus_get_object(struct ubus_context *ctx, const char *name);
-int ubus_call_object(struct agent *a, wifi_object_t wobj, const char *method,
+int ubus_call_object_args(struct ubus_context *ctx, wifi_object_t wobj,
+			  struct blob_buf *bb, const char *method,
+			  void (*response_cb)(struct ubus_request *, int, struct blob_attr *),
+			  void *priv);
+int ubus_call_object(struct ubus_context *ctx, wifi_object_t wobj, const char *method,
 		void (*response_cb)(struct ubus_request *, int, struct blob_attr *), void *priv);
 int wifi_radio_scan_req(struct agent *a, struct wifi_radio_element *re,
 			       const char *ssid, int num_opclass,
diff --git a/src/agent_cmdu.c b/src/agent_cmdu.c
index 4d4d580be62145ed35c2e92d4f86dd7766e4168b..9d32c252c6c38f5b5d3f1aff798a30c2571ff405 100644
--- a/src/agent_cmdu.c
+++ b/src/agent_cmdu.c
@@ -39,7 +39,7 @@
 
 
 struct cmdu_buff *agent_gen_ap_autoconfig_search(struct agent *a,
-		struct wifi_radio_element *radio, uint8_t profile)
+		uint8_t ieee1905band, uint8_t profile)
 {
 	struct cmdu_buff *frm = NULL;
 	int ret = 0;
@@ -63,9 +63,6 @@ struct cmdu_buff *agent_gen_ap_autoconfig_search(struct agent *a,
 	if (ret)
 		goto out;
 
-	band = wifi_band_to_ieee1905band(radio->band);
-	trace("radio band = %d, band = %d\n", radio->band, band);
-
 	ret = agent_gen_autoconf_freq_band(a, frm, band);
 	if (ret)
 		goto out;
@@ -102,7 +99,7 @@ struct cmdu_buff *agent_gen_ap_autoconfig_search(struct agent *a,
 	memcpy(frm->origin, origin, 6);
 	cmdu_put_eom(frm);
 
-	dbg("%s:%d: radio = %s\n", __func__, __LINE__, radio->name);
+	dbg("%s:%d: band = 0x%x\n", __func__, __LINE__, ieee1905band);
 	return frm;
 out:
 	cmdu_free(frm);
@@ -1811,7 +1808,8 @@ error:
 	return NULL;
 }
 
-struct cmdu_buff *agent_gen_topology_discovery(struct agent *a)
+struct cmdu_buff *agent_gen_topology_discovery(struct agent *a, uint8_t *almac,
+					       uint8_t *macaddr)
 {
 	struct cmdu_buff *frm = NULL;
 	uint16_t mid = 0;
@@ -1824,11 +1822,11 @@ struct cmdu_buff *agent_gen_topology_discovery(struct agent *a)
 		return NULL;
 	}
 
-	ret = agent_gen_al_mac(a, frm, a->almac);
+	ret = agent_gen_al_mac(a, frm, almac);
 	if (ret)
 		goto out;
 
-	ret = agent_gen_mac(a, frm, a->almac);
+	ret = agent_gen_mac(a, frm, macaddr);
 	if (ret)
 		goto out;
 
diff --git a/src/agent_cmdu.h b/src/agent_cmdu.h
index fd100dc763bacceca911a29862d190fa9d79b2cc..e3f1684d997e2f3e6f2e58badaba2addbac1421d 100644
--- a/src/agent_cmdu.h
+++ b/src/agent_cmdu.h
@@ -30,7 +30,7 @@ struct wifi_scan_request_radio;
 #define CH_SCAN_RESP_CMDU_MAX_LEN 1400
 
 struct cmdu_buff *agent_gen_ap_autoconfig_search(struct agent *a,
-		struct wifi_radio_element *radio, uint8_t profile);
+		uint8_t ieee1905band, uint8_t profile);
 struct cmdu_buff *agent_gen_ap_metrics_response(struct agent *a,
 		struct cmdu_buff *rec_cmdu, struct node *n);
 struct cmdu_buff *agent_gen_higher_layer_response(struct agent *a,
@@ -62,7 +62,7 @@ struct cmdu_buff *agent_gen_ap_caps_response(struct agent *a,
 		struct cmdu_buff *rec_cmdu);
 struct cmdu_buff *agent_gen_bk_caps_response(struct agent *a,
 		struct cmdu_buff *cmdu);
-struct cmdu_buff *agent_gen_topology_notification (struct agent *agent,
+struct cmdu_buff *agent_gen_topology_notification(struct agent *agent,
 		struct sta *s, uint8_t *bssid, uint8_t assoc_event);
 struct cmdu_buff *agent_gen_ap_autoconfig_wsc(struct agent *a, uint8_t *origin,
 		struct wifi_radio_element *radio);
@@ -96,7 +96,8 @@ struct cmdu_buff *agent_gen_assoc_sta_metric_responsex(struct agent *a,
 struct cmdu_buff *agent_gen_oper_channel_response(struct agent *a,
 		struct wifi_radio_element *radio, uint32_t channel,
 		uint32_t bandwidth, bool all);
-struct cmdu_buff *agent_gen_topology_discovery(struct agent *a);
+struct cmdu_buff *agent_gen_topology_discovery(struct agent *a, uint8_t *almac,
+					       uint8_t *macaddr);
 struct cmdu_buff *agent_gen_failed_connection(struct agent *a,
 		uint8_t *sta, int status_code, int reason_code);
 
diff --git a/src/agent_map.c b/src/agent_map.c
index dd1cc0ccef7dd7f442e757d6ef94d5676d41c6f0..868d638f6462d2d496f039ae468d94e78675edd2 100644
--- a/src/agent_map.c
+++ b/src/agent_map.c
@@ -1375,7 +1375,7 @@ int handle_ap_autoconfig_search(void *agent, struct cmdu_buff *rx_cmdu,
 			}
 		}
 	}
-
+	dbh_handle_autoconfig_search(&a->priv, rx_cmdu->dev_ifname, cmdu_get_mid(rx_cmdu), tv);
 	return 0;
 }
 
@@ -1619,6 +1619,7 @@ int handle_ap_autoconfig_response(void *agent, struct cmdu_buff *rx_cmdu,
 		agent_reschedule_heartbeat_autocfg(a, HEARTBEAT_AUTOCFG_INTERVAL);
 	}
 
+	dbh_handle_autoconfig_response(&a->priv, rx_cmdu->dev_ifname, cmdu_get_mid(rx_cmdu), tv);
 	return 0;
 }
 
diff --git a/src/backhaul.c b/src/backhaul.c
index 50beae76e342791eb07d16c381e1927047b15905..05d0c6c514713a740d909b3383df5cc41aa155c1 100644
--- a/src/backhaul.c
+++ b/src/backhaul.c
@@ -542,7 +542,7 @@ void agent_check_bsta_connections(struct agent *a)
 #endif
 		uobjid = ubus_get_object(a->ubus_ctx, objname);
 
-		ubus_call_object(a, uobjid, "status", cb, bk);
+		ubus_call_object(a->ubus_ctx, uobjid, "status", cb, bk);
 	}
 
 	/* reloading is costly - only do it once after all parsing is done */
diff --git a/src/dynbh/dbh_config.c b/src/dynbh/dbh_config.c
index 29fcade160fe5d37eb70239ab6a5354c45f097ae..6d35b04fa7736e002807bddd723b821ad9762fc7 100644
--- a/src/dynbh/dbh_config.c
+++ b/src/dynbh/dbh_config.c
@@ -1,3 +1,4 @@
+#if DYNBH
 #include "dbh_config.h"
 
 #include <stdbool.h>
@@ -102,3 +103,4 @@ int dbh_config_load(struct dynbh_ctx *cfg)
 	return 0;
 }
 #endif
+#endif
diff --git a/src/dynbh/dbh_config.h b/src/dynbh/dbh_config.h
index 97c684be589aabd706ca7a7fb6d1eb156277814a..ff6ea73831333b9dbdaf787d570378ae47893dde 100644
--- a/src/dynbh/dbh_config.h
+++ b/src/dynbh/dbh_config.h
@@ -1,3 +1,4 @@
+#ifdef DYNBH
 #ifndef DBH_CONFIG_H
 #define DBH_CONFIG_H
 
@@ -9,4 +10,5 @@ int set_value_by_string(const char *package, const char *section,
 		const char *key, const char *value, enum uci_option_type type);
 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 46b40c3f8b7ba4e5eca70c756448e39ebdfc9c88..5d31ff2e0b8d9ab14f00e0dced80ac2544fc9359 100644
--- a/src/dynbh/dbh_nl.c
+++ b/src/dynbh/dbh_nl.c
@@ -1,14 +1,16 @@
 /*
- * i1905_netlink.c - netlink interface to kernel.
+ * dbh_nl.c - netlink interface to kernel.
  *
- * Copyright (C) 2021 IOPSYS Software Solutions AB. All rights reserved.
+ * Copyright (C) 2021-2024 IOPSYS Software Solutions AB. All rights reserved.
+ * Copyright (C) 2025 Genexis AB.
  *
- * Author: anjan.chanda@iopsys.eu
+ * Author: jakob.olsson@genexis.eu
  *
  * See LICENSE file for license related information.
  *
  */
 
+#ifdef DYNBH
 #include "dbh_nl.h"
 
 #include <time.h>
@@ -251,3 +253,4 @@ void i1905_unregister_nlevents(struct dynbh_ctx *priv)
 		rtnl_event.sock = NULL;
 	}
 }
+#endif
diff --git a/src/dynbh/dbh_nl.h b/src/dynbh/dbh_nl.h
index a65f459804fe3ff65def1f093e86fe3d3345a459..ead974e78e6bb35cdf8e9e7b470d0f838b4e2d33 100644
--- a/src/dynbh/dbh_nl.h
+++ b/src/dynbh/dbh_nl.h
@@ -1,3 +1,4 @@
+#ifdef DYNBH
 #ifndef DBH_NL_H
 #define DBH_NL_H
 
@@ -6,4 +7,5 @@ struct dynbh_ctx;
 int i1905_register_nlevents(struct dynbh_ctx *priv);
 void i1905_unregister_nlevents(struct dynbh_ctx *priv);
 
-#endif
\ No newline at end of file
+#endif
+#endif
diff --git a/src/dynbh/dynbh.c b/src/dynbh/dynbh.c
index afc2d421435ecd00876f5f91829e376e08ce624a..e3dc26e2ca06de421851961ecfb0e7c73652a51d 100644
--- a/src/dynbh/dynbh.c
+++ b/src/dynbh/dynbh.c
@@ -1,7 +1,7 @@
+#ifdef DYNBH
 #include "dynbh.h"
 
 #include <1905_tlvs.h>
-#include <cmdu.h>
 #include <easy/if_utils.h>
 #include <easy/utils.h>
 #include <easymesh.h>
@@ -20,6 +20,10 @@
 #include <ubusmsg.h>
 #include <linux/if.h>
 
+#include "agent.h"
+#include "agent_cmdu.h"
+#include "backhaul.h"
+#include "1905_ubus.h"
 #include "dbh_config.h"
 #include "dbh_nl.h"
 #include "../utils/utils.h"
@@ -30,18 +34,97 @@
 #define BIT(n)	(1U << (n))
 #endif
 
-const char *PROG_NAME = "dynbhd";
-bool syslogging;
-bool usefifo;
-const char *outfile_path;
-const char *objname;
-
 #define map_plugin			IEEE1905_OBJECT_MULTIAP
 #define HEARTBEAT_PROBE_TIMEOUT 	30
 #define APCONF_MAX_RETRIES 		5
 #define APCONF_INTERVAL 		2
 
 
+#if 0
+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}\"}"
+}
+#endif
+static void issue_discovery(struct dynbh_ctx *priv, struct ethport *port)
+{
+	struct agent *a = container_of(priv, struct agent, priv);
+	struct cmdu_buff *resp;
+
+	resp = agent_gen_topology_discovery(a, priv->almac, port->macaddr);
+	if (resp) {
+	//	agent_send_cmdu(a, resp);
+	//	cmdu_free(resp);
+	}
+}
+
+static void bridge_delif(struct dynbh_ctx *priv, struct ethport *port)
+{
+	br_delif(priv->al_bridge, port->ifname);
+	issue_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);
+}
+
+static void i1905_modif(struct dynbh_ctx *priv, struct ethport *port, bool add)
+{
+	uint32_t uobj_id = WIFI_OBJECT_INVALID;
+	const char *fn = (add ? "add_interface" : "del_interface");
+	int ret;
+	struct blob_buf bb = {0};
+	//char objname[32];
+	//TODO: IF OBJECT ALREADY EXISTS AND ADDIF NOP
+
+	//snprintf(objname, sizeof(objname), "ieee1905.al.%s", port->ifname);
+
+	uobj_id = ubus_get_object(priv->ubus_ctx, "ieee1905");
+	if (uobj_id == WIFI_OBJECT_INVALID) {
+		err("%s: ieee1905 not present\n", __func__);
+		return;
+	}
+	//if (uobj_id == WIFI_OBJECT_INVALID && add
+	//    || uobj_id != WIFI_OBJECT_INVALID && !del) {
+	//	err("%s not present! skipping '%s' from config\n",
+	//					objname, f->name);
+	//	continue;
+	blob_buf_init(&bb, 0);
+	blobmsg_add_string(&bb, "ifname", port->ifname);
+	ret = ubus_call_object_args(priv->ubus_ctx, uobj_id, &bb, fn, NULL, NULL);
+	if (ret) {
+		err("%s: Failed to get '%s' (ret = %d) name:%s\n", __func__, fn, ret, "ieee1905");
+	}
+	blob_buf_free(&bb);
+}
+
+static void i1905_addif(struct dynbh_ctx *priv, struct ethport *port)
+{
+	i1905_modif(priv, port, true);
+}
+
+static void i1905_delif(struct dynbh_ctx *priv, struct ethport *port)
+{
+	i1905_modif(priv, port, false);
+}
+
+
 /**
  * disconnect & disable bstas
  * create /var/run/multiap/map.agent.bsta_global_disable
@@ -49,7 +132,7 @@ const char *objname;
  */
 static void link_up(struct ethport *port)
 {
-	fprintf(stderr, "|%s:%d|\n", __func__, __LINE__);
+	err("|%s:%d|\n", __func__, __LINE__);
 	runCmd("/lib/wifi/dynbhd/api up %s", port->ifname);
 	runCmd("/lib/wifi/multiap set_uplink eth %s", port->ifname);
 }
@@ -60,20 +143,20 @@ static void link_up(struct ethport *port)
  */
 static void link_down(void)
 {
-	fprintf(stderr, "|%s:%d|\n", __func__, __LINE__);
+	err("|%s:%d|\n", __func__, __LINE__);
 	runCmd("/lib/wifi/dynbhd/api down");
 }
 
 #ifdef PERSIST_CONTROLLER
 static void controller_discovery_persist(void)
 {
-	fprintf(stderr, "|%s:%d|\n", __func__, __LINE__);
+	err("|%s:%d|\n", __func__, __LINE__);
 	runCmd("/lib/wifi/dynbhd/api persist_cntlr");
 }
 
 static void controller_discovery_disable(void)
 {
-	fprintf(stderr, "|%s:%d|\n", __func__, __LINE__);
+	err("|%s:%d|\n", __func__, __LINE__);
 	runCmd("/lib/wifi/dynbhd/api disable_cntlr");
 }
 
@@ -81,18 +164,20 @@ static int controller_discovery_dhcp(void)
 {
 	char rc[2] = {0};
 
-	fprintf(stderr, "|%s:%d|\n", __func__, __LINE__);
+	err("|%s:%d|\n", __func__, __LINE__);
 	chrCmd(rc, 2, "/lib/wifi/dynbhd/api dhcp_discovery");
 
 	return atoi(rc);
 }
 #endif
 
-void delif(struct ethport *port)
+void delif(struct dynbh_ctx *priv, struct ethport *port)
 {
-	runCmd("/lib/wifi/dynbhd/api bridge_delif %s", port->ifname);
-	runCmd("ubus call ieee1905 add_interface '{\"ifname\":\"%s\"}'", port->ifname);
-	fprintf(stderr, "brctl delif %s %s\n", port->ctx->al_bridge, port->ifname);
+	//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);
 }
 
 void addif(struct ethport *port)
@@ -100,9 +185,11 @@ void addif(struct ethport *port)
 	if (if_isbridge_interface(port->ifname))
 		return;
 
-	runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname);
-	runCmd("/lib/wifi/dynbhd/api bridge_addif %s", port->ifname);  /* add back to bridge */
-	fprintf(stderr, "cmd: brctl addif %s %s\n", port->ctx->al_bridge, port->ifname); /* add back to bridge */
+	//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 */
 }
 
 struct ethport *ethport_by_ifname(struct dynbh_ctx *p,
@@ -122,13 +209,13 @@ struct ethport *ethport_by_mid(struct dynbh_ctx *p, uint16_t mid)
 {
 	struct ethport *port = NULL;
 
-	fprintf(stderr, "%s %d mid %d\n", __func__, __LINE__, mid);
+	err("%s %d mid %d\n", __func__, __LINE__, mid);
 
 	list_for_each_entry(port, &p->ethportlist, list) {
 		int i;
 
 		for (i = 0; i < port->num_mid; i++) {
-			fprintf(stderr, "%s %d mid[%d] %d\n", __func__, __LINE__, i, port->mid[i]);
+			err("%s %d mid[%d] %d\n", __func__, __LINE__, i, port->mid[i]);
 
 			if (port->mid[i] == mid)
 				return port;
@@ -148,7 +235,7 @@ static void bridge_readd(atimer_t *t)
 	if (port->active_uplink)
 		link_down();
 
-	fprintf(stderr, "|%s:%d| link timed out for iface:%s mid:%d, %d, add back to bridge\n", __func__, __LINE__, port->ifname, port->mid[0], port->mid[1]);
+	err("|%s:%d| link timed out for iface:%s mid:%d, %d, add back to bridge\n", __func__, __LINE__, port->ifname, port->mid[0], port->mid[1]);
 	port->loop = false;
 	port->active_uplink = false;
 	addif(port);
@@ -158,7 +245,7 @@ static void bridge_readd(atimer_t *t)
 	if (timeout > HEARTBEAT_PROBE_TIMEOUT)
 		timeout = HEARTBEAT_PROBE_TIMEOUT;
 
-	fprintf(stderr, "|%s:%d| timeout = %d\n", __func__, __LINE__, timeout);
+	err("|%s:%d| timeout = %d\n", __func__, __LINE__, timeout);
 
 	port->retries++;
 	timer_set(&port->send_apconf, timeout * 1000);
@@ -186,24 +273,25 @@ static void bridge_readd(atimer_t *t)
 static void send_apconf_cb(atimer_t *t)
 {
 	struct ethport *port = container_of(t, struct ethport, send_apconf);
-	char mid[16] = {0};
+	struct agent *a = container_of(port->ctx, struct agent, priv);
+	struct cmdu_buff *cmdu;
+	uint16_t mid = 0;
 
-	fprintf(stderr, "|%s:%d| sending query num %d for ifname:%s alid:%s \n", __func__, __LINE__, (port->num_mid+1), port->ifname, port->ctx->alidstr);
-	runCmd("[ -n \"$(ubus list ieee1905.al.%s)\" ] || ubus call ieee1905 add_interface '{\"ifname\":\"%s\"}'", port->ifname, port->ifname);
+	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);
 
 /*
 ubus call ieee1905 cmdu '{"ifname":"eth0", "dst":"01:80:C2:00:00:13", "type":7, "mid":0, "data":"010006A6CEDA6DAF8412s0d0001000e00010080000201018100020100b3000102000000"}'
 */
-	chrCmd(mid, 16, "ubus call ieee1905.al.%s cmdu '{\"dst\":\"01:80:C2:00:00:13\", \"type\":7, \"mid\":0, \"data\":\"010006%12s0d0001000e00010080000201018100020100b3000102000000\"}' | grep mid | cut -d' ' -f2", port->ifname, port->ctx->alidstr);
-	runCmd("ubus list ieee1905.al.%s", port->ifname);
-	fprintf(stderr, "mid = %s\n", mid);
-	errno = 0;
-	port->mid[port->num_mid] = (uint16_t) strtoul(mid, NULL, 10);
-	if (errno) {
-		fprintf(stderr, "Invalid mid value: %s\n", mid);
-		port->mid[port->num_mid] = 0;
-	}
-	fprintf(stderr, "mid[%d] = %u\n", port->num_mid, port->mid[port->num_mid]);
+	//chrCmd(mid, 16, "ubus call ieee1905.al.%s cmdu '{\"dst\":\"01:80:C2:00:00:13\", \"type\":7, \"mid\":0, \"data\":\"010006%12s0d0001000e00010080000201018100020100b3000102000000\"}' | grep mid | cut -d' ' -f2", port->ifname, port->ctx->alidstr);
+	//SEND AUTOCONF SEARCH
+	cmdu = agent_gen_ap_autoconfig_search(a, 0x01, 0x03);
+	ieee1905_ubus_send_al_cmdu(port->ctx->ubus_ctx, cmdu, &mid, port->ifname, a->pvid);
+	//runCmd("ubus list ieee1905.al.%s", port->ifname);
+	err("mid = %d\n", mid);
+	port->mid[port->num_mid] = mid;
+	err("mid[%d] = %d\n", port->num_mid, port->mid[port->num_mid]);
 	if (port->num_mid < 31)
 		port->num_mid++;
 
@@ -232,7 +320,7 @@ static void send_dhcp_discovery_cb(atimer_t *t)
 	 * uplink and take no action
 	 */
 
-	fprintf(stderr, "%s: sending dhcp discovery num:%d\n", __func__, port->dhcp_retries);
+	err("%s: sending dhcp discovery num:%d\n", __func__, port->dhcp_retries);
 
 	rc = controller_discovery_dhcp();
 	if (rc) {
@@ -245,44 +333,6 @@ static void send_dhcp_discovery_cb(atimer_t *t)
 }
 #endif
 
-
-/* check for eth uplink existence */
-static bool is_backhaul_type_eth(void)
-{
-	struct blob_buf bk = { 0 };
-	char *type;
-	struct blob_attr *tb[4];
-	static const struct blobmsg_policy bk_attr[4] = {
-		[0] = { .name = "type", .type = BLOBMSG_TYPE_STRING },
-		[1] = { .name = "macaddr", .type = BLOBMSG_TYPE_STRING },
-		[2] = { .name = "backhaul_device_id", .type = BLOBMSG_TYPE_TABLE },
-		[3] = { .name = "backhaul_device_macaddr", .type = BLOBMSG_TYPE_TABLE },
-	};
-
-	blob_buf_init(&bk, 0);
-
-	if (!blobmsg_add_json_from_file(&bk, MAP_UPLINK_PATH)) {
-		fprintf(stderr, "Failed to parse %s\n", MAP_UPLINK_PATH);
-		goto out;
-	}
-
-	blobmsg_parse(bk_attr, 4, tb, blob_data(bk.head), blob_len(bk.head));
-
-	if (!tb[0])
-		goto out;
-
-	type = blobmsg_data(tb[0]);
-
-	fprintf(stderr, "---- type = %s ------\n", type);
-
-	blob_buf_free(&bk);
-
-	return !strncmp(type, "eth", 4);
-out:
-	blob_buf_free(&bk);
-	return false;
-}
-
 void dynbh_handle_port_down(struct dynbh_ctx *priv, struct ethport *port)
 {
 	timer_del(&port->send_apconf);
@@ -332,7 +382,7 @@ void dynbh_handle_port_up(struct ethport *port)
 	timer_set(&port->bridge_add, (APCONF_MAX_RETRIES * APCONF_INTERVAL) * 1000);
 
 	/* remove iface from brdige */
-	delif(port);
+	delif(port->ctx, port);
 }
 
 struct ethport *alloc_ethport_search(struct dynbh_ctx *priv,
@@ -401,7 +451,7 @@ static void mapagent_event_handler(void *agent, struct blob_attr *msg)
 			      blobmsg_data(tb[1]), blobmsg_data_len(tb[1]));
 
 		if (!tb2[0] || !tb2[1]) {
-			fprintf(stderr, "|%s:%d| event parse error.\n", __func__, __LINE__);
+			err("|%s:%d| event parse error.\n", __func__, __LINE__);
 			return;
 		}
 
@@ -440,7 +490,7 @@ static void agent_event_handler(struct ubus_context *ctx,
 	if (!str)
 		return;
 
-	fprintf(stderr, "[ &agent = %p ] Received [event = %s]  [val = %s]\n",
+	err("[ &agent = %p ] Received [event = %s]  [val = %s]\n",
 			a, type, str);
 	for (i = 0; i < ARRAY_SIZE(evs); i++) {
 		if (!strcmp(type, evs[i].ev_type)) {
@@ -453,79 +503,17 @@ static void agent_event_handler(struct ubus_context *ctx,
 }
 #endif
 
-static char *agent_get_backhaul_ifname(char *ifname)
-{
-	struct blob_buf bk = { 0 };
-	struct blob_attr *tb[1];
-	static const struct blobmsg_policy bk_attr[1] = {
-		[0] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
-	};
-
-	blob_buf_init(&bk, 0);
-
-        if (!blobmsg_add_json_from_file(&bk, MAP_UPLINK_PATH)) {
-		fprintf(stderr, "Failed to parse %s\n", MAP_UPLINK_PATH);
-		goto out;
-        }
 
-	blobmsg_parse(bk_attr, 1, tb, blob_data(bk.head), blob_len(bk.head));
-
-	if (!tb[0])
-		goto out;
-
-	strncpy(ifname, blobmsg_data(tb[0]), 15);
-	ifname[15] = '\0';
-
-	blob_buf_free(&bk);
-	return ifname;
-out:
-	blob_buf_free(&bk);
-	return NULL;
-}
-
-static int handle_autoconfig_response(const char *ifname, uint8_t *src,
-				      uint8_t *from, uint16_t mid,
-				      struct cmdu_buff *rxdata, size_t rxlen,
-				      void *priv, void *cookie)
+int dbh_handle_autoconfig_response(struct dynbh_ctx *priv, char *ifname,
+				      uint16_t mid, struct tlv *tv[][TLV_MAXNUM])
 {
-	struct dynbh_ctx *p = (struct dynbh_ctx *) priv;
+	struct agent *a = container_of(priv, struct agent, priv);
 	char almac_str[18] = {0};
 	struct ethport *port;
-	struct tlv_policy a_policy[] = {
-		[0] = {
-			.type = TLV_TYPE_SUPPORTED_ROLE,
-			.present = TLV_PRESENT_ONE
-		},
-		[1] = {
-			.type = MAP_TLV_SUPPORTED_SERVICE,
-			.present = TLV_PRESENT_OPTIONAL_ONE
-		},
-		[2] = {
-			.type = MAP_TLV_MULTIAP_PROFILE,
-			.present = TLV_PRESENT_ONE
-		},
-		[3] = {
-			.type = TLV_TYPE_SUPPORTED_FREQ_BAND,
-			.present = TLV_PRESENT_ONE
-		}
-	};
-	struct tlv *tv[4][TLV_MAXNUM] = {0};
 	bool has_cntlr = false;
 	int timeout = HEARTBEAT_PROBE_TIMEOUT;
-	int ret;
-
-	fprintf(stderr, "mapclient: %s ===>\n", __func__);
-
-	ret = cmdu_parse_tlvs(rxdata, tv, a_policy, 4);
-	if (ret) {
-		fprintf(stderr, "%s: parse_tlv failed\n", __func__);
-		return -1;
-	}
 
-	if (!tv[0][0] || !tv[1][0] || !tv[2][0] || !tv[3][0]) {
-		fprintf(stderr, "malformed data %d %d %d %d\n", !!tv[0][0], !!tv[1][0], !!tv[2][0], !!tv[3][0]);
-		return -1;
-	}
+	err("mapclient: %s ===>\n", __func__);
 
 	if (tv[1][0]->data[0] > 0) {
 		int i;
@@ -539,36 +527,33 @@ static int handle_autoconfig_response(const char *ifname, uint8_t *src,
 		}
 	}
 	if (!has_cntlr) {
-		fprintf(stderr, "Response did not support controller!\n");
+		err("Response did not support controller!\n");
 		return -1;
 	}
 
 
-	port = ethport_by_mid(p, mid);
+	port = ethport_by_mid(priv, mid);
 	if (!port) {
-		fprintf(stderr, "No matching mid found\n");
+		err("No matching mid found\n");
 
-		port = ethport_by_ifname(p, ifname);
+		port = ethport_by_ifname(priv, ifname);
 		if (!port) {
-			fprintf(stderr, "No interface matching %s found - no action\n", ifname);
+			err("No interface matching %s found - no action\n", ifname);
 			return -1;
 		} else if (port->active_uplink || port->loop) {
-			fprintf(stderr, "Interface %s already known to be connected to a controller - no action\n", ifname);
+			err("Interface %s already known to be connected to a controller - no action\n", ifname);
 			goto out;
 		} else {
-			fprintf(stderr, "Interface %s is not known to have a controller\n", ifname);
+			err("Interface %s is not known to have a controller\n", ifname);
 		}
 	}
 
-	memcpy(port->backhaul_mac, src, 6);
-	memcpy(port->backhaul_device_id, from, 6);
-
-	if (!is_backhaul_type_eth()) {
+	if (!agent_is_backhaul_type_eth()) {
 		/* if there is no active eth backhaul use this link as backhaul */
 		port->active_uplink = true;
 		port->loop = false;
 		link_up(port);
-		fprintf(stderr, "|%s:%d| Interface %s is active uplink\n", __func__, __LINE__, port->ifname);
+		err("|%s:%d| Interface %s is active uplink\n", __func__, __LINE__, port->ifname);
 		addif(port);
 #ifdef PERSIST_CONTROLLER
 		if (port->ctx->discovery_mode == DYNAMIC_CNTLR_MODE_AUTO) {
@@ -580,23 +565,24 @@ static int handle_autoconfig_response(const char *ifname, uint8_t *src,
 	} else if (port->active_uplink) {
 		char ul_ifname[16] = {0};
 
-		if (agent_get_backhaul_ifname(ul_ifname)) {
+		if (agent_get_backhaul_ifname(a, ul_ifname)) {
 			if (strncmp(ul_ifname, port->ifname, 16))
 				link_up(port);
 		} else
 			link_up(port);
 
-		fprintf(stderr, "|%s:%d| Interface %s is already known as active uplink\n", __func__, __LINE__, port->ifname);
+		err("|%s:%d| Interface %s is already known as active uplink\n", __func__, __LINE__, port->ifname);
 		goto out;
 	}
 
-	fprintf(stderr, "|%s:%d| active controller (%s) found for iface:%s mid:%d, keep out of bridge\n",
+	err("|%s:%d| active controller (%s) found for iface:%s mid:%d, keep out of bridge\n",
 			__func__, __LINE__, almac_str, port->ifname, mid);
 
 	if (if_isbridge_interface(port->ifname))
-		runCmd("/lib/wifi/dynbhd/api bridge_delif %s", port->ifname);  /* add back to bridge */
+		bridge_delif(priv, port);
 
-	runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname);
+	//runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname);
+	i1905_delif(port->ctx, port);
 
 	port->loop = true;
 out:
@@ -608,57 +594,14 @@ out:
 	return 0;
 }
 
-static int handle_autoconfig_search(const char *ifname, uint8_t *src,
-				      uint8_t *from, uint16_t mid,
-				      struct cmdu_buff *rxdata, size_t rxlen,
-				      void *priv, void *cookie)
+int dbh_handle_autoconfig_search(struct dynbh_ctx *priv, char *ifname, uint16_t mid, struct tlv *tv[][TLV_MAXNUM])
 {
-	struct dynbh_ctx *p = (struct dynbh_ctx *) priv;
-	char almac_str[18] = {0};
+	struct agent *a = container_of(priv, struct agent, priv);
 	struct ethport *port;
-	struct tlv_policy a_policy[] = {
-		[0] = { .type = TLV_TYPE_AL_MAC_ADDRESS_TYPE,
-			.present = TLV_PRESENT_ONE,
-			.len = 6, /* macaddr */
-		},
-		[1] = { .type = TLV_TYPE_SEARCHED_ROLE,
-			.present = TLV_PRESENT_ONE,
-			.len = 1, /* tlv_searched_role */
-		},
-		[2] = { .type = TLV_TYPE_AUTOCONFIG_FREQ_BAND,
-			.present = TLV_PRESENT_ONE,
-			.len = 1, /* tlv_autoconfig_band */
-		},
-		[3] = { .type = MAP_TLV_SUPPORTED_SERVICE,
-			.present = TLV_PRESENT_OPTIONAL_ONE,
-			.minlen = 1, /* num of services */
-		},
-		[4] = { .type = MAP_TLV_SEARCHED_SERVICE,
-			.present = TLV_PRESENT_OPTIONAL_ONE,
-			.minlen = 1, /* num of services */
-		},
-		[5] = { .type = MAP_TLV_MULTIAP_PROFILE,
-			.present = TLV_PRESENT_ONE,
-			.len = 1, /* tlv_map_profile */
-		},
-	};
-	struct tlv *tv[6][TLV_MAXNUM] = {0};
 	bool has_cntlr = false;
 	int timeout = HEARTBEAT_PROBE_TIMEOUT;
-	int ret;
-
-	fprintf(stderr, "mapclient: %s ===>\n", __func__);
-
-	ret = cmdu_parse_tlvs(rxdata, tv, a_policy, 6);
-	if (ret) {
-		fprintf(stderr, "%s: parse_tlv failed\n", __func__);
-		return -1;
-	}
 
-	if (!tv[0][0] || !tv[1][0] || !tv[2][0] || !tv[5][0]) {
-		fprintf(stderr, "malformed data %d %d %d %d\n", !!tv[0][0], !!tv[1][0], !!tv[2][0], !!tv[3][0]);
-		return -1;
-	}
+	err("mapclient: %s ===>\n", __func__);
 
 	if (tv[3][0]->data[0] > 0) {
 		int i;
@@ -672,31 +615,29 @@ static int handle_autoconfig_search(const char *ifname, uint8_t *src,
 		}
 	}
 	if (!has_cntlr) {
-		fprintf(stderr, "Search did not support controller!\n");
+		err("Search did not support controller!\n");
 		return -1;
 	}
 
 
-	port = ethport_by_ifname(p, ifname);
+	port = ethport_by_ifname(priv, ifname);
 	if (!port) {
-		fprintf(stderr, "No interface matching %s found - no action\n", ifname);
+		err("No interface matching %s found - no action\n", ifname);
 		return -1;
 	} else if (port->active_uplink || port->loop) {
-		fprintf(stderr, "Interface %s already known to be connected to a controller - no action\n", ifname);
-		return -1;
+		err("Interface %s already known to be connected to a controller - no action\n", ifname);
+		goto out;
 	} else {
-		fprintf(stderr, "Interface %s is not known to have a controller\n", ifname);
+		err("Interface %s is not known to have a controller\n", ifname);
 	}
 
-	memcpy(port->backhaul_mac, src, 6);
-	memcpy(port->backhaul_device_id, from, 6);
 
-	if (!is_backhaul_type_eth()) {
+	if (!agent_is_backhaul_type_eth()) {
 		/* if there is no active eth backhaul use this link as backhaul */
 		port->active_uplink = true;
 		port->loop = false;
 		link_up(port);
-		fprintf(stderr, "|%s:%d| Interface %s is active uplink\n", __func__, __LINE__, port->ifname);
+		err("|%s:%d| Interface %s is active uplink\n", __func__, __LINE__, port->ifname);
 		addif(port);
 #ifdef PERSIST_CONTROLLER
 		if (port->ctx->discovery_mode == DYNAMIC_CNTLR_MODE_AUTO) {
@@ -708,23 +649,24 @@ static int handle_autoconfig_search(const char *ifname, uint8_t *src,
 	} else if (port->active_uplink) {
 		char ul_ifname[16] = {0};
 
-		if (agent_get_backhaul_ifname(ul_ifname)) {
+		if (agent_get_backhaul_ifname(a, ul_ifname)) {
 			if (strncmp(ul_ifname, port->ifname, 16))
 				link_up(port);
 		} else
 			link_up(port);
 
-		fprintf(stderr, "|%s:%d| Interface %s is already known as active uplink\n", __func__, __LINE__, port->ifname);
+		err("|%s:%d| Interface %s is already known as active uplink\n", __func__, __LINE__, port->ifname);
 		goto out;
 	}
 
-	fprintf(stderr, "|%s:%d| active controller (%s) found for iface:%s mid:%d, keep out of bridge\n",
-			__func__, __LINE__, almac_str, port->ifname, mid);
+	//err("|%s:%d| active controller (%s) found for iface:%s mid:%d, keep out of bridge\n",
+	//		__func__, __LINE__, almac_str, port->ifname, mid);
 
 	if (if_isbridge_interface(port->ifname))
-		runCmd("/lib/wifi/dynbhd/api bridge_delif %s", port->ifname);  /* add back to bridge */
+		bridge_delif(priv, port);
 
-	runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname);
+	//runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname);
+	i1905_delif(port->ctx, port);
 
 	port->loop = true;
 out:
@@ -736,211 +678,16 @@ out:
 	return 0;
 }
 
+#if 0
 static int handle_1905_ack(const char *ifname, uint8_t *src,
 			   uint8_t *from, uint16_t mid,
 			   struct cmdu_buff *rxdata, size_t rxlen, void *priv,
 			   void *cookie)
 {
-	fprintf(stderr, "mapclient: %s ===>\n", __func__);
+	err("mapclient: %s ===>\n", __func__);
 	return 0;
 }
-
-typedef int (*cmdu_handler_t)(const char *ifname, uint8_t *src, uint8_t *from,
-			      uint16_t mid, struct cmdu_buff *rxdata,
-			      size_t rxlen, void *priv, void *cookie);
-
-
-static const cmdu_handler_t i1905ftable[] = {
-	[0x00] = NULL,
-	[0x01] = NULL,
-	[0x02] = NULL,
-	[0x03] = NULL,
-	[0x04] = NULL,
-	[0x05] = NULL,
-	[0x06] = NULL,
-	[0x07] = handle_autoconfig_search,
-	[0x08] = handle_autoconfig_response,
-	[0x09] = NULL,
-	[0x0a] = NULL,
-};
-
-#define CMDU_TYPE_MAP_START	0x8000
-#define CMDU_TYPE_MAP_END	0x8001
-
-static const cmdu_handler_t mapclient_ftable[] = {
-	[0x00] = handle_1905_ack,
-};
-
-
-static int mapclient_handle_cmdu_notification(struct blob_attr *msg, struct dynbh_ctx *priv)
-{
-	static const struct blobmsg_policy cmdu_attrs[6] = {
-		[0] = { .name = "type", .type = BLOBMSG_TYPE_INT16 },
-		[1] = { .name = "mid", .type = BLOBMSG_TYPE_INT16 },
-		[2] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
-		[3] = { .name = "source", .type = BLOBMSG_TYPE_STRING },
-		[4] = { .name = "origin", .type = BLOBMSG_TYPE_STRING },
-		[5] = { .name = "cmdu", .type = BLOBMSG_TYPE_STRING },
-	};
-	char in_ifname[16] = {0};
-	struct blob_attr *tb[6];
-	char src[18] = { 0 }, src_origin[18] = { 0 };
-	uint8_t *tlv = NULL;
-	char *tlvstr = NULL;
-	uint16_t type;
-	uint8_t srcmac[6], origin[6];
-	uint16_t mid = 0;
-	int len = 0;
-	struct cmdu_buff *cmdu;
-	int ret = 0;
-	int idx;
-	const cmdu_handler_t *f;
-
-	blobmsg_parse(cmdu_attrs, 6, tb, blob_data(msg), blob_len(msg));
-
-	if (!tb[0] || !tb[1])
-		return -1;
-
-	if (tb[0]) {
-		int t;
-
-		t = blobmsg_get_u16(tb[0]);
-		if (t < 0)
-			return -1;
-
-		type = (uint16_t)t;
-	}
-
-	if (tb[1])
-		mid = (uint16_t)blobmsg_get_u16(tb[1]);
-
-
-	if (tb[2])
-		strncpy(in_ifname, blobmsg_data(tb[2]), 15);
-
-	if (tb[3]) {
-		strncpy(src, blobmsg_data(tb[3]), 17);
-		hwaddr_aton(src, srcmac);
-	}
-
-	if (tb[4]) {
-		strncpy(src_origin, blobmsg_data(tb[4]), 17);
-		hwaddr_aton(src_origin, origin);
-	}
-
-
-	if (tb[5]) {
-		len = blobmsg_data_len(tb[5]) - 16;
-
-		tlvstr = calloc(1, len + 1);
-
-		if (!tlvstr)
-			return -1;
-
-		strncpy(tlvstr, (blobmsg_data(tb[5]) + 16), len);
-		len = (len - 1) / 2;
-		tlv = calloc(1, len);
-		if (!tlv) {
-			free(tlvstr);
-			return -1;
-		}
-
-		strtob(tlvstr, len, tlv);
-		free(tlvstr);
-	}
-
-	cmdu = cmdu_alloc_custom(type, &mid, in_ifname, srcmac, tlv, len);
-	if (!cmdu) {
-		fprintf(stderr, "%s: cmdu_alloc_custom() failed!\n", __func__);
-		if (tlv)
-			free(tlv);
-		return -1;
-	}
-	memcpy(cmdu->origin, origin, 6);
-	fprintf(stderr, "%s: cmdu_alloc_custom() succeeded! cmdu->cdata->hdr.mid %u\n", __func__, cmdu_get_mid(cmdu));
-
-
-	if (type >= CMDU_TYPE_MAP_START) {
-		idx = type - CMDU_TYPE_MAP_START;
-		f = mapclient_ftable;
-		if (ARRAY_SIZE(mapclient_ftable) < idx)
-			goto error;
-	} else {
-		idx = type;
-		f = i1905ftable;
-		if (ARRAY_SIZE(i1905ftable) < idx)
-			goto error;
-	}
-
-	if (f[idx]) {
-		ret = f[idx](in_ifname, srcmac, origin, mid, cmdu, len, priv, NULL);
-	}
-
-
-
-error:
-	if (tlv)
-		free(tlv);
-	cmdu_free(cmdu);
-	return ret;
-}
-
-int dynbh_map_sub_cb(void *bus, void *priv, void *data)
-{
-	struct blob_attr *msg = (struct blob_attr *)data;
-	char *str;
-
-
-	str = blobmsg_format_json(msg, true);
-	fprintf(stderr, "Received notification '%s'\n", str);
-	free(str);
-
-	mapclient_handle_cmdu_notification(msg, priv);
-
-	return 0;
-}
-
-int dynbh_map_del_cb(void *bus, void *priv, void *data)
-{
-	uint32_t *obj = (uint32_t *)data;
-
-	fprintf(stderr, "Object 0x%x no longer present\n", *obj);
-	return 0;
-}
-
-static int dynbh_subscribe_for_cmdus(struct dynbh_ctx *priv)
-{
-	mapmodule_cmdu_mask_t cmdu_mask = {0};
-	int ret;
-	uint32_t map_id;
-
-
-	map_prepare_cmdu_mask(cmdu_mask,
-			      CMDU_TYPE_AP_AUTOCONFIGURATION_SEARCH,
-			      CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE,
-			      -1);
-
-	ret = ubus_lookup_id(priv->ctx, map_plugin, &map_id);
-	if (ret) {
-		fprintf(stderr, "%s: %s\n", map_plugin, ubus_strerror(ret));
-		return -1;
-	}
-
-	priv->map_oid = map_id;
-	ret = map_subscribe(priv->ctx,
-			    &priv->map_oid,
-			    "dynbhd", &cmdu_mask, priv,
-			    dynbh_map_sub_cb,
-			    dynbh_map_del_cb,
-			    &priv->subscriber);
-	if (ret) {
-		fprintf(stderr, "dynbh: Failed to 'register' with %s (err = %s)\n",
-			map_plugin, ubus_strerror(ret));
-	}
-
-	return ret;
-}
-
+#endif
 void remove_newline(char *buf)
 {
         int len;
@@ -984,7 +731,6 @@ static int dynbhd_status(struct ubus_context *ctx, struct ubus_object *obj,
 }
 
 
-
 int cntlr_publish_object(struct dynbh_ctx *c, const char *objname)
 {
 	struct ubus_object *obj;
@@ -1019,20 +765,21 @@ int cntlr_publish_object(struct dynbh_ctx *c, const char *objname)
 	obj_type->methods = obj->methods;
 	obj->type = obj_type;
 
-	ret = ubus_add_object(c->ctx, obj);
+	ret = ubus_add_object(c->ubus_ctx, obj);
 	if (ret) {
-		fprintf(stderr, "Failed to add '%s' err = %s\n",
+		err("Failed to add '%s' err = %s\n",
 				objname, ubus_strerror(ret));
 		free(obj_methods);
 		free(obj_type);
 		return ret;
 	}
 
-	fprintf(stderr, "Published '%s' object\n", objname);
+	err("Published '%s' object\n", objname);
 
 	return 0;
 }
 
+#if 0
 int main(int argc, char **argv)
 {
 	const char *ubus_socket = NULL;
@@ -1063,7 +810,7 @@ int main(int argc, char **argv)
 	uloop_init();
 	priv->ctx = ubus_connect(ubus_socket);
 	if (!priv->ctx) {
-		fprintf(stderr, "Failed to connect to ubus\n");
+		err("Failed to connect to ubus\n");
 		free(priv);
 		return -1;
 	}
@@ -1100,3 +847,5 @@ int main(int argc, char **argv)
 
 	return 0;
 }
+#endif
+#endif
diff --git a/src/dynbh/dynbh.h b/src/dynbh/dynbh.h
index 68b14ed12459d9e12435cc36ea956e113c3b14b2..1d381aaa598d43a6868d4d87b8e622941ae50db4 100644
--- a/src/dynbh/dynbh.h
+++ b/src/dynbh/dynbh.h
@@ -1,8 +1,10 @@
+#ifdef DYNBH
 #ifndef DYNBH_H
 #define DYNBH_H
 
 #include <libubox/list.h>
 #include <libubus.h>
+#include <cmdu.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <timer_impl.h>
@@ -19,12 +21,11 @@ enum cntlr_discovery_mode {
 
 
 struct ethport {
+	char ifname[16];
+	uint8_t macaddr[6];
 	bool connected;
 	bool loop;
 	bool active_uplink;
-	char ifname[16];
-	uint8_t backhaul_mac[6];
-	uint8_t backhaul_device_id[6];
 	uint8_t num_mid;
 	uint16_t mid[32];
 	atimer_t bridge_add;
@@ -37,14 +38,9 @@ struct ethport {
 };
 
 struct dynbh_ctx {
-	char alidstr[16]; /* 6 octet macaddr without separators */
+	uint8_t almac[6];
 	char al_bridge[16];
-	uint16_t cmdu_mask;
-	struct ubus_context *ctx;
-	uint32_t oid;
-	uint32_t map_oid;
-	void *subscriber;
-	struct ubus_event_handler evh;
+	struct ubus_context *ubus_ctx;
 	int queued_searches;
 	struct list_head ethportlist; /*  */
 	atimer_t heartbeat;
@@ -55,10 +51,11 @@ struct dynbh_ctx {
 
 };
 
-void delif(struct ethport *port);
+void delif(struct dynbh_ctx *priv, struct ethport *port);
 void addif(struct ethport *port);
 
-
+struct ethport *alloc_ethport_search(struct dynbh_ctx *priv,
+		char *ifname);
 struct ethport *ethport_by_ifname(struct dynbh_ctx *p,
 		const char *ifname);
 struct ethport *ethport_by_mid(struct dynbh_ctx *p, uint16_t mid);
@@ -68,4 +65,9 @@ void dynbh_handle_port_down(struct dynbh_ctx *priv, struct ethport *port);
 
 void free_ethport_search(struct ethport *port);
 
+int dbh_handle_autoconfig_response(struct dynbh_ctx *priv, char *ifname,
+				      uint16_t mid, struct tlv *tv[][TLV_MAXNUM]);
+int dbh_handle_autoconfig_search(struct dynbh_ctx *priv, char *ifname, uint16_t mid, struct tlv *tv[][TLV_MAXNUM]);
+
+#endif
 #endif
diff --git a/src/nl.h b/src/nl.h
index 800b5dc1785ac18132e3ca4d0c091d80db36fdf3..92568327b334e64305d31908333ab46cce13524f 100644
--- a/src/nl.h
+++ b/src/nl.h
@@ -8,7 +8,6 @@
 #include <easy/utils.h>
 #include <easy/if_utils.h>
 #include <linux/if_bridge.h>
-#include <net/if.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <wifidefs.h>
@@ -17,7 +16,7 @@ struct agent;
 struct nl_sock;
 
 struct ts_iface {
-	char name[IFNAMSIZ];
+	char name[16];
 	uint16_t vid;
 	int ifi_index;
 	struct bridge_vlan_info cur_vinfo[MAX_VIDS];
diff --git a/src/utils/1905_ubus.c b/src/utils/1905_ubus.c
index 31604b597762ff35ef1b82aeb17b60e6b49e2850..e3b6d70739e4a564ee3338dcfe13a5a965d23b69 100644
--- a/src/utils/1905_ubus.c
+++ b/src/utils/1905_ubus.c
@@ -231,9 +231,9 @@ out:
 	return -1;
 }
 
-int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx,
-			    struct cmdu_buff *cmdu, uint16_t *msgid,
-			    uint16_t vid)
+static int ieee1905_send_cmdu(struct ubus_context *ubus_ctx,
+			       struct cmdu_buff *cmdu, char *objname,
+			       uint16_t *msgid, uint16_t vid)
 {
 	struct blob_buf bb = {};
 	char dst_addr[18] = {};
@@ -244,7 +244,7 @@ int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx,
 	};
 	int ret = 0;
 
-	ret = ubus_lookup_id(ubus_ctx, "ieee1905", &id);
+	ret = ubus_lookup_id(ubus_ctx, objname, &id);
 	if (ret != UBUS_STATUS_OK)
 		return -1;
 
@@ -264,7 +264,7 @@ int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx,
 	if (vid)
 		blobmsg_add_u32(&bb, "vid", (uint32_t)vid);
 
-	trace("|%s:%d|cmdu:0x%04x|dst:%s|mid:%u|datalen:%u|ifname:%s|vid:%u\n",
+	err("|%s:%d|cmdu:0x%04x|dst:%s|mid:%u|datalen:%u|ifname:%s|vid:%u\n",
 	      __func__, __LINE__, cmdu_get_type(cmdu), dst_addr,
 	      cmdu_get_mid(cmdu), cmdu->datalen, cmdu->dev_ifname, vid);
 	if (cmdu->datalen) {
@@ -283,7 +283,7 @@ int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx,
 		tlv_str[len-1] = '\0';
 
 		blobmsg_add_string(&bb, "data", tlv_str);
-		trace("|%s:%d|data:%s|\n", __func__, __LINE__, tlv_str);
+		err("|%s:%d|data:%s|\n", __func__, __LINE__, tlv_str);
 		free(tlv_str);
 	}
 
@@ -294,20 +294,38 @@ int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx,
 		ret = ctx.status;
 
 	if (ret) {
-		trace("[%s:%d] ubus call failed for |ieee1905 send| rc: %d\n",
+		err("[%s:%d] ubus call failed for |ieee1905 send| rc: %d\n",
 					__func__, __LINE__, ret);
 		goto out;
 	}
 
 	*msgid = ctx.mid;
-	trace("|%s:%d| msgid = %d\n", __func__, __LINE__, *msgid);
+	err("|%s:%d| msgid = %d\n", __func__, __LINE__, *msgid);
 
 out:
 	blob_buf_free(&bb);
-	trace("%s ret %d\n", __func__, ret);
+	err("%s ret %d\n", __func__, ret);
 	return ret;
 }
 
+/* send CMDU using an ieee1905.al.X object */
+int ieee1905_ubus_send_al_cmdu(struct ubus_context *ubus_ctx,
+			       struct cmdu_buff *cmdu, uint16_t *msgid,
+			       char *ifname, uint16_t vid)
+{
+	char objname[32] = {0};
+
+	snprintf(objname, 31, "ieee1905.al.%s", ifname);
+	return ieee1905_send_cmdu(ubus_ctx, cmdu, objname, msgid, vid);
+}
+
+int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx,
+			    struct cmdu_buff *cmdu, uint16_t *msgid,
+			    uint16_t vid)
+{
+	return ieee1905_send_cmdu(ubus_ctx, cmdu, "ieee1905", msgid, vid);
+}
+
 int ieee1905_ubus_set_vid(struct ubus_context *ubus_ctx,
 					uint16_t vid)
 {
diff --git a/src/utils/1905_ubus.h b/src/utils/1905_ubus.h
index 885432ac5a94d91e20f941bf783b59122e50519f..a2ae1ff28e5b8d60693c9e7acaecdfe2772ca857 100644
--- a/src/utils/1905_ubus.h
+++ b/src/utils/1905_ubus.h
@@ -16,6 +16,9 @@ struct ubus_context;
 struct cmdu_buff *ieee1905_ubus_buildcmdu(struct ubus_context *ubus_ctx,
 			  uint16_t msg_type, char *ifname);
 int ieee1905_ubus_send_frag_scheme(struct ubus_context *ubus_ctx, uint8_t *origin, int frag_scheme);
+int ieee1905_ubus_send_al_cmdu(struct ubus_context *ubus_ctx,
+			       struct cmdu_buff *cmdu, uint16_t *msgid,
+			       char *ifname, uint16_t vid);
 int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx,
 			    struct cmdu_buff *cmdu, uint16_t *msgid,
 			    uint16_t vid);