diff --git a/src/controller.conf b/src/controller.conf
index 1cb46cfb8c0af03c1d6c4ab8e82b9d0277652059..e34cb611d0acd13770af031c34d48c64c22f62b5 100644
--- a/src/controller.conf
+++ b/src/controller.conf
@@ -48,6 +48,7 @@ config agent-policy
 	option rcpi_threshold '30'                 # 0 - 220 valid range
 	option report_scan '0'                     # 0 or 1 for independent scans
 	option report_sta_assocfails '1'           # 0 or 1 - stas assoc failure
+	option report_sta_assocfails_rate '2'      # reporting rate for STA assoc fails (attempts per minute)
 	option report_metric_periodic '0'          # 0, or 1 - 255 in secs
 	option report_rcpi_threshold '0'           # 0, or 1 - 220
 	option report_util_threshold '0'           # 0, or  channel-util value
@@ -67,6 +68,7 @@ config agent-policy
 	option rcpi_threshold '30'                 # 0 - 220 valid range
 	option report_scan '0'                     # 0 or 1 for independent scans
 	option report_sta_assocfails '1'           # 0 or 1 - stas assoc failure
+	option report_sta_assocfails_rate '2'      # reporting rate for STA assoc fails (attempts per minute)
 	option report_metric_periodic '0'          # 0, or 1 - 255 in secs
 	option report_rcpi_threshold '0'           # 0, or 1 - 220
 	option report_util_threshold '0'           # 0, or  channel-util value
diff --git a/src/core/cntlr_tlv_generator.c b/src/core/cntlr_tlv_generator.c
index 7d6cfab0e79f0ee835e0a2296c3ef3da6e7ca9d8..f5a9f9f64c8f5e67b70f4af9dd80f2694c6f347e 100644
--- a/src/core/cntlr_tlv_generator.c
+++ b/src/core/cntlr_tlv_generator.c
@@ -261,3 +261,161 @@ struct tlv_map_profile *cntlr_gen_map_profile(struct controller *c,
 
 	return p;
 }
+
+struct tlv_ch_scan_rep_policy *cntlr_gen_ch_scan_rep_policy(
+		struct controller *c, struct agent_policy *a,
+		struct cmdu_cstruct *cmdu)
+{
+	struct tlv_ch_scan_rep_policy *p;
+
+	p = calloc(1, sizeof(struct tlv_ch_scan_rep_policy));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_CHANNEL_SCAN_REPORTING_POLICY;
+	p->ch_scans = a->report_scan;
+
+	return p;
+}
+
+struct tlv_unsuccess_assoc_policy *cntlr_gen_unsuccess_assoc_policy(
+		struct controller *c, struct agent_policy *a,
+		struct cmdu_cstruct *cmdu)
+{
+	struct tlv_unsuccess_assoc_policy *p;
+
+	p = calloc(1, sizeof(struct tlv_unsuccess_assoc_policy));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_UNSUCCESS_ASSOCIATION_POLICY;
+	p->report = a->report_sta_assocfails;
+	p->max_reporting_rate = a->report_sta_assocfails_rate;
+
+	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)
+{
+	struct tlv_backhaul_bss_config *p;
+
+	p = calloc(1, sizeof(struct tlv_backhaul_bss_config));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_BACKHAUL_BSS_CONFIG;
+	memcpy(p->bssid, bssid, 6);
+	p->p1 = a->disallow_bsta_p1;
+	p->p2 = a->disallow_bsta_p2;
+
+	return p;
+}
+
+struct tlv_steering_policy *cntlr_gen_steering_policy(
+		struct controller *c, struct agent_policy *a,
+		struct cmdu_cstruct *cmdu, int num_radio, uint8_t *radiolist)
+{
+	int i = 0, index;
+	struct tlv_steering_policy *p;
+	struct stax *x;
+	uint8_t sta_mac[6] = {0};
+
+	p = calloc(1, sizeof(struct tlv_steering_policy));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_STEERING_POLICY;
+
+	p->local_disallowed_sta_nr = 0;
+	list_for_each_entry(x, &a->steer_exlist, list) {
+		p->local_disallowed_sta_nr++;
+		index = p->local_disallowed_sta_nr - 1;
+		p->local_disallowed_sta_macs = realloc(p->local_disallowed_sta_macs,
+				p->local_disallowed_sta_nr * sizeof(*p->local_disallowed_sta_macs));
+		if (!p->local_disallowed_sta_macs)
+			goto fail_alloc;
+
+		hwaddr_aton(x->macstring, sta_mac);
+		memcpy(p->local_disallowed_sta_macs[index].addr, sta_mac, 6);
+	}
+
+	p->btm_disallowed_sta_nr = 0;
+	list_for_each_entry(x, &a->btmsteer_exlist, list) {
+		p->btm_disallowed_sta_nr++;
+		index = p->btm_disallowed_sta_nr - 1;
+		p->btm_disallowed_sta_macs = realloc(p->local_disallowed_sta_macs,
+				p->btm_disallowed_sta_nr * sizeof(*p->local_disallowed_sta_macs));
+		if (!p->btm_disallowed_sta_macs)
+			goto fail_alloc;
+
+		hwaddr_aton(x->macstring, sta_mac);
+		memcpy(p->local_disallowed_sta_macs[index].addr, sta_mac, 6);
+	}
+
+	p->control_policy_radio_nr = num_radio;
+	p->control_policy = calloc(p->control_policy_radio_nr,
+			sizeof(*p->control_policy));
+	if (!p->control_policy)
+		goto fail_alloc;
+
+	for (i = 0; i < p->control_policy_radio_nr; i++) {
+		memcpy(p->control_policy[i].radio_id, &radiolist[i*6], 6);
+		p->control_policy[i].steering_policy = a->policy;
+		p->control_policy[i].channel_utilization_thres =
+							a->util_threshold;
+		p->control_policy[i].rcpi_steering_thres =
+							a->rcpi_threshold;
+	}
+
+	return p;
+
+fail_alloc:
+	if (p->local_disallowed_sta_macs)
+		free(p->local_disallowed_sta_macs);
+	if (p->btm_disallowed_sta_macs)
+		free(p->btm_disallowed_sta_macs);
+
+	free(p);
+
+	return NULL;
+}
+
+struct tlv_metric_report_policy *cntlr_gen_metric_report_policy(
+		struct controller *c, struct agent_policy *a,
+		struct cmdu_cstruct *cmdu, int num_radio, uint8_t *radiolist)
+{
+	int i = 0;
+	struct tlv_metric_report_policy *p;
+
+	p = calloc(1, sizeof(struct tlv_metric_report_policy));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_METRIC_REPORTING_POLICY;
+	p->interval = a->report_metric_periodic;
+	p->metric_reporting_policy_radio_nr = num_radio;
+	p->metric_reporting_policy = calloc(p->metric_reporting_policy_radio_nr,
+					sizeof(*p->metric_reporting_policy));
+
+	if (!p->metric_reporting_policy) {
+		free(p);
+		return NULL;
+	}
+
+	for (i = 0; i < p->metric_reporting_policy_radio_nr; i++) {
+		memcpy(p->metric_reporting_policy[i].radio_id, &radiolist[i*6], 6);
+		p->metric_reporting_policy[i].rcpi_thres =
+						a->report_rcpi_threshold;
+		p->metric_reporting_policy[i].rcpi_hysteresis_margin; //FIXME
+		p->metric_reporting_policy[i].channel_utilization_thres =
+						a->report_util_threshold;
+		p->metric_reporting_policy[i].is_assoc_sta_traffic_stats =
+						a->include_sta_stats;
+		p->metric_reporting_policy[i].is_assoc_sta_link_metrics =
+						a->include_sta_metric;
+	}
+
+	return p;
+}
diff --git a/src/core/cntlr_tlv_generator.h b/src/core/cntlr_tlv_generator.h
index 399f92bc4334cccb72068480aae0efb98e48970b..042fc98842c84db4fe2a9854e1acf7541f854ecc 100644
--- a/src/core/cntlr_tlv_generator.h
+++ b/src/core/cntlr_tlv_generator.h
@@ -23,4 +23,18 @@ 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,
 		struct cmdu_cstruct *cmdu);
+struct tlv_steering_policy *cntlr_gen_steering_policy(struct controller *c,
+		struct agent_policy *a, struct cmdu_cstruct *cmdu,
+		int num_radio, uint8_t *radiolist);
+struct tlv_metric_report_policy *cntlr_gen_metric_report_policy(struct controller *c,
+		struct agent_policy *a, struct cmdu_cstruct *cmdu,
+		int num_radio, uint8_t *radiolist);
+struct tlv_ch_scan_rep_policy *cntlr_gen_ch_scan_rep_policy(struct controller *c,
+		struct agent_policy *a, struct cmdu_cstruct *cmdu);
+struct tlv_unsuccess_assoc_policy *cntlr_gen_unsuccess_assoc_policy(
+		struct controller *c, struct agent_policy *a,
+		struct cmdu_cstruct *cmdu);
+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);
 #endif
diff --git a/src/core/cntlr_ubus.c b/src/core/cntlr_ubus.c
index cd4110b5ab334243a8551089c5bbec661c5b9e47..1f98a939521f7a02555a32ad111f4c9704273d00 100644
--- a/src/core/cntlr_ubus.c
+++ b/src/core/cntlr_ubus.c
@@ -31,6 +31,7 @@
 #include "hlist.h"
 #include "allsta.h"
 #include "cntlr_ubus.h"
+#include "cntlr_tlv_generator.h"
 
 #include "map_module.h"
 
@@ -109,6 +110,19 @@ static const struct blobmsg_policy bk_steer_policy_params[__BK_STEER_POLICY_MAX]
 	[BK_STEER_POLICY_STA_MAC] = { .name = "bksta", .type = BLOBMSG_TYPE_STRING },
 };
 
+enum {
+	AP_POLICY_CONFIG_AGENT,
+	AP_POLICY_CONFIG_RADIOS,
+	AP_POLICY_CONFIG_BSS,
+	__AP_POLICY_CONFIG_MAX,
+};
+
+static const struct blobmsg_policy ap_policy_config_params[__AP_POLICY_CONFIG_MAX] = {
+	[AP_POLICY_CONFIG_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING },
+	[AP_POLICY_CONFIG_RADIOS] = { .name = "radiolist", .type = BLOBMSG_TYPE_ARRAY },
+	[AP_POLICY_CONFIG_BSS] = { .name = "bsslist", .type = BLOBMSG_TYPE_ARRAY },
+};
+
 void send_cmdu_cb(struct ubus_request *req,
 				int type, struct blob_attr *msg)
 {
@@ -764,18 +778,216 @@ fail_cmdu:
 	return UBUS_STATUS_UNKNOWN_ERROR;
 }
 
+static int cntlr_ap_policy_config(struct ubus_context *ctx, struct ubus_object *obj,
+				struct ubus_request_data *req, const char *method,
+				struct blob_attr *msg)
+{
+	char agent[18] = {0};
+	char radio[18] = {0};
+	char bss[18] = {0};
+	uint8_t hwaddr[6] = {0};
+	int tlv_index = 0;
+	struct cmdu_cstruct *cmdu_data;
+	struct agent_policy *a, *found = NULL;
+	struct blob_attr *attr = NULL;
+	uint8_t *radiolist = NULL;
+	uint8_t *bsslist = NULL;
+	int rem, num_radio = 0, num_bss = 0;
+	int i = 0;
+	struct blob_attr *tb[__AP_POLICY_CONFIG_MAX];
+	struct controller *c = container_of(obj, struct controller, obj);
+	/* TLVs */
+	struct tlv_steering_policy *p1 = NULL;
+	struct tlv_metric_report_policy *p2 = NULL;
+	/* Map-2 tlvs */
+// #ifdef PROFILE2
+	struct tlv_default_8021q_settings *p3 = NULL;
+	struct tlv_traffic_sep_policy *p4 = NULL;
+	struct tlv_ch_scan_rep_policy *p5 = NULL;
+	struct tlv_unsuccess_assoc_policy *p6 = NULL;
+	struct tlv_backhaul_bss_config *p7 = NULL;
+// #endif
+
+	blobmsg_parse(ap_policy_config_params, __AP_POLICY_CONFIG_MAX, tb,
+			blob_data(msg), blob_len(msg));
+
+	if (!tb[AP_POLICY_CONFIG_AGENT] || !tb[AP_POLICY_CONFIG_RADIOS]) {
+		fprintf(stderr, "Agent policy config: provide Agent or Radio " \
+				"address in format 11:22:33...\n");
+		return UBUS_STATUS_INVALID_ARGUMENT;
+	}
+
+	strncpy(agent, blobmsg_data(tb[AP_POLICY_CONFIG_AGENT]), sizeof(agent) - 1);
+	if (!hwaddr_aton(agent, hwaddr))
+		return UBUS_STATUS_UNKNOWN_ERROR;
+
+	list_for_each_entry(a, &c->cfg.policylist, list) {
+		if (!memcmp(hwaddr, a->agent_id, sizeof(hwaddr))) {
+			found = a;
+			break;
+		}
+	}
+
+	if (!found)
+		return UBUS_STATUS_UNKNOWN_ERROR;
+
+	/* fetch radio id's */
+	blobmsg_for_each_attr(attr, tb[AP_POLICY_CONFIG_RADIOS], rem) {
+		uint8_t bssid[6] = {0};
+
+		if (blobmsg_type(attr) != BLOBMSG_TYPE_STRING)
+			continue;
+
+		memset(radio, 0, sizeof(radio));
+		strncpy(radio, blobmsg_data(attr), sizeof(radio)-1);
+		if (!hwaddr_aton(radio, bssid)) {
+			fprintf(stderr, "Agent policy config: provide radio " \
+					"address in format 11:22:33...\n");
+			if (radiolist)
+				free(radiolist);
+
+			return UBUS_STATUS_UNKNOWN_ERROR;
+		}
+
+		num_radio++;
+		radiolist = (uint8_t *)realloc(radiolist, 6 * num_radio * sizeof(uint8_t));
+		memcpy(&radiolist[(num_radio-1)*6], bssid, 6);
+	}
+
+	if (num_radio == 0)
+		return UBUS_STATUS_UNKNOWN_ERROR;
+
+	/* fetch BSS list */
+	blobmsg_for_each_attr(attr, tb[AP_POLICY_CONFIG_BSS], rem) {
+		uint8_t bssid[6] = {0};
+
+		if (blobmsg_type(attr) != BLOBMSG_TYPE_STRING)
+			continue;
+
+		memset(bss, 0, sizeof(bss));
+		strncpy(bss, blobmsg_data(attr), sizeof(bss)-1);
+		if (!hwaddr_aton(bss, bssid)) {
+			fprintf(stderr, "Agent policy config: provide bssid " \
+					"address in format 11:22:33...\n");
+			goto fail_bss_parsing;
+		}
+
+		num_bss++;
+		bsslist = (uint8_t *)realloc(bsslist, 6 * num_bss * sizeof(uint8_t));
+		memcpy(&bsslist[(num_bss-1)*6], bssid, 6);
+	}
+
+	cmdu_data = (struct cmdu_cstruct *)calloc(1, sizeof(struct cmdu_cstruct));
+	if (!cmdu_data) {
+		fprintf(stderr, "failed to malloc cmdu\n");
+		goto fail_bss_parsing;
+	}
+
+	cmdu_data->message_type = CMDU_POLICY_CONFIG_REQ;
+	memcpy(cmdu_data->origin, hwaddr, 6);
+
+	cmdu_data->num_tlvs = 2;
+// #ifdef PROFILE2
+	cmdu_data->num_tlvs += 4 + num_bss;
+// #endif
+
+	cmdu_data->tlvs = (uint8_t **)calloc(cmdu_data->num_tlvs, sizeof(uint8_t *));
+	if (!cmdu_data->tlvs) {
+		cmdu_data->num_tlvs = 0;
+		goto fail_cmdu;
+	}
+
+	/* Steering Policy TLV */
+	p1 = cntlr_gen_steering_policy(c, found, cmdu_data, num_radio, radiolist);
+	if (!p1)
+		goto fail_cmdu;
+
+	cmdu_data->tlvs[tlv_index++] = (uint8_t *)p1;
+
+	/* Metric Reporting Policy TLV */
+	p2 = cntlr_gen_metric_report_policy(c, found, cmdu_data, num_radio, radiolist);
+	if (!p2)
+		goto fail_cmdu;
+
+	cmdu_data->tlvs[tlv_index++] = (uint8_t *)p2;
+
+	/* Default 802.1Q setting TLV */
+// #ifdef PROFILE2
+	p3 = cntlr_gen_8021q_settings(c, NULL, cmdu_data);
+	if (!p3)
+		goto fail_cmdu;
+
+	cmdu_data->tlvs[tlv_index++] = (uint8_t *)p3;
+
+	/* Traffic Seperation Policy TLV */
+	p4 = cntlr_gen_traffic_sep_policy(c, cmdu_data);
+	if (!p4)
+		goto fail_cmdu;
+
+	cmdu_data->tlvs[tlv_index++] = (uint8_t *)p4;
+
+	/* Channel Scan Reporting Policy TLV */
+	p5 = cntlr_gen_ch_scan_rep_policy(c, found, cmdu_data);
+	if (!p5)
+		goto fail_cmdu;
+
+	cmdu_data->tlvs[tlv_index++] = (uint8_t *)p5;
+
+	/* Unsuccessful Association Policy TLV */
+	p6 = cntlr_gen_unsuccess_assoc_policy(c, found, cmdu_data);
+	if (!p6)
+		goto fail_cmdu;
+
+	cmdu_data->tlvs[tlv_index++] = (uint8_t *)p6;
+
+	/* Backhaul BSS Configuration TLV */
+	for (i = 0; i < num_bss; i++) {
+		uint8_t bssid[6] = {0};
+
+		memcpy(bssid, &bsslist[i*6], 6);
+		p7 = cntlr_gen_backhaul_bss_config(c, found, cmdu_data, bssid);
+		if (!p7)
+			goto fail_cmdu;
+
+		cmdu_data->tlvs[tlv_index++] = (uint8_t *)p7;
+	}
+// #endif
+
+	// TODO: ff:ff:ff:ff:ff:ff = send to all agents
+
+	send_cmdu(c, cmdu_data);
+
+	if (bsslist)
+		free(bsslist);
+
+	free(radiolist);
+
+	return 0;
+
+fail_cmdu:
+	free(cmdu_data);
+fail_bss_parsing:
+	if (bsslist)
+		free(bsslist);
+
+	free(radiolist);
+
+	return UBUS_STATUS_UNKNOWN_ERROR;
+}
+
 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[5] = {
+	struct ubus_method m[6] = {
 		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("channels", cntlr_channel_pref,
 				channel_pref_policy_params),
-		UBUS_METHOD("bk_steer", cntlr_bk_steer, bk_steer_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("teardown_ap", cntlr_teardown_ap,
 				config_policy_params),
diff --git a/src/core/config.c b/src/core/config.c
index bb72a65b3b619cd8b878fea94c0827cc0eb7bf2d..e6e6f82288fc5ebc9c2d0c0ff8b1b105aa5a342f 100644
--- a/src/core/config.c
+++ b/src/core/config.c
@@ -41,9 +41,21 @@
 
 int verbose;
 
+static void stax_add_entry(struct list_head *h, char *sta_macstr)
+{
+	struct stax *n;
+
+	n = calloc(1, sizeof(struct stax));
+	if (n) {
+		snprintf(n->macstring, 18, "%s", sta_macstr);
+		list_add(&n->list, h);
+	}
+}
+
 void cntlr_config_dump(struct controller_config *c)
 {
 	int i;
+	struct stax *x = NULL;
 
 	dbg("Controller config ---------\n");
 	dbg("Enabled: %d\n", c->enabled);
@@ -75,6 +87,7 @@ void cntlr_config_dump(struct controller_config *c)
 	dbg("  RCPI-threshold        : %d\n", c->apolicy.rcpi_threshold);
 	dbg("  Report scan           : %d\n", c->apolicy.report_scan);
 	dbg("  Report assocfails     : %d\n", c->apolicy.report_sta_assocfails);
+	dbg("  Report assocfails rate: %d\n", c->apolicy.report_sta_assocfails_rate);
 	dbg("  Report metric         : %d\n", c->apolicy.report_metric_periodic);
 	dbg("  Report RCPI-thresh    : %d\n", c->apolicy.report_rcpi_threshold);
 	dbg("  Report Util-thresh    : %d\n", c->apolicy.report_util_threshold);
@@ -85,6 +98,17 @@ void cntlr_config_dump(struct controller_config *c)
 	dbg("  Disallow bSTA P1      : %d\n", c->apolicy.disallow_bsta_p1);
 	dbg("  Disallow bSTA P2      : %d\n", c->apolicy.disallow_bsta_p2);
 
+#if 0
+	// INIT_LIST_HEAD(&c->apolicy.steer_exlist); // TODO: remove INIT_LIST_HEAD
+	// INIT_LIST_HEAD(&c->apolicy.btmsteer_exlist);
+	list_for_each_entry(x, &c->apolicy.steer_exlist, list) {
+		dbg("  Disallowed STA        : %s\n", x->macstring);
+	}
+	list_for_each_entry(x, &c->apolicy.btmsteer_exlist, list) {
+		dbg("  Disallowed BTM STA    : %s\n", x->macstring);
+	}
+#endif
+
 	dbg("---------------------------\n");
 }
 
@@ -224,11 +248,14 @@ static int cntlr_config_get_agent_policy(struct controller_config *c,
 {
 	enum {
 		POL_AGENT_ID,
+		POL_STEER_EXCLUDE,
+		POL_STEER_EXCLUDE_BTM,
 		POL_STEER,
 		POL_UTIL_TH,
 		POL_RCPI_TH,
 		POL_RPT_SCAN,
 		POL_RPT_ASSOC_FAILS,
+		POL_RPT_ASSOC_FAILS_RATE,
 		POL_RPT_METRIC_PERIODIC,
 		POL_RPT_RCPI_TH,
 		POL_RPT_UTIL_TH,
@@ -242,11 +269,14 @@ static int cntlr_config_get_agent_policy(struct controller_config *c,
 	};
 	const struct uci_parse_option opts[] = {
 		{ .name = "agent_id", .type = UCI_TYPE_STRING },
+		{ .name = "steer_exclude", .type = UCI_TYPE_LIST },
+		{ .name = "steer_exclude_btm", .type = UCI_TYPE_LIST },
 		{ .name = "steer_policy", .type = UCI_TYPE_STRING },
 		{ .name = "util_threshold", .type = UCI_TYPE_STRING },
 		{ .name = "rcpi_threshold", .type = UCI_TYPE_STRING },
 		{ .name = "report_scan", .type = UCI_TYPE_STRING },
 		{ .name = "report_sta_assocfails", .type = UCI_TYPE_STRING },
+		{ .name = "report_sta_assocfails_rate", .type = UCI_TYPE_STRING },
 		{ .name = "report_metric_periodic", .type = UCI_TYPE_STRING },
 		{ .name = "report_rcpi_threshold", .type = UCI_TYPE_STRING },
 		{ .name = "report_util_threshold", .type = UCI_TYPE_STRING },
@@ -259,11 +289,15 @@ static int cntlr_config_get_agent_policy(struct controller_config *c,
 	};
 	struct uci_option *tb[NUM_POLICIES];
 	struct agent_policy *a;
+	struct uci_element *x;
 
 	a = calloc(1, sizeof(*a));
 	if (!a)
 		return -1;
 
+	INIT_LIST_HEAD(&a->steer_exlist);
+	INIT_LIST_HEAD(&a->btmsteer_exlist);
+
 	uci_parse_section(s, opts, NUM_POLICIES, tb);
 
 	if (tb[POL_AGENT_ID]) {
@@ -272,6 +306,18 @@ static int cntlr_config_get_agent_policy(struct controller_config *c,
 		hwaddr_aton(val, a->agent_id);
 	}
 
+	if (tb[POL_STEER_EXCLUDE]) {
+		uci_foreach_element(&tb[POL_STEER_EXCLUDE]->v.list, x) {
+			stax_add_entry(&a->steer_exlist, x->name);
+		}
+	}
+
+	if (tb[POL_STEER_EXCLUDE_BTM]) {
+		uci_foreach_element(&tb[POL_STEER_EXCLUDE_BTM]->v.list, x) {
+			stax_add_entry(&a->btmsteer_exlist, x->name);
+		}
+	}
+
 	if (tb[POL_STEER])
 		a->policy = atoi(tb[POL_STEER]->v.string);
 
@@ -292,6 +338,11 @@ static int cntlr_config_get_agent_policy(struct controller_config *c,
 					true : false;
 	}
 
+	if (tb[POL_RPT_ASSOC_FAILS_RATE]) {
+		a->report_sta_assocfails_rate =
+				atoi(tb[POL_RPT_ASSOC_FAILS_RATE]->v.string);
+	}
+
 	if (tb[POL_RPT_METRIC_PERIODIC]) {
 		a->report_metric_periodic =
 				atoi(tb[POL_RPT_METRIC_PERIODIC]->v.string);
diff --git a/src/core/config.h b/src/core/config.h
index 792e25bd2732711cbe089a2893755c3c05b743f5..75c0af2a5d12516f5134b9ea1719801d04aba909 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -37,6 +37,11 @@ enum wifi_security {
 };
 */
 
+struct stax {
+	char macstring[32];     /* ':' separated mac address string */
+	struct list_head list;
+};
+
 struct iface_credential {
 	enum wifi_band band;
 	enum wifi_security sec;
@@ -63,6 +68,7 @@ struct agent_policy {
 	uint8_t rcpi_threshold;           /* 0 - 220 */
 	bool report_scan;                 /* report independent scans */
 	bool report_sta_assocfails;       /* report STA assoc fails */
+	uint32_t report_sta_assocfails_rate;  /* reporting rate for STA assoc fails (attempts per minute) */
 	uint8_t report_metric_periodic;   /* 0 = disable, else 1 - 255 in secs */
 	uint8_t report_rcpi_threshold;    /* 0, or 1 - 220 */
 	uint8_t report_util_threshold;    /* 0, or channel utilization value */