diff --git a/src/Makefile b/src/Makefile
index 9daac83e83af9a1b91c817a547b32eeebbd4bfb5..f7288672c04ace4413b750cb0c58c132a38971f0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -21,6 +21,7 @@ CNTLR_OBJS = \
 	core/cntlr.o \
 	core/cntlr_map.o \
 	core/cntlr_tlv_generator.o \
+	core/cntlr_cmdu_generator.o \
 	core/cntlr_map_debug.o \
 	core/config.o \
 	core/main.o
diff --git a/src/controller.conf b/src/controller.conf
index 155015341ad4ec0d74afbb3a170e99d1c59f5d41..69ec214de9cdfbf8260a1cd0272a9631c8a03aca 100644
--- a/src/controller.conf
+++ b/src/controller.conf
@@ -1,4 +1,4 @@
-config wificntlr
+config controller controller
 	option enabled '1'
 	option registrar '5 2'	    #bands on which wps registrar supported
 	option debug '6'
@@ -10,12 +10,24 @@ config fh-credentials
 	option ssid 'map-net5'
 	option vlan '101'
 
+config vlan 'lan'
+	option network 'lan'
+	option id '1'
+	option proto 'dhcp'
+
+config vlan 'guest'
+	option network 'guest'
+	option id '2'
+	option proto 'static'
+	option ip_address '10.0.1.1'
+
 config fh-credentials
 	option band '2'
 	option encryption 'psk2'
 	option key '1234567890'
 	option ssid 'map-net2'
-	option vlan '0'               # 0 - 2 rsvd, 3 - 4094 => vlan id
+	option vlan_id '2'               # 0 - 2 rsvd, 3 - 4094 => vlan id
+	#option vlan 'lan'
 
 config bk-credentials
 	option band '5'
diff --git a/src/core/cntlr.h b/src/core/cntlr.h
index a66bd2f97bf8f7962ab0ee79b1082784f8acbbdb..65ba7f17c4627767c2c91e88e318461282a1e7ee 100644
--- a/src/core/cntlr.h
+++ b/src/core/cntlr.h
@@ -63,6 +63,7 @@ enum nodetype {
 	NODE_ETH_EXTENDER,
 };
 
+
 enum uplink_type {
 	UL_UNSPEC,
 	UL_ETH,
diff --git a/src/core/cntlr_cmdu_generator.c b/src/core/cntlr_cmdu_generator.c
new file mode 100644
index 0000000000000000000000000000000000000000..6750ce8f8cfecd1bc3bfd9df5c5cf3fa11f2c16e
--- /dev/null
+++ b/src/core/cntlr_cmdu_generator.c
@@ -0,0 +1,204 @@
+/*
+ * agent_tlv_generator.c - tlv building function
+ *
+ * Copyright (C) 2020 IOPSYS Software Solutions AB. All rights reserved.
+ *
+ * Author: jakob.olsson@iopsys.eu
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <net/if_arp.h>
+#include <pthread.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <json-c/json.h>
+#include <libubox/blobmsg.h>
+#include <libubox/blobmsg_json.h>
+#include <libubox/uloop.h>
+#include <libubox/ustream.h>
+#include <libubox/utils.h>
+#include <libubus.h>
+
+#include <map1905/map2.h>
+#include <map1905/maputils.h>
+#include <wsc.h>
+
+#include <uci.h>
+
+#include <easy/easy.h>
+#include <wifi.h>
+
+#include "map_module.h"
+#include "utils.h"
+#include "debug.h"
+#include "liblist.h"
+#include "config.h"
+#include "comm.h"
+#include "msgqueue.h"
+#include "worker.h"
+#include "cntlr.h"
+#include "cntlr_tlv_generator.h"
+#include "cntlr_cmdu_generator.h"
+
+static void cmdu_defaults(struct cmdu_cstruct *cmdu, uint8_t *origin,
+		char *intf_name, uint16_t type)
+{
+	memcpy(cmdu->origin, origin, 6);
+	if (intf_name)
+		strncpy(cmdu->intf_name, intf_name,
+				sizeof(cmdu->intf_name) - 1);
+	else
+		strncpy(cmdu->intf_name, "br-lan", sizeof(cmdu->intf_name) - 1);
+
+	cmdu->message_type = type;
+}
+
+struct cmdu_cstruct *cntlr_gen_ap_autoconfig_renew(struct controller *c,
+		uint8_t *origin, char *intf_name, uint8_t *almac)
+{
+	struct cmdu_cstruct *cmdu;
+	struct tlv_al_mac *p;
+	struct tlv_supported_freq_band *p1;
+	struct tlv_supported_role *p2;
+	int tlv_index = 0;
+
+	cmdu = (struct cmdu_cstruct *)calloc(1,	sizeof(struct cmdu_cstruct));
+	if (!cmdu) {
+		fprintf(stderr, "failed to malloc cmdu\n");
+		return NULL;
+	}
+
+	cmdu_defaults(cmdu, origin, intf_name,
+			CMDU_TYPE_AP_AUTOCONFIGURATION_RENEW);
+
+	p = cntlr_gen_al_mac(c, almac);
+	if (!p)
+		goto fail_cmdu;
+	cmdu->num_tlvs++;
+
+	/* Hard-code dummy 5GHz, ignored by agent according to spec */
+	p1 = cntlr_gen_supported_freq_band(c, 0x01);
+	if (!p1)
+		goto fail_p;
+	cmdu->num_tlvs++;
+
+	/* Hard-code dummy registrar role, only valid value */
+	p2 = cntlr_gen_supported_role(c, 0x00);
+	if (!p2)
+		goto fail_p1;
+	cmdu->num_tlvs++;
+
+	cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs, sizeof(uint8_t *));
+	if (!cmdu->tlvs)
+		goto fail_p2;
+	cmdu->tlvs[tlv_index++] = (uint8_t *)p;
+	cmdu->tlvs[tlv_index++] = (uint8_t *)p1;
+	cmdu->tlvs[tlv_index++] = (uint8_t *)p2;
+
+	return cmdu;
+fail_p2:
+	map_free_tlv_cstruct((uint8_t *) p2);
+fail_p1:
+	map_free_tlv_cstruct((uint8_t *) p1);
+fail_p:
+	map_free_tlv_cstruct((uint8_t *) p);
+fail_cmdu:
+	map_free_cmdu(cmdu);
+	return NULL;
+}
+
+struct cmdu_cstruct *cntlr_gen_ap_capability_query(struct controller *c,
+		uint8_t *origin, char *intf_name)
+{
+	struct cmdu_cstruct *cmdu;
+
+	cmdu = (struct cmdu_cstruct *)calloc(1,	sizeof(struct cmdu_cstruct));
+	if (!cmdu) {
+		fprintf(stderr, "failed to malloc cmdu\n");
+		return NULL;
+	}
+
+	cmdu_defaults(cmdu, origin, intf_name, CMDU_AP_CAPABILITY_QUERY);
+
+	return cmdu;
+}
+
+struct cmdu_cstruct *cntlr_gen_client_capability_query(struct controller *c,
+		uint8_t *origin, char *intf_name, uint8_t *sta, uint8_t *bssid)
+{
+	struct tlv_client_info *p;
+	struct cmdu_cstruct *cmdu;
+
+	cmdu = (struct cmdu_cstruct *)calloc(1,
+			sizeof(struct cmdu_cstruct));
+	if (!cmdu) {
+		fprintf(stderr, "failed to malloc cmdu\n");
+		return NULL;
+	}
+
+	cmdu_defaults(cmdu, origin, intf_name, CMDU_CLIENT_CAPABILITY_QUERY);
+
+	p = cntlr_gen_client_info(c, sta, bssid);
+	if (!p)
+		goto fail_cmdu;
+
+	cmdu->num_tlvs = 1;
+	cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs,
+			sizeof(uint8_t *));
+
+	if (!cmdu->tlvs)
+		goto fail_p;
+
+	cmdu->tlvs[0] = (uint8_t *)p;
+
+	return cmdu;
+fail_p:
+	map_free_tlv_cstruct((uint8_t *) p);
+fail_cmdu:
+	map_free_cmdu(cmdu);
+	return NULL;
+}
+
+struct cmdu_cstruct *cntlr_gen_backhaul_steer_request(struct controller *c,
+		uint8_t *origin, char *intf_name, uint8_t *bssid,
+		uint8_t *bkhaul, uint8_t op_class, uint8_t channel)
+{
+	struct tlv_backhaul_steer_req *p;
+	struct cmdu_cstruct *cmdu;
+
+	cmdu = (struct cmdu_cstruct *)calloc(1,
+			sizeof(struct cmdu_cstruct));
+	if (!cmdu) {
+		fprintf(stderr, "failed to malloc cmdu\n");
+		return NULL;
+	}
+
+	cmdu_defaults(cmdu, origin, intf_name, CMDU_BACKHAUL_STEER_REQUEST);
+
+	p = cntlr_gen_backhaul_steer_req(c, bkhaul, bssid, op_class, channel);
+	if (!p)
+		goto fail_cmdu;
+
+	cmdu->num_tlvs = 1;
+	cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs,
+			sizeof(uint8_t *));
+
+	if (!cmdu->tlvs)
+		goto fail_p;
+
+	cmdu->tlvs[0] = (uint8_t *)p;
+
+	return cmdu;
+fail_p:
+	map_free_tlv_cstruct((uint8_t *) p);
+fail_cmdu:
+	map_free_cmdu(cmdu);
+	return NULL;
+}
diff --git a/src/core/cntlr_cmdu_generator.h b/src/core/cntlr_cmdu_generator.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b478b9942f6c9d779944d26d45dba959d9e1220
--- /dev/null
+++ b/src/core/cntlr_cmdu_generator.h
@@ -0,0 +1,22 @@
+/*
+ * agent_tlv_generator.h - tlv building function declarations
+ *
+ * Copyright (C) 2020 IOPSYS Software Solutions AB. All rights reserved.
+ *
+ * Author: jakob.olsson@iopsys.eu
+ *
+ */
+
+#ifndef CNTLR_CMDU_GEN_H
+#define CNTLR_CMDU_GEN_H
+
+struct cmdu_cstruct *cntlr_gen_ap_autoconfig_renew(struct controller *c,
+		uint8_t *origin, char *intf_name, uint8_t *almac);
+struct cmdu_cstruct *cntlr_gen_ap_capability_query(struct controller *c,
+		uint8_t *origin, char *intf_name);
+struct cmdu_cstruct *cntlr_gen_client_capability_query(struct controller *c,
+		uint8_t *origin, char *intf_name, uint8_t *sta, uint8_t *bssid);
+struct cmdu_cstruct *cntlr_gen_backhaul_steer_request(struct controller *c,
+		uint8_t *origin, char *intf_name, uint8_t *bssid,
+		uint8_t *bkhaul, uint8_t op_class, uint8_t channel);
+#endif
diff --git a/src/core/cntlr_map.c b/src/core/cntlr_map.c
index 9feb715e583dd5259f6b21ac42b4ccd260d56d56..d8f850d0d42c448eafec625e13fe6bd96180f787 100644
--- a/src/core/cntlr_map.c
+++ b/src/core/cntlr_map.c
@@ -79,7 +79,6 @@ int handle_topology_response(void *cntlr, struct cmdu_cstruct *cmdu)
 	return 0;
 }
 
-/* TODO: error handling */
 int handle_ap_autoconfig_search(void *cntlr, struct cmdu_cstruct *rec_cmdu)
 {
 	trace("%s: --->\n", __func__);
@@ -88,8 +87,36 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_cstruct *rec_cmdu)
 	struct cmdu_cstruct *cmdu;
 	struct tlv_map_profile *p;
 	struct tlv_supp_service *p1;
+	struct tlv_supported_freq_band *p2;
+	struct tlv_al_mac *almac_tlv;
+	struct tlv_autoconf_freq_band *freq_tlv;
+	char mac_str[18] = {0};
 	int ret;
 
+	almac_tlv = extract_tlv_by_type(rec_cmdu, TLV_TYPE_AL_MAC_ADDRESS_TYPE);
+	if (!almac_tlv)
+		return -1;
+
+	freq_tlv = extract_tlv_by_type(rec_cmdu, TLV_TYPE_AUTOCONFIG_FREQ_BAND);
+	if (!freq_tlv)
+		return -1;
+
+	if (freq_tlv->freq_band == 0x00) {
+		if (!c->cfg.has_registrar_2g)
+			return -1;
+	} else if (freq_tlv->freq_band == 0x01) {
+		if (!c->cfg.has_registrar_5g)
+			return -1;
+	} else
+		return -1;
+
+	if (!hwaddr_ntoa(almac_tlv->al_mac_address, mac_str))
+		return -1;
+
+	ret = cntlr_config_add_agent(&c->cfg, mac_str);
+	if (!ret)
+		cntlr_config_reload(&c->cfg);
+
 	cmdu = (struct cmdu_cstruct *)calloc(1,
 			sizeof(struct cmdu_cstruct));
 	if (!cmdu) {
@@ -99,7 +126,7 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_cstruct *rec_cmdu)
 
 	cmdu->message_type = CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE;
 	memcpy(cmdu->origin, rec_cmdu->origin, 6);
-	cmdu->message_id = cmdu->message_id;
+	cmdu->message_id = rec_cmdu->message_id;
 	strncpy(cmdu->intf_name, rec_cmdu->intf_name,
 			sizeof(cmdu->intf_name) - 1);
 
@@ -113,17 +140,25 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_cstruct *rec_cmdu)
 		goto fail_p;
 	cmdu->num_tlvs++;
 
+	p2 = cntlr_gen_supported_freq_band(c, freq_tlv->freq_band);
+	if (!p2)
+		goto fail_p1;
+	cmdu->num_tlvs++;
+
 	cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs,	sizeof(uint8_t *));
 	if (!cmdu->tlvs)
-		goto fail_p1;
+		goto fail_p2;
 
 	cmdu->tlvs[tlv_index++] = (uint8_t *)p;
 	cmdu->tlvs[tlv_index++] = (uint8_t *)p1;
+	cmdu->tlvs[tlv_index++] = (uint8_t *)p2;
 
 	ret = send_cmdu(c, cmdu);
 	map_free_cmdu(cmdu);
 
 	return ret;
+fail_p2:
+	map_free_tlv_cstruct((uint8_t *) p2);
 fail_p1:
 	map_free_tlv_cstruct((uint8_t *) p1);
 fail_p:
@@ -147,6 +182,7 @@ int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_cstruct *rec_cmdu)
 	struct tlv_default_8021q_settings *p;
 	struct tlv_traffic_sep_policy *p1;
 	struct tlv_ap_radio_identifier *p2;
+	struct tlv_ap_radio_basic_cap *rec_basic_cap;
 	struct tlv_wsc *p3;
 	struct cmdu_cstruct *cmdu;
 	int tlv_index = 0, ret, i;
@@ -184,7 +220,12 @@ int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_cstruct *rec_cmdu)
 		goto fail_p;
 	cmdu->num_tlvs++;
 
-	p2 = cntlr_gen_radio_identifier(c, cmdu, rec_cmdu);
+	rec_basic_cap = extract_tlv_by_type(rec_cmdu,
+			MAP_TLV_AP_RADIO_BASIC_CAPABILITIES);
+	if (!rec_basic_cap)
+		goto fail_p1;
+
+	p2 = cntlr_gen_ap_radio_identifier(c, cmdu, rec_basic_cap->radio_id);
 	if (!p2)
 		goto fail_p1;
 	cmdu->num_tlvs++;
diff --git a/src/core/cntlr_tlv_generator.c b/src/core/cntlr_tlv_generator.c
index 558492cb22693b4682a4bd3dfd6c6ab9d393a786..72df47432ec3b8a17520079176ef1468a0ac1cd2 100644
--- a/src/core/cntlr_tlv_generator.c
+++ b/src/core/cntlr_tlv_generator.c
@@ -158,12 +158,15 @@ struct tlv_wsc *cntlr_gen_wsc(struct controller *c,
 	else /* default to WPA */
 		cfg.input.auth_types = 0x0008;
 
-	/* backhaul STA */
-	cfg.input.mapie |= (creds->mode == WIFI_MODE_STA ? 1 << 7 : 0);
+	/* backhaul STA - DEPRECATED
+	 * cfg.input.mapie |= (creds->mode == WIFI_MODE_STA ? 1 << 7 : 0);
+	 */
 	/* backhaul BSS */
 	cfg.input.mapie |= (creds->multi_ap & 0x01) << 6;
+	cfg.input.mapie |= (creds->mode == AP_WIFI_BBSS ? (1 << 6) : 0);
 	/* fronthaul BSS */
 	cfg.input.mapie |= (creds->multi_ap & 0x02) << 4;
+	cfg.input.mapie |= (creds->mode == AP_WIFI_FBSS ? (1 << 5) : 0);
 	/* backhaul STA */
 	cfg.input.mapie |= (creds->disallow_bsta << 2);
 	/* teardown bit */
@@ -181,33 +184,22 @@ struct tlv_wsc *cntlr_gen_wsc(struct controller *c,
 	return m2;
 }
 
-struct tlv_ap_radio_identifier *cntlr_gen_radio_identifier(struct controller *c,
-		struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu)
+
+struct tlv_ap_radio_identifier *cntlr_gen_ap_radio_identifier(struct controller *c,
+		struct cmdu_cstruct *cmdu, uint8_t *hwaddr)
 {
 	struct tlv_ap_radio_identifier *p;
-	uint8_t *tlv;
-	int i;
 
-	p = (struct tlv_ap_radio_identifier *) calloc(1,
+	p = (struct tlv_ap_radio_identifier *)calloc(1,
 			sizeof(struct tlv_ap_radio_identifier));
-	if (!p)
+	if (!p) {
+		fprintf(stderr, "failed to malloc tlv\n");
 		return NULL;
-
-	for (i = 0; i < rec_cmdu->num_tlvs; i++) {
-		tlv = (uint8_t *) rec_cmdu->tlvs[i];
-		switch (*tlv) {
-		case MAP_TLV_AP_RADIO_BASIC_CAPABILITIES: {
-			struct tlv_ap_radio_basic_cap *rec_p = (struct tlv_ap_radio_basic_cap *)tlv;
-
-			p->tlv_type = MAP_TLV_AP_RADIO_IDENTIFIER;
-			memcpy(p->radio_id, rec_p->radio_id, 6);
-			break;
-		}
-		default:
-			break;
-		}
 	}
 
+	p->tlv_type = MAP_TLV_AP_RADIO_IDENTIFIER;
+	memcpy(p->radio_id, hwaddr, 6);
+
 	return p;
 }
 
@@ -267,6 +259,20 @@ struct tlv_ch_scan_rep_policy *cntlr_gen_ch_scan_rep_policy(
 	return p;
 }
 
+struct tlv_al_mac *cntlr_gen_al_mac(struct controller *c, uint8_t *hwaddr)
+{
+	struct tlv_al_mac *p;
+
+	p = calloc(1, sizeof(struct tlv_al_mac));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = TLV_TYPE_AL_MAC_ADDRESS_TYPE;
+	memcpy(p->al_mac_address, hwaddr, 6);
+
+	return p;
+}
+
 struct tlv_unsuccess_assoc_policy *cntlr_gen_unsuccess_assoc_policy(
 		struct controller *c, struct agent_policy *a,
 		struct cmdu_cstruct *cmdu)
@@ -284,6 +290,21 @@ struct tlv_unsuccess_assoc_policy *cntlr_gen_unsuccess_assoc_policy(
 	return p;
 }
 
+struct tlv_supported_freq_band *cntlr_gen_supported_freq_band(struct controller *c,
+		uint8_t freq_band)
+{
+	struct tlv_supported_freq_band *p;
+
+	p = calloc(1, sizeof(struct tlv_supported_freq_band));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = TLV_TYPE_SUPPORTED_FREQ_BAND;
+	p->freq_band = freq_band;
+
+	return p;
+}
+
 struct tlv_backhaul_bss_config *cntlr_gen_backhaul_bss_config(
 		struct controller *c, struct agent_policy *a,
 		struct cmdu_cstruct *cmdu, const uint8_t *bssid)
@@ -409,3 +430,53 @@ struct tlv_metric_report_policy *cntlr_gen_metric_report_policy(
 
 	return p;
 }
+
+struct tlv_supported_role *cntlr_gen_supported_role(struct controller *c,
+		uint8_t role)
+{
+	struct tlv_supported_role *p;
+
+	p = calloc(1, sizeof(struct tlv_supported_role));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = TLV_TYPE_SUPPORTED_ROLE;
+	p->role = role;
+
+	return p;
+}
+
+struct tlv_client_info *cntlr_gen_client_info(struct controller *c,
+		uint8_t *sta, uint8_t *bssid)
+{
+	struct tlv_client_info *p;
+
+	p = calloc(1, sizeof(struct tlv_client_info));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_CLIENT_INFO;
+	memcpy(p->bssid, bssid, 6);
+	memcpy(p->client_addr, sta, 6);
+
+	return p;
+}
+
+struct tlv_backhaul_steer_req *cntlr_gen_backhaul_steer_req(struct controller *c,
+		uint8_t *bssid, uint8_t *bkhaul, uint8_t op_class,
+		uint8_t channel)
+{
+	struct tlv_backhaul_steer_req *p;
+
+	p = calloc(1, sizeof(struct tlv_backhaul_steer_req));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_BACKHAUL_STEERING_REQUEST;
+	memcpy(p->bssid, bssid, 6);
+	memcpy(p->addr, bkhaul, 6);
+
+	p->channel = channel;
+	p->op_class = op_class;
+	return p;
+}
diff --git a/src/core/cntlr_tlv_generator.h b/src/core/cntlr_tlv_generator.h
index d409c49100525f51d4ded99e75125654dd011ab0..74adb4f98a713331f0cf2db65dd27d67d43c6dad 100644
--- a/src/core/cntlr_tlv_generator.h
+++ b/src/core/cntlr_tlv_generator.h
@@ -10,6 +10,7 @@
 #ifndef CNTLR_TLV_GEN_H
 #define CNTLR_TLV_GEN_H
 
+uint8_t *extract_tlv_by_type(struct cmdu_cstruct *cmdu, uint8_t tlv_type);
 struct tlv_default_8021q_settings *cntlr_gen_8021q_settings(struct controller *c,
 		struct agent_policy *a);
 struct tlv_traffic_sep_policy *cntlr_gen_traffic_sep_policy(struct controller *c,
@@ -17,8 +18,8 @@ struct tlv_traffic_sep_policy *cntlr_gen_traffic_sep_policy(struct controller *c
 struct tlv_wsc *cntlr_gen_wsc(struct controller *c,
 		struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu,
 		struct iface_credential *fh);
-struct tlv_ap_radio_identifier *cntlr_gen_radio_identifier(struct controller *c,
-		struct cmdu_cstruct *cmdu, struct cmdu_cstruct *rec_cmdu);
+struct tlv_ap_radio_identifier *cntlr_gen_ap_radio_identifier(struct controller *c,
+		struct cmdu_cstruct *cmdu, uint8_t *hwaddr);
 struct tlv_supp_service *cntlr_gen_supp_service(struct controller *c,
 		struct cmdu_cstruct *cmdu);
 struct tlv_map_profile *cntlr_gen_map_profile(struct controller *c,
@@ -37,4 +38,14 @@ struct tlv_unsuccess_assoc_policy *cntlr_gen_unsuccess_assoc_policy(
 struct tlv_backhaul_bss_config *cntlr_gen_backhaul_bss_config(
 		struct controller *c, struct agent_policy *a,
 		struct cmdu_cstruct *cmdu, const uint8_t *bssid);
+struct tlv_al_mac *cntlr_gen_al_mac(struct controller *c, uint8_t *hwaddr);
+struct tlv_supported_freq_band *cntlr_gen_supported_freq_band(struct controller *c,
+		uint8_t freq_band);
+struct tlv_supported_role *cntlr_gen_supported_role(struct controller *c,
+		uint8_t role);
+struct tlv_client_info *cntlr_gen_client_info(struct controller *c,
+		uint8_t *sta, uint8_t *bssid);
+struct tlv_backhaul_steer_req *cntlr_gen_backhaul_steer_req(struct controller *c,
+		uint8_t *bssid, uint8_t *bkhaul, uint8_t op_class,
+		uint8_t channel);
 #endif
diff --git a/src/core/cntlr_ubus.c b/src/core/cntlr_ubus.c
index ed10aaa93f767e47c8bb1af954b44bd277407ce4..bc383006588ca63e19c75edcf08d08fe2b85dc69 100644
--- a/src/core/cntlr_ubus.c
+++ b/src/core/cntlr_ubus.c
@@ -34,6 +34,9 @@
 #include "cntlr_tlv_generator.h"
 
 #include "map_module.h"
+#include "cntlr_tlv_generator.h"
+#include "cntlr_cmdu_generator.h"
+
 
 enum {
 	AP_POLICY_AGENT,
@@ -105,11 +108,15 @@ static const struct blobmsg_policy config_policy_params[__CFG_POLICY_MAX] = {
 
 enum {
 	RECFG_POLICY_AGENT,
+	RECFG_POLICY_ALMAC,
+	RECFG_POLICY_EGRESS,
 	__RECFG_POLICY_MAX,
 };
 
 static const struct blobmsg_policy reconfig_policy_params[__RECFG_POLICY_MAX] = {
 	[RECFG_POLICY_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING },
+	[RECFG_POLICY_ALMAC] = { .name = "almac", .type = BLOBMSG_TYPE_STRING },
+	[RECFG_POLICY_EGRESS] = { .name = "egress", .type = BLOBMSG_TYPE_STRING }
 };
 
 enum {
@@ -198,14 +205,16 @@ int send_cmdu(struct controller *c,
 
 	blobmsg_add_u32(&b, "type", cmdu_data->message_type);
 	blobmsg_add_string(&b, "egress", cmdu_data->intf_name);
-	blobmsg_add_u32(&b, "mid", cmdu_data->message_id);
+	if (cmdu_data->message_id)
+		blobmsg_add_u32(&b, "mid", cmdu_data->message_id);
 
 	hwaddr_ntoa(cmdu_data->origin, dst_addr);
 	blobmsg_add_string(&b, "dst_macaddr", dst_addr);
 
-	fprintf(stdout, "|%s:%d|cmdu:%s|dst:%s|num_tlvs:%d|\n", __func__, __LINE__,
+	fprintf(stdout, "|%s:%d|cmdu:%s|dst:%s|num_tlvs:%d|egress:%s|\n",
+			__func__, __LINE__,
 			map_stringify_cmdu_type(cmdu_data->message_type),
-			dst_addr, cmdu_data->num_tlvs);
+			dst_addr, cmdu_data->num_tlvs, cmdu_data->intf_name);
 
 	if (cmdu_data->num_tlvs > 0) {
 		for (i = 0; i < cmdu_data->num_tlvs; i++) {
@@ -356,37 +365,28 @@ int cntlr_ap_caps(struct ubus_context *ctx, struct ubus_object *obj,
 {
 	struct blob_attr *tb[__AP_POLICY_MAX];
 	struct controller *c = container_of(obj, struct controller, obj);
-	char agent[18] = {0};
-	struct cmdu_cstruct *cmdu_data;
-
-	cmdu_data = (struct cmdu_cstruct *)calloc(1,
-			sizeof(struct cmdu_cstruct));
-	if (!cmdu_data) {
-		fprintf(stderr, "failed to malloc cmdu\n");
-		return UBUS_STATUS_UNKNOWN_ERROR;
-	}
+	uint8_t hwaddr[6] = {0};
+	struct cmdu_cstruct *cmdu;
 
 	blobmsg_parse(ap_caps_policy_params, __AP_POLICY_MAX, tb,
 			blob_data(msg), blob_len(msg));
 
-
 	if (tb[AP_POLICY_AGENT]) {
+		char agent[18] = {0};
+
 		strncpy(agent, blobmsg_data(tb[AP_POLICY_AGENT]),
 				sizeof(agent) - 1);
-		if (!hwaddr_aton(agent, cmdu_data->origin))
+		if (!hwaddr_aton(agent, hwaddr))
 			return UBUS_STATUS_UNKNOWN_ERROR;
 	}
 
-	// TODO: ff:ff:ff:ff:ff:ff = send to all agents
-
-	cmdu_data->message_type = CMDU_AP_CAPABILITY_QUERY;
-	cmdu_data->message_id = 1;
-
-	cmdu_data->num_tlvs = 0;
 
-	send_cmdu(c, cmdu_data);
+	cmdu = cntlr_gen_ap_capability_query(c, hwaddr, NULL);
+	if (!cmdu)
+		return UBUS_STATUS_UNKNOWN_ERROR;
 
-	map_free_cmdu(cmdu_data);
+	send_cmdu(c, cmdu);
+	map_free_cmdu(cmdu);
 
 	return 0;
 }
@@ -577,15 +577,14 @@ fail_cmdu:
 }
 
 static int cntlr_sta_caps(struct ubus_context *ctx, struct ubus_object *obj,
-			struct ubus_request_data *req, const char *method,
-			struct blob_attr *msg)
+		struct ubus_request_data *req, const char *method,
+		struct blob_attr *msg)
 {
 	struct blob_attr *tb[__STA_POLICY_MAX];
-	uint8_t hw_bssid[6] = {0}, hw_sta[6] = {0};
-	struct tlv_client_info *p;
+	uint8_t hw_bssid[6] = {0}, hw_sta[6] = {0}, hw_agent[6] = {0};
 	struct controller *c = container_of(obj, struct controller, obj);
-	char sta[18] = {0}, agent[18] = {0}, bssid[18] = {0};
-	struct cmdu_cstruct *cmdu_data;
+	char sta[18] = {0}, bssid[18] = {0};
+	struct cmdu_cstruct *cmdu;
 
 	blobmsg_parse(sta_caps_policy_params, __STA_POLICY_MAX, tb,
 			blob_data(msg), blob_len(msg));
@@ -599,62 +598,29 @@ static int cntlr_sta_caps(struct ubus_context *ctx, struct ubus_object *obj,
 	strncpy(sta, blobmsg_data(tb[STA_POLICY_STA]), sizeof(sta) - 1);
 	strncpy(bssid, blobmsg_data(tb[STA_POLICY_BSSID]), sizeof(bssid) - 1);
 
-	cmdu_data = (struct cmdu_cstruct *)calloc(1,
-			sizeof(struct cmdu_cstruct));
-	if (!cmdu_data) {
-		fprintf(stderr, "failed to malloc cmdu\n");
-		return UBUS_STATUS_UNKNOWN_ERROR;
-	}
-
 	if (tb[AP_POLICY_AGENT]) {
+		char agent[18] = {0};
+
 		strncpy(agent, blobmsg_data(tb[AP_POLICY_AGENT]),
 				sizeof(agent) - 1);
-		if (!hwaddr_aton(agent, cmdu_data->origin))
-			goto fail_cmdu;
-	}
-
-	// TODO: ff:ff:ff:ff:ff:ff = send to all agents
-
-	cmdu_data->message_type = CMDU_CLIENT_CAPABILITY_QUERY;
-	cmdu_data->message_id = 1;
-
-	p = calloc(1, sizeof(struct tlv_client_info));
-	if (!p) {
-		fprintf(stderr, "failed to malloc cmdu\n");
-		goto fail_cmdu;
-	}
-
-	if (!hwaddr_aton(sta, hw_sta)) {
-		fprintf(stderr, "STA Capability Query: provide STA " \
-				"address in format 11:22:33...\n");
-		goto fail_p;
-	}
-
-	if (!hwaddr_aton(bssid, hw_bssid)) {
-		fprintf(stderr, "STA Capability Query: provide BSSID " \
-				"address in format 11:22:33...\n");
-		goto fail_p;
+		if (!hwaddr_aton(agent, hw_agent))
+			return UBUS_STATUS_UNKNOWN_ERROR;
 	}
 
-	p->tlv_type = MAP_TLV_CLIENT_INFO;
-	memcpy(p->bssid, hw_bssid, 6);
-	memcpy(p->client_addr, hw_sta, 6);
+	if (!hwaddr_aton(sta, hw_sta))
+		return UBUS_STATUS_UNKNOWN_ERROR;
 
-	cmdu_data->num_tlvs = 1;
-	cmdu_data->tlvs = (uint8_t **)calloc(cmdu_data->num_tlvs,
-			sizeof(uint8_t *));
+	if (!hwaddr_aton(sta, hw_bssid))
+		return UBUS_STATUS_UNKNOWN_ERROR;
 
-	if (cmdu_data->tlvs)
-		cmdu_data->tlvs[0] = (uint8_t *)p;
+	cmdu = cntlr_gen_client_capability_query(c, hw_agent, NULL, hw_sta,
+			hw_bssid);
+	if (!cmdu)
+		return UBUS_STATUS_UNKNOWN_ERROR;
 
-	send_cmdu(c, cmdu_data);
-	map_free_cmdu(cmdu_data);
+	send_cmdu(c, cmdu);
+	map_free_cmdu(cmdu);
 	return 0;
-fail_p:
-	map_free_tlv_cstruct((uint8_t *) p);
-fail_cmdu:
-	map_free_cmdu(cmdu_data);
-	return UBUS_STATUS_UNKNOWN_ERROR;
 }
 
 static int cntlr_teardown_ap(struct ubus_context *ctx, struct ubus_object *obj,
@@ -668,33 +634,49 @@ static int cntlr_reconfig_ap(struct ubus_context *ctx, struct ubus_object *obj,
 			struct ubus_request_data *req, const char *method,
 			struct blob_attr *msg)
 {
-	return 0;
-}
 
+	struct controller *c = container_of(obj, struct controller, obj);
+	struct blob_attr *tb[__RECFG_POLICY_MAX];
+	char almac[18] = {0}, egress[16] = {0};
+	uint8_t hwaddr[6] = {0}, alhwaddr[6] = {0};
+	struct cmdu_cstruct *cmdu;
+	int i, tlv_index = 0;
+
+	blobmsg_parse(reconfig_policy_params, __RECFG_POLICY_MAX, tb,
+			blob_data(msg), blob_len(msg));
 
-/*
- * - One AP Radio Identifier TLV (see section 17.2.3).
- * - One or more WSC TLV (containing M2).
- * - Zero or one Default 802.1Q Settings TLV (see section 17.2.49). [Profile-2]
- * - Zero or one Traffic Separation Policy TLV (see section 17.2.50). [Profile-2]
-*/
-
-struct tlv_ap_radio_identifier *cntlr_gen_config_ap_tlv(struct controller *c,
-		struct cmdu_cstruct *cmdu, uint8_t *hwaddr)
-{
-	struct tlv_ap_radio_identifier *p;
+	if (!tb[RECFG_POLICY_ALMAC]) {
+		fprintf(stderr, "Provide ALMAC address in format 11:22:33...\n");
+		return UBUS_STATUS_INVALID_ARGUMENT;
+	}
 
-	p = (struct tlv_ap_radio_identifier *)calloc(1,
-			sizeof(struct tlv_ap_radio_identifier));
-	if (!p) {
-		fprintf(stderr, "failed to malloc tlv\n");
-		return NULL;
+	if (tb[RECFG_POLICY_AGENT]) {
+		char agent[18] = {0};
+
+		strncpy(agent, blobmsg_data(tb[RECFG_POLICY_AGENT]),
+				sizeof(agent) - 1);
+		if (!hwaddr_aton(agent, hwaddr))
+			return UBUS_STATUS_UNKNOWN_ERROR;
 	}
 
-	p->tlv_type = MAP_TLV_AP_RADIO_IDENTIFIER;
-	memcpy(p->radio_id, hwaddr, 6);
+	if (tb[RECFG_POLICY_EGRESS])
+		strncpy(egress, blobmsg_data(tb[RECFG_POLICY_EGRESS]),
+				sizeof(egress) - 1);
+	else
+		strncpy(egress, "br-lan", sizeof(egress) - 1);
+
+	strncpy(almac, blobmsg_data(tb[RECFG_POLICY_ALMAC]),
+			sizeof(almac) - 1);
+	if (!hwaddr_aton(almac, alhwaddr))
+		return UBUS_STATUS_UNKNOWN_ERROR;
+
+	cmdu = cntlr_gen_ap_autoconfig_renew(c, alhwaddr, egress, alhwaddr);
+	if (!cmdu)
+		return UBUS_STATUS_UNKNOWN_ERROR;
 
-	return p;
+	send_cmdu(c, cmdu);
+	map_free_cmdu(cmdu);
+	return UBUS_STATUS_OK;
 }
 
 static struct netif_radio *cntlr_radio_to_bssid(struct controller *c, const char *radio)
@@ -768,7 +750,7 @@ static int cntlr_config_ap(struct ubus_context *ctx, struct ubus_object *obj,
 			free(cmdu);
 			return UBUS_STATUS_UNKNOWN_ERROR;
 		}
-		p = cntlr_gen_config_ap_tlv(c, cmdu, hwaddr);
+		p = cntlr_gen_ap_radio_identifier(c, cmdu, hwaddr);
 	} else if (tb[CFG_POLICY_RADIO]) {
 		char radio[18] = {0};
 		struct netif_radio *r;
@@ -781,7 +763,7 @@ static int cntlr_config_ap(struct ubus_context *ctx, struct ubus_object *obj,
 			return UBUS_STATUS_UNKNOWN_ERROR;
 		}
 
-		p = cntlr_gen_config_ap_tlv(c, cmdu, r->hwaddr);
+		p = cntlr_gen_ap_radio_identifier(c, cmdu, r->hwaddr);
 	}
 	/*
 	else { // TODO: all radios
@@ -870,10 +852,11 @@ static int cntlr_bk_steer(struct ubus_context *ctx, struct ubus_object *obj,
 			struct blob_attr *msg)
 {
 	struct blob_attr *tb[__BK_STEER_POLICY_MAX];
-	struct tlv_backhaul_steer_req *p;
 	struct controller *c = container_of(obj, struct controller, obj);
-	char agent[18] = {0}, bssid[18] = {0}, bkhaul[18] = {0};
+	char agent_str[18] = {0}, bssid_str[18] = {0}, bkhaul_str[18] = {0};
+	uint8_t agent[6] = {0}, bssid[6] = {0}, bkhaul[6] = {0};
 	struct cmdu_cstruct *cmdu;
+	uint8_t op_class, channel;
 
 	blobmsg_parse(bk_steer_policy_params, __BK_STEER_POLICY_MAX, tb,
 			blob_data(msg), blob_len(msg));
@@ -885,64 +868,40 @@ static int cntlr_bk_steer(struct ubus_context *ctx, struct ubus_object *obj,
 		return UBUS_STATUS_INVALID_ARGUMENT;
 	}
 
-	strncpy(bssid, blobmsg_data(tb[BK_STEER_POLICY_BSSID]),
-			sizeof(bssid) - 1);
-	strncpy(bkhaul, blobmsg_data(tb[BK_STEER_POLICY_STA_MAC]),
-			sizeof(bkhaul) - 1);
+	strncpy(bssid_str, blobmsg_data(tb[BK_STEER_POLICY_BSSID]),
+			sizeof(bssid_str) - 1);
+	strncpy(bkhaul_str, blobmsg_data(tb[BK_STEER_POLICY_STA_MAC]),
+			sizeof(bkhaul_str) - 1);
 
-	cmdu = (struct cmdu_cstruct *)calloc(1,
-			sizeof(struct cmdu_cstruct));
-	if (!cmdu) {
-		fprintf(stderr, "failed to malloc cmdu\n");
-		return UBUS_STATUS_UNKNOWN_ERROR;
-	}
-
-	if (tb[AP_POLICY_AGENT]) {
-		strncpy(agent, blobmsg_data(tb[AP_POLICY_AGENT]),
-				sizeof(agent) - 1);
-		if (!hwaddr_aton(agent, cmdu->origin))
-			goto fail_cmdu;
-	}
-
-	cmdu->message_type = CMDU_BACKHAUL_STEER_REQUEST;
-
-	p = calloc(1, sizeof(struct tlv_client_info));
-	if (!p) {
-		fprintf(stderr, "failed to malloc cmdu\n");
-		goto fail_cmdu;
-	}
-
-	cmdu->num_tlvs++;
-
-	if (!hwaddr_aton(bssid, p->bssid)) {
+	if (!hwaddr_aton(bssid_str, bssid)) {
 		fprintf(stderr, "BSSID must be in format 11:22:33...\n");
-		goto fail_p;
+		return UBUS_STATUS_INVALID_ARGUMENT;
 	}
 
-	if (!hwaddr_aton(bkhaul, p->addr)) {
+	if (!hwaddr_aton(bkhaul_str, bkhaul)) {
 		fprintf(stderr, "Backhaul must be in format 11:22:33...\n");
-		goto fail_p;
+		return UBUS_STATUS_INVALID_ARGUMENT;
 	}
 
-	p->channel = blobmsg_get_u8(tb[BK_STEER_POLICY_CHANNEL]);
-	p->op_class = blobmsg_get_u8(tb[BK_STEER_POLICY_OP_CLASS]);
-	p->tlv_type = MAP_TLV_BACKHAUL_STEERING_REQUEST;
+	if (tb[AP_POLICY_AGENT]) {
+		strncpy(agent_str, blobmsg_data(tb[AP_POLICY_AGENT]),
+				sizeof(agent_str) - 1);
+		if (!hwaddr_aton(agent_str, agent))
+			return UBUS_STATUS_INVALID_ARGUMENT;
+	}
 
-	cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs,
-			sizeof(uint8_t *));
+	channel = blobmsg_get_u8(tb[BK_STEER_POLICY_CHANNEL]);
+	op_class = blobmsg_get_u8(tb[BK_STEER_POLICY_OP_CLASS]);
 
-	if (cmdu->tlvs)
-		cmdu->tlvs[0] = (uint8_t *)p;
+	cmdu = cntlr_gen_backhaul_steer_request(c, agent, NULL, bssid, bkhaul,
+			op_class, channel);
+	if (!cmdu)
+		return UBUS_STATUS_UNKNOWN_ERROR;
 
 	send_cmdu(c, cmdu);
 	map_free_cmdu(cmdu);
 
 	return 0;
-fail_p:
-	map_free_tlv_cstruct((uint8_t *) p);
-fail_cmdu:
-	free(cmdu);
-	return UBUS_STATUS_UNKNOWN_ERROR;
 }
 
 static int cntlr_ap_policy_config(struct ubus_context *ctx, struct ubus_object *obj,
@@ -1147,20 +1106,24 @@ int cntlr_publish_object(struct controller *c, const char *objname)
 	struct ubus_object *obj;
 	struct ubus_object_type *obj_type;
 	struct ubus_method *obj_methods;
-	struct ubus_method m[7] = {
+	struct ubus_method m[8] = {
 		UBUS_METHOD_NOARG("status", cntlr_status),
-		UBUS_METHOD("ap_caps", cntlr_ap_caps, ap_caps_policy_params),
-		UBUS_METHOD("sta_caps", cntlr_sta_caps, sta_caps_policy_params),
+		UBUS_METHOD("ap_caps", cntlr_ap_caps,
+				ap_caps_policy_params),
+		UBUS_METHOD("sta_caps", cntlr_sta_caps,
+				sta_caps_policy_params),
 		UBUS_METHOD("channels", cntlr_channel_pref,
 				channel_pref_policy_params),
 		UBUS_METHOD("bk_steer", cntlr_bk_steer, bk_steer_policy_params),
-		UBUS_METHOD("agent_policy", cntlr_ap_policy_config, ap_policy_config_params),
-		UBUS_METHOD("channel", cntlr_channel_select, channel_select_policy_params)
+		UBUS_METHOD("agent_policy", cntlr_ap_policy_config,
+				ap_policy_config_params),
+		UBUS_METHOD("channel", cntlr_channel_select,
+				channel_select_policy_params),
+		UBUS_METHOD("reconfig_ap", cntlr_reconfig_ap,
+				reconfig_policy_params),
 		/*
 		UBUS_METHOD("teardown_ap", cntlr_teardown_ap,
 				config_policy_params),
-		UBUS_METHOD("reconfig_ap", cntlr_reconfig_ap,
-				reconfig_policy_params),
 		UBUS_METHOD("config_ap", cntlr_config_ap, config_policy_params),
 		*/
 
diff --git a/src/core/config.c b/src/core/config.c
index 08db6bd444fa3cc5ed94910688aedd04dc976129..95446f9ad886f4470ecdad21fb6902b9b09b1210 100644
--- a/src/core/config.c
+++ b/src/core/config.c
@@ -52,6 +52,97 @@ static void stax_add_entry(struct list_head *h, char *sta_macstr)
 	}
 }
 
+struct uci_package *uci_load_pkg(struct uci_context **ctx, const char *config)
+{
+	struct uci_package *pkg;
+
+	if (!*ctx) {
+		*ctx = uci_alloc_context();
+		if (!*ctx)
+			return NULL;
+	}
+	if (uci_load(*ctx, config, &pkg) != UCI_OK) {
+		free(*ctx);
+		return NULL;
+	}
+
+	return pkg;
+}
+
+int set_value(struct uci_context *ctx, struct uci_package *pkg,
+		struct uci_section *section, const char *key,
+		const char *value, enum uci_option_type type)
+{
+	struct uci_ptr ptr = {0};
+
+	ptr.p = pkg;
+	ptr.s = section;
+	ptr.option = key;
+	ptr.value = value;
+
+	if (type == UCI_TYPE_STRING)
+		return uci_set(ctx, &ptr);
+
+	if (type == UCI_TYPE_LIST)
+		return uci_add_list(ctx, &ptr);
+
+	return -1;
+}
+
+struct uci_section *config_get_agent_section(struct uci_context *ctx,
+		struct uci_package *pkg, const char *type, const char *al_mac)
+{
+	struct uci_element *e;
+	struct uci_section *section;
+
+	uci_foreach_element(&pkg->sections, e) {
+		const char *agent_id;
+
+		section = uci_to_section(e);
+		if (strcmp(section->type, type))
+			continue;
+
+		agent_id = uci_lookup_option_string(ctx, section, "agent_id");
+		if (agent_id && !strcmp(agent_id, al_mac))
+			return section;
+	}
+
+	return NULL;
+}
+
+int cntlr_config_add_agent(struct controller_config *c, char *al_mac)
+{
+	struct uci_context *ctx = NULL;
+	struct uci_package *pkg;
+	struct uci_section *section;
+	int ret = -1;
+
+	pkg = uci_load_pkg(&ctx, "mapcontroller");
+	if (!pkg)
+		return ret;
+
+	section = config_get_agent_section(ctx, pkg, "agent-policy", al_mac);
+	if (section)
+		goto out_pkg;
+
+	ret = uci_add_section(ctx, pkg, "agent-policy", &section);
+	if (ret)
+		goto out_pkg;
+
+	ret = uci_save(ctx, pkg);
+	if (ret)
+		goto out_pkg;
+
+	ret = set_value(ctx, pkg, section, "agent_id", al_mac, UCI_TYPE_STRING);
+
+	uci_commit(ctx, &pkg, false);
+
+out_pkg:
+	uci_unload(ctx, pkg);
+	uci_free_context(ctx);
+	return ret;
+}
+
 void cntlr_config_dump(struct controller_config *c)
 {
 	int i;
@@ -195,13 +286,13 @@ static int cntlr_config_get_credentials(struct controller_config *c,
 			return -1;
 
 		cred = &c->fh[c->num_fh++];
-		cred->mode = WIFI_MODE_AP;
+		cred->mode = AP_WIFI_FBSS;
 	} else {
 		if (c->num_bk >= 2)
 			return -1;
 
 		cred = &c->bk[c->num_bk++];
-		cred->mode = WIFI_MODE_STA;
+		cred->mode = AP_WIFI_BBSS;
 	}
 
 	uci_parse_section(s, opts, NUM_CREDS, tb);
@@ -411,7 +502,7 @@ int cntlr_config_reload(struct controller_config *cfg)
 	if (!ctx)
 		return -1;
 
-	if (uci_load(ctx, "controller", &pkg)) {
+	if (uci_load(ctx, "mapcontroller", &pkg)) {
 		uci_free_context(ctx);
 		return -1;
 	}
@@ -419,7 +510,7 @@ int cntlr_config_reload(struct controller_config *cfg)
 	uci_foreach_element(&pkg->sections, e) {
 		struct uci_section *s = uci_to_section(e);
 
-		if (!strcmp(s->type, "wificntlr")) {
+		if (!strcmp(s->type, "controller")) {
 			cntlr_config_get_base(cfg, s);
 		} else if (!strcmp(s->type, "fh-credentials") ||
 				!strcmp(s->type, "bk-credentials")) {
diff --git a/src/core/config.h b/src/core/config.h
index b4aa7029df296c613821ebc07aeb7f3bc3328cc6..fea14869367217218facabfbaaab494a9bbb5efe 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -37,6 +37,11 @@ enum wifi_security {
 };
 */
 
+enum aptype {
+	AP_WIFI_FBSS,
+	AP_WIFI_BBSS,
+};
+
 struct stax {
 	char macstring[32];     /* ':' separated mac address string */
 	struct list_head list;
@@ -51,7 +56,7 @@ struct iface_credential {
 	uint16_t vlanid;
 	uint8_t multi_ap;
 	struct list_head *list;
-	enum wifi_mode mode;
+	enum aptype mode;
 	uint8_t disallow_bsta;
 };
 
@@ -103,6 +108,8 @@ struct controller_config {
 
 struct controller;
 
+int cntlr_config_add_agent(struct controller_config *c, char *al_mac);
+
 int cntlr_config_reload(struct controller_config *cfg);
 int cntlr_config_defaults(struct controller *c, struct controller_config *cfg);
 void cntlr_config_dump(struct controller_config *cfg);