diff --git a/src/core/agent.c b/src/core/agent.c index a893dd23b511cc021050044b0d1efd1da6961a66..b2ce271ced813f768410837ed485f6770d0b152a 100644 --- a/src/core/agent.c +++ b/src/core/agent.c @@ -353,7 +353,7 @@ struct wifi_assoc_frame *wifi_get_frame(struct agent *a, uint8_t *macaddr) } /* lookup netif struct by name */ -static struct netif_fh *get_netif_by_name(struct agent *a, const char *name) +struct netif_fh *get_netif_by_name(struct agent *a, const char *name) { struct netif_fh *p; diff --git a/src/core/agent.h b/src/core/agent.h index c2e17e5a3a53b4f8ff8e2506dd7ee3df808ed0bc..7694a1379c24d1302bfec3f0b4db4ca7414d4aea 100644 --- a/src/core/agent.h +++ b/src/core/agent.h @@ -166,6 +166,7 @@ struct netif_fh { char ssid[33]; char standard[32]; bool enabled; + bool torndown; int bssload; struct netif_fhcfg *cfg; int nbr_scan; @@ -552,10 +553,11 @@ extern void wifiagent_notify_event(struct agent *a, void *ev_type, extern int plugins_load(int argc, char *argv[], struct list_head *plugins); extern int plugins_unload(struct list_head *plugins); - +struct netif_fh *get_netif_by_name(struct agent *a, const char *name); struct netif_fh *wifi_radio_to_ap(struct agent *a, const char *radio); struct wifi_radio_element *wifi_ifname_to_radio_element(struct agent *a, char *ifname); +const char *wifi_ifname_to_radio(struct agent *a, char *ifname); int prepare_tunneled_message(void *agent, uint8_t protocol, const char *framestr); int wifi_mod_bridge(struct agent *a, char *ifname, char *action); diff --git a/src/core/agent_map.c b/src/core/agent_map.c index 288bd920669c469d69a280a746a1a82ef952f876..087deb078daed9e1d60cfb9670a51a0062b1dd8a 100644 --- a/src/core/agent_map.c +++ b/src/core/agent_map.c @@ -885,16 +885,47 @@ int wifi_get_radio_index_by_mac(struct agent *a, return -1; } +int wifi_disable_iface(char *ifname) +{ + uci_set_wireless_interface_option("mapagent", "fh-iface", "ifname", + ifname, "enabled", "0"); + uci_set_wireless_interface_option("wireless", "wifi-iface", "ifname", + ifname, "start_disabled", "1"); + dbg("|%s:%d|Disabled interface %s\n", __func__, __LINE__, ifname); + return 0; +} + int wifi_teardown_iface(const char *ifname) { config_del_iface("wireless", "wifi-iface", ifname); - //config_del_iface("ieee1905", "wifi-iface", ifname); config_del_iface("mapagent", "fh-iface", ifname); - config_del_iface("mapagent", "bk-iface", ifname); return 0; } +int wifi_disable_map_ifaces_by_radio(struct agent *a, char *device) +{ + struct netif_fhcfg *fh, *fh_tmp; + + list_for_each_entry_safe(fh, fh_tmp, &a->cfg.fhlist, list) { + struct netif_fh *f; + + if (strncmp(fh->device, device, sizeof(fh->device) - 1)) + continue; + + wifi_disable_iface(fh->name); + //fh->enabled = 0; + //clean_fh(fh); + f = get_netif_by_name(a, fh->name); + if (f) + f->torndown = true; + } + + agent_config_reload(&a->cfg); + agent_link_ap_to_cfg(a); + return 0; +} + int wifi_teardown_map_ifaces_by_radio(struct agent *a, char *device) { struct netif_fhcfg *fh, *fh_tmp; @@ -1024,6 +1055,25 @@ char *wifi_gen_first_ifname(struct agent *a, char *device, char *ifname) return NULL; } +/* return ifname buffer */ +struct netif_fh *wifi_get_first_available_map(struct agent *a, char *device, char *ifname) +{ + struct netif_fh *fh; + + list_for_each_entry(fh, &a->fhlist, list) { + if (!fh->torndown) + continue; + + if (strncmp(fh->cfg->device, device, IFNAMSIZ)) + continue; + + strncpy(ifname, fh->name, IFNAMSIZ - 1); + return fh; + } + + return NULL; +} + int wsc_get_iop_ext(uint8_t *msg, uint16_t msglen, struct iop_ext *exts) { uint8_t *p; @@ -1163,7 +1213,7 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_buff *rx_cmdu) goto teardown; } - wifi_teardown_map_ifaces_by_radio(a, radio->name); + wifi_disable_map_ifaces_by_radio(a, radio->name); while (tv[3][num]) { struct wps_credential out = {0}; @@ -1172,14 +1222,18 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_buff *rx_cmdu) 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 "\ - "maximum number of interfaces have "\ - "been reached\n", MACFMT "!\n", - MAC2STR(bssid)); - /* TODO: what should be the correct course of action? */ - break; + struct netif_fh *fh; + + fh = wifi_get_first_available_map(a, radio->name, ifname); + if (!fh) { + if (!wifi_gen_first_ifname(a, radio->name, ifname)) { + err("Failed to find valid interface name, probably "\ + "maximum number of interfaces have "\ + "been reached\n", MACFMT "!\n", + MAC2STR(bssid)); + /* TODO: what should be the correct course of action? */ + break; + } } ret = wsc_process_m2(radio->autconfig.m1_frame, @@ -1236,6 +1290,9 @@ int handle_ap_autoconfig_wsc(void *agent, struct cmdu_buff *rx_cmdu) goto teardown; } + if (fh) + fh->torndown = false; + free(ext); num++; } diff --git a/src/core/config.c b/src/core/config.c index 0df2eefe12bfa6523d4437801ad6958fe5fe7506..44c9275c2662a26d19e24972fb82d4c4c572a800 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -958,6 +958,8 @@ int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device, interface_name, "encryption", auth_type_str); uci_set_wireless_interface_option(UCI_AGENT, UCI_FH_AGENT, "ifname", interface_name, "multi_ap", multiap_str); + uci_set_wireless_interface_option(UCI_AGENT, UCI_FH_AGENT, "ifname", + interface_name, "enabled", "1"); if (multi_ap & 0x01) { char disallow_str[2] = {0}; @@ -1001,6 +1003,10 @@ int uci_apply_m2(struct agent_config *cfg, char *interface_name, char *device, interface_name, "ieee80211k", "1"); uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname", interface_name, "ieee80211v", "1"); + uci_set_wireless_interface_option(UCI_WIRELESS, UCI_WLAN_IFACE, "ifname", + interface_name, "start_disabled", "0"); + dbg("|%s:%d| Enabled interface %s\n", __func__, __LINE__, + interface_name); do { char buf[512] = {0};