diff --git a/src/core/agent.h b/src/core/agent.h
index 59a8701b8bf5a953eba7ebf634b462d8be2fd7fc..ae08dda63741d961f0b48269a723a968a84b954d 100644
--- a/src/core/agent.h
+++ b/src/core/agent.h
@@ -348,6 +348,15 @@ struct wifi_unassoc_sta_element {
 	uint8_t rssi;
 };
 
+struct iop_ext {
+	uint8_t bridge[16];
+	uint8_t proto[8];
+	uint8_t vid;
+	uint8_t bk_ssid[33];
+	uint8_t bk_key[65];
+	uint32_t br_ip;
+};
+
 struct wsc_key {
 	uint8_t *key;
 	uint32_t key_len;
diff --git a/src/core/agent_map.c b/src/core/agent_map.c
index 3c55d713586d6d62eeb415f31ae478eae6844690..d783a3a1eca2170c0a1814e749a315974d0465d8 100644
--- a/src/core/agent_map.c
+++ b/src/core/agent_map.c
@@ -1062,6 +1062,79 @@ char *wifi_gen_first_ifname(struct agent *a, char *device, char *ifname)
 	return NULL;
 }
 
+int wsc_get_iop_ext(uint8_t *msg, uint16_t msglen, struct iop_ext *exts)
+{
+	uint8_t *p;
+	uint8_t *msg_end;
+
+	if (!msg || msglen == 0 || !exts)
+		return -1;
+
+	p = msg;
+	msg_end = msg + msglen;
+
+	while (abs(p - msg) < msglen - 4) {
+		uint16_t attr_type;
+		uint16_t attr_len;
+
+		attr_type = buf_get_be16(p);
+		p += 2;
+		attr_len = buf_get_be16(p);
+		p += 2;
+
+		if (p + attr_len > msg_end)
+			return -1;
+
+		if (attr_type == ATTR_VENDOR_EXTENSION) {
+			uint8_t id[3] =  {0};
+			uint8_t *end_of_ext;
+			uint8_t subelem;
+			uint8_t len;
+
+			/* May be one or more subelements (Section 12 of WSC spec) */
+			end_of_ext = p + attr_len;
+			memcpy(id, p, sizeof(id));
+			p += 3;
+			attr_len -= 3;
+
+			if (id[0] == IOP_VENDOR_ID_1 &&
+					id[1] == IOP_VENDOR_ID_2 &&
+					id[2] == IOP_VENDOR_ID_3) {
+
+				while (p < end_of_ext) {
+					memcpy(&subelem, p, 1);
+					p += 1;
+					attr_len -= 1;
+
+					memcpy(&len, p, 1);
+					p += 1;
+					attr_len -= 1;
+
+					if (subelem == ATTR_BRIDGE)
+						memcpy(exts->bridge, p, len);
+					else if (subelem == ATTR_PROTO)
+						memcpy(exts->proto, p, len);
+					else if (subelem == ATTR_VID)
+						memcpy(&exts->vid, p, len);
+					else if (subelem == ATTR_BR_IP)
+						memcpy(&exts->br_ip, p, len);
+					else if (subelem == ATTR_BK_SSID)
+						memcpy(exts->bk_ssid, p, len);
+					else if (subelem == ATTR_BK_KEY)
+						memcpy(exts->bk_key, p, len);
+
+					p += len;
+					attr_len -= len;
+				}
+			}
+		}
+
+		p += attr_len;
+	}
+
+	return 0;
+}
+
 int handle_ap_autoconfig_wsc(void *agent, struct cmdu_buff *rx_cmdu)
 {
 	struct agent *a = (struct agent *) agent;
@@ -1102,6 +1175,9 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_buff *rx_cmdu)
 		struct wps_credential out = {0};
 		char ifname[IFNAMSIZ] = {0};
 		int rv;
+		uint8_t *ext = NULL;
+		uint16_t extlen = 0;
+		struct iop_ext exts = {0};
 
 		if (!wifi_gen_first_ifname(a, radio->name, ifname)) {
 			err("Failed to find valid interface name, probably "\
@@ -1111,9 +1187,11 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_buff *rx_cmdu)
 			return -1;
 		}
 
-		ret = wsc_process_m2(radio->autconfig.m1_frame, radio->autconfig.m1_size,
-				radio->autconfig.key, tv[3][num]->data, tlv_length(tv[3][num]),
-				&out);
+		ret = wsc_process_m2(radio->autconfig.m1_frame,
+				radio->autconfig.m1_size,
+				radio->autconfig.key, tv[3][num]->data,
+				tlv_length(tv[3][num]),
+				&out, &ext, &extlen);
 		if (ret) {
 			err("Failed to process M2 target for interface "\
 					MACFMT "!\n", MAC2STR(bssid));
@@ -1125,6 +1203,18 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_buff *rx_cmdu)
 			return -1;
 		}
 
+		ret = wsc_get_iop_ext(ext, extlen, &exts);
+		if (ret) {
+			err("Failed to process IOPSYS vendor ext for interface "\
+					MACFMT "!\n", MAC2STR(bssid));
+
+			wifi_teardown_map_ifaces_by_radio(a, radio->name);
+			/* Return rather than freeing because it may belong to
+			 * an updated frame
+			 */
+			return -1;
+		}
+
 		if (BIT(4, out.mapie)) {
 			err("MAP Extension had teardown bit set, tearing down "\
 					"all MAP interfaces for bssid "	MACFMT \
@@ -1137,7 +1227,7 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_buff *rx_cmdu)
 		}
 
 		ret = uci_apply_m2(&a->cfg, ifname, radio->name, &out,
-				radio->onboarded);
+				radio->onboarded, &exts);
 		if (ret) {
 			err("Failure to process M2, tearing down all MAP "\
 					" interfaces for bssid " MACFMT "\n",
diff --git a/src/core/config.c b/src/core/config.c
index 99e752a95331a5bf01e9ba7c3a20f47be532f6be..e9bbd1ab1011a56a95a301e6a1d39ccd99d939c8 100644
--- a/src/core/config.c
+++ b/src/core/config.c
@@ -713,7 +713,7 @@ int uci_apply_wps_credentials(struct agent_config *cfg, enum wifi_band band)
 
 /* TODO: batch the changes arther than commit oneby one */
 int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device,
-		struct wps_credential *out, bool onboarded)
+		struct wps_credential *out, bool onboarded, struct iop_ext *exts)
 {
 	bool ret;
 	char auth_type_str[20] = {0};
@@ -739,7 +739,7 @@ int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device,
 
 	memcpy(ssid, out->ssid, out->ssidlen);
 	memcpy(network_key, out->key, out->keylen);
-	memcpy(bridge, out->bridge, 15);
+	memcpy(bridge, exts->bridge, 15);
 
 	inet_ntop(AF_INET, &out->br_ip, ipaddr_str, INET_ADDRSTRLEN);
 
@@ -750,11 +750,11 @@ int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device,
 	dbg("  - NETWORK_KEY     : %s\n", network_key);
 	dbg("  - MAPIE_EXTENSION : 0x%02x\n", out->mapie);
 	dbg("  - BRIDGE          : %s\n", bridge);
-	dbg("  - PROTO           : %s\n", out->proto);
-	dbg("  - VID             : 0x%02x\n", out->vid);
+	dbg("  - PROTO           : %s\n", exts->proto);
+	dbg("  - VID             : 0x%02x\n", exts->vid);
 	dbg("  - BR_IP           : %s\n", ipaddr_str);
-	dbg("  - BK_SSID         : %s\n", out->bk_ssid);
-	dbg("  - BK_KEY          : %s\n", out->bk_key);
+	dbg("  - BK_SSID         : %s\n", exts->bk_ssid);
+	dbg("  - BK_KEY          : %s\n", exts->bk_key);
 	dbg("  - BAND            : %s\n", band_str);
 
 	// if teardown bit is set, return
@@ -775,7 +775,7 @@ int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device,
 		return M2_PROCESS_ERROR;
 	}
 
-	ret = uci_set_bridge("network", bridge, out->proto, ipaddr_str);
+	ret = uci_set_bridge("network", bridge, exts->proto, ipaddr_str);
 	if (ret) {
 		info("Error seting up bridge from M2!\n");
 		return M2_PROCESS_ERROR;
@@ -843,9 +843,9 @@ int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device,
 	uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
 			interface_name, "multi_ap", multiap_str);
 	uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
-			interface_name, "multi_ap_backhaul_key", out->bk_key);
+			interface_name, "multi_ap_backhaul_key", exts->bk_key);
 	uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname",
-			interface_name, "multi_ap_backhaul_ssid", out->bk_ssid);
+			interface_name, "multi_ap_backhaul_ssid", exts->bk_ssid);
 	uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE,	"ifname",
 			interface_name, "ieee80211k", "1");
 	uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE,	"ifname",
diff --git a/src/core/config.h b/src/core/config.h
index 04e132a986c1383ce407f66d2455c254f0219d06..32956e3dfd36a24d95ba52fb5207a6039aaa53e4 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -37,6 +37,8 @@ enum steer_action {
 #define CONTROLLER_SELECT_RETRY_INT		3	/* attempts */
 #define CONTROLLER_SELECT_AUTOSTART		0	/* don't start cntlr */
 
+struct iop_ext;
+
 struct steer_policy {
 	char name[16];	/* XXX: maps to struct steer_rule.name in (all)?
 			 * cases otherwise there is no way of knowing how
@@ -257,7 +259,7 @@ void clean_fh(struct netif_fhcfg *p);
 int clean_all_fh(struct agent_config *cfg);
 
 int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device,
-		struct wps_credential *out, bool onboarded);
+		struct wps_credential *out, bool onboarded, struct iop_ext *exts);
 int uci_apply_wps_credentials(struct agent_config *cfg, enum wifi_band band);
 int wifi_reorder_interfaces_by_device(struct agent_config *ac,
 		struct uci_context *ctx, struct uci_package *pkg, char *device);