diff --git a/src/agent_map.c b/src/agent_map.c
index 65b85cbbd69ff6816c0c573b86771eb6e8ae8028..1faf224988b96c69a315e7b9d4f11b9ded7e1d69 100644
--- a/src/agent_map.c
+++ b/src/agent_map.c
@@ -19,10 +19,6 @@
 #include <net/if_arp.h>
 #include <pthread.h>
 
-#ifndef IFNAMSIZ
-#define IFNAMSIZ 16
-#endif
-
 #define AGENT_WIFI_IFACE_MAX_NUM 8
 #define BSTA_STEER_TIMEOUT (7 * 1000)
 
@@ -1184,20 +1180,13 @@ char *wifi_gen_first_ifname(struct agent *a, char *device, char *ifname)
 	int i;
 	uint8_t devnum = get_device_num_from_name(device);
 
-
-	snprintf(ifname, IFNAMSIZ, "%s", a->cfg.netdev);
-	snprintf(ifname + strlen(ifname), IFNAMSIZ, "%hhu", devnum);
-
 	/* TODO: should work with 16 instead of 8 */
-	for (i = 1; i <= AGENT_WIFI_IFACE_MAX_NUM; i++) {
+	for (i = 0; i <= AGENT_WIFI_IFACE_MAX_NUM; i++) {
+
+		config_calc_ifname(&a->cfg, devnum, i, ifname);
 
 		if (!check_wireless_ifname(a, device, ifname))
 			return ifname;
-
-		snprintf(ifname, IFNAMSIZ, "%s", a->cfg.netdev);
-		snprintf(ifname + strlen(ifname), IFNAMSIZ, "%hhu", devnum);
-		snprintf(ifname + strlen(ifname), IFNAMSIZ, "%s", a->cfg.brcm_setup ? "." : "_");
-		snprintf(ifname + strlen(ifname), IFNAMSIZ, "%d", i);
 	}
 
 	return NULL;
diff --git a/src/config.c b/src/config.c
index 9006844aea141fbb0571c2752a46bbe8930a7edc..652d3e7ca9d0b903102e96fa717b2b24bc2fc97e 100644
--- a/src/config.c
+++ b/src/config.c
@@ -11,10 +11,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 
-#ifndef IFNAMSIZ
-#define IFNAMSIZ 16
-#endif
-
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
@@ -1059,6 +1055,21 @@ bool config_find_uuid(struct agent_config *cfg, char *buf)
 	return found;
 }
 
+static char *get_separator(char *netdev)
+{
+	char separators[] = { '_', '.', '-', '\0' };
+	size_t i = 0;
+	char *pos = NULL;
+
+	while (separators[i] != '\0') {
+		pos = strchr(netdev, separators[i++]);
+		if (pos)
+			break;
+	}
+
+	return pos;
+}
+
 /* 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 iop_ext *exts)
@@ -1162,12 +1173,20 @@ int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device,
 	ret = uci_check_wifi_iface(UCI_WIRELESS, interface_name,
 			UCI_WLAN_IFACE);
 	if (!ret) {
-		char name[32] = {0};
+		char section_name[32] = {0};
+		char *psep;
+
+		snprintf(section_name, sizeof(section_name),
+				 "%s_ap", interface_name);
+
+		psep = get_separator(interface_name);
+		if (psep && *psep != '_') /* e.g.: '.' or '-' */
+			/* only '_' allowed in section names */
+			replace_char(section_name, *psep, '_');
 
-		snprintf(name, sizeof(name), "%s_ap", interface_name);
-		replace_char(name, '.', '_');
 		ret = uci_add_wireless_iface_sec(UCI_WIRELESS, interface_name,
-				UCI_WLAN_IFACE, name);
+				UCI_WLAN_IFACE, section_name);
+
 		if (!ret)
 			return M2_PROCESS_ERROR;
 
@@ -1814,11 +1833,13 @@ static int agent_config_get_wifi_agent(struct agent_config *a,
 		strncpy(a->al_bridge, "br-lan", sizeof(a->al_bridge) - 1);
 
 	if (tb[A_NETDEV]) {
-		const char *ifname;
-		ifname = tb[A_NETDEV]->v.string;
-		strncpy(a->netdev, ifname, sizeof(a->netdev) - 1);
+		const char *netdev;
+
+		netdev = tb[A_NETDEV]->v.string;
+		strncpy(a->netdev, netdev, sizeof(a->netdev) - 1);
 	} else { /* Default to wl/wlan if not specfied */
-		strncpy(a->netdev, (a->brcm_setup)?"wl":"wlan", sizeof(a->netdev) - 1);
+		strncpy(a->netdev, (a->brcm_setup) ? "wl%." : "wlan%_",
+				sizeof(a->netdev) - 1);
 	}
 
 	if (tb[A_TS])
@@ -2956,6 +2977,55 @@ int agent_config_clean(struct agent_config *cfg)
 	return 0;
 }
 
+/* config_calc_name - depending on the netdev option in UCI
+ * wl : wl0, wl0.1, wl0.2
+ * wl%. : wl0, wl0.1, wl0.2
+ * wlan%_ : wlan0, wlan0_1, wlan0_2
+ * wlan%_% : wlan0_0, wlan0_1, wlan0_2
+ */
+int config_calc_ifname(struct agent_config *cfg,
+		uint8_t dev_num, uint8_t index, char *ifname)
+{
+	char fmt[IFNAMSIZ] = { 0 };
+	char *posX, *posS, *posY;
+
+
+	posX = strstr(cfg->netdev, "%");
+
+	if (posX) {
+		strncpy(fmt, cfg->netdev, abs(cfg->netdev - posX));
+		strncat(fmt, "%hhu", sizeof(fmt) - strlen(fmt) - 1);
+	} else {
+		/* legacy: option netdev 'wl' (or 'wlan') */
+		strncpy(fmt, cfg->netdev, sizeof(fmt));
+		snprintf(ifname, IFNAMSIZ, "%s", cfg->netdev);
+		snprintf(ifname + strlen(ifname), IFNAMSIZ, "%hhu", dev_num);
+		if (index > 0) {
+			snprintf(ifname + strlen(ifname), IFNAMSIZ, "%s",
+					cfg->brcm_setup ? "." : "_");
+			snprintf(ifname + strlen(ifname), IFNAMSIZ, "%hhu", index);
+		}
+		return 0;
+	}
+
+	posS = get_separator(cfg->netdev);
+
+	if (posS) {
+		posY = strchr(posS, '%');
+		if (posY || index != 0) {
+			if (sizeof(fmt) > strlen(fmt) + 1)
+				/* add separator, e.g: '.' or '_' */
+				strncat(fmt, posS, 1);
+			strncat(fmt, "%hhu", sizeof(fmt) - strlen(fmt) - 1);
+			snprintf(ifname, sizeof(fmt), fmt, dev_num, index);
+		} else {
+			snprintf(ifname, sizeof(fmt), fmt, dev_num);
+		}
+	}
+
+	return 0;
+}
+
 int wifi_reorder_interfaces_by_device(struct agent_config *ac,
 		struct uci_context *ctx, struct uci_package *pkg, char *device)
 {
@@ -2976,10 +3046,11 @@ int wifi_reorder_interfaces_by_device(struct agent_config *ac,
 			__LINE__, device);
 
 	devnum = get_device_num_from_name(device);
-	snprintf(ifname, IFNAMSIZ, "%s", ac->netdev);
-	snprintf(ifname + strlen(ifname), IFNAMSIZ, "%hhu", devnum);
 
-	for (i = 1; i < 16; i++) {
+	for (i = 0; i < 16; i++) {
+
+		config_calc_ifname(ac, devnum, i, ifname);
+
 		uci_foreach_element(&pkg->sections, e) {
 			struct uci_section *s = uci_to_section(e);
 
@@ -3000,11 +3071,6 @@ int wifi_reorder_interfaces_by_device(struct agent_config *ac,
 			j++;
 			break;
 		}
-
-		snprintf(ifname, IFNAMSIZ, "%s", ac->netdev);
-		snprintf(ifname + strlen(ifname), IFNAMSIZ, "%d", devnum);
-		snprintf(ifname + strlen(ifname), IFNAMSIZ, "%s", ac->brcm_setup ? "." : "_");
-		snprintf(ifname + strlen(ifname), IFNAMSIZ, "%d", i);
 	}
 
 	return 0;
diff --git a/src/config.h b/src/config.h
index c86cb4d7526fdcf951e3950b197533bea101fed8..e4010f1b43db2054d9ee5b036b9d3b69bf44bb99 100644
--- a/src/config.h
+++ b/src/config.h
@@ -175,6 +175,9 @@ struct agent_config_radio {
 	struct list_head list;
 };
 
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
 struct agent_config {
 	bool enabled;
 	int debug_level;
@@ -193,7 +196,7 @@ struct agent_config {
 	int resend_num;
 	uint8_t cntlr_almac[6];
 	char al_bridge[16];
-	char netdev[16];
+	char netdev[IFNAMSIZ];
 
 	struct policy_cfg *pcfg;  /* policy section */
 	struct ctrl_select_cfg *cscfg;  /* controller select section */
@@ -281,6 +284,8 @@ 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 iop_ext *exts);
 int uci_apply_wps_credentials(struct agent_config *cfg, enum wifi_band band);
+int config_calc_ifname(struct agent_config *cfg, uint8_t dev_num,
+		uint8_t index, char *ifname);
 int wifi_reorder_interfaces_by_device(struct agent_config *ac,
 		struct uci_context *ctx, struct uci_package *pkg, char *device);
 int wifi_reorder_interfaces(struct agent_config *ac);