From: Felix Fietkau Date: Mon, 25 Nov 2013 15:43:15 +0000 (+0000) Subject: hostapd: update to version 2013-11-20 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=1d75f7506df7518d59b9d3c5297feb93f0828917;p=librecmc%2Flibrecmc.git hostapd: update to version 2013-11-20 Signed-off-by: Felix Fietkau SVN-Revision: 38914 --- diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index fbc4e8c1c3..896a6373bd 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -8,16 +8,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_VERSION:=20130807 +PKG_VERSION:=20131120 PKG_RELEASE:=1 -PKG_REV:=d2ba3d6bd9336ef8fd761a0cc7999824d4c4da41 +PKG_REV:=594516b4c28a94ca686b17f1e463dfd6712b75a7 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=git://w1.fi/srv/git/hostap.git PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE_VERSION:=$(PKG_REV) PKG_SOURCE_PROTO:=git -PKG_MIRROR_MD5SUM:=4e7c1f97edd7514535056fce54ae053a +# PKG_MIRROR_MD5SUM:=4e7c1f97edd7514535056fce54ae053a PKG_MAINTAINER:=Felix Fietkau @@ -252,6 +252,7 @@ define Build/RunMake $(TARGET_CONFIGURE_OPTS) \ $(DRIVER_MAKEOPTS) \ LIBS="$(TARGET_LDFLAGS)" \ + LIBS_c="" \ BCHECK= \ $(2) endef diff --git a/package/network/services/hostapd/patches/100-madwifi_key_fixes.patch b/package/network/services/hostapd/patches/100-madwifi_key_fixes.patch new file mode 100644 index 0000000000..dcd6d10bd6 --- /dev/null +++ b/package/network/services/hostapd/patches/100-madwifi_key_fixes.patch @@ -0,0 +1,34 @@ +--- a/src/drivers/driver_madwifi.c ++++ b/src/drivers/driver_madwifi.c +@@ -450,7 +450,9 @@ wpa_driver_madwifi_set_key(const char *i + + memset(&wk, 0, sizeof(wk)); + wk.ik_type = cipher; +- wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; ++ wk.ik_flags = IEEE80211_KEY_RECV; ++ if (set_tx) ++ wk.ik_flags |= IEEE80211_KEY_XMIT; + if (addr == NULL || is_broadcast_ether_addr(addr)) { + memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); + wk.ik_keyix = key_idx; +@@ -462,6 +464,20 @@ wpa_driver_madwifi_set_key(const char *i + wk.ik_keylen = key_len; + memcpy(wk.ik_keydata, key, key_len); + ++#ifdef WORDS_BIGENDIAN ++#define WPA_KEY_RSC_LEN 8 ++ { ++ size_t i; ++ u8 tmp[WPA_KEY_RSC_LEN]; ++ os_memset(tmp, 0, sizeof(tmp)); ++ for (i = 0; i < seq_len; i++) ++ tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i]; ++ os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN); ++ } ++#else /* WORDS_BIGENDIAN */ ++ os_memcpy(&wk.ik_keyrsc, seq, seq_len); ++#endif /* WORDS_BIGENDIAN */ ++ + ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); + if (ret < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" diff --git a/package/network/services/hostapd/patches/110-bool_fix.patch b/package/network/services/hostapd/patches/110-bool_fix.patch new file mode 100644 index 0000000000..9f82b0b057 --- /dev/null +++ b/package/network/services/hostapd/patches/110-bool_fix.patch @@ -0,0 +1,14 @@ +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -1933,9 +1933,9 @@ void ieee802_1x_notify_pre_auth(struct e + } + + +-static const char * bool_txt(Boolean bool) ++static const char * bool_txt(Boolean bool_val) + { +- return bool ? "TRUE" : "FALSE"; ++ return bool_val ? "TRUE" : "FALSE"; + } + + diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch new file mode 100644 index 0000000000..2289f517f8 --- /dev/null +++ b/package/network/services/hostapd/patches/200-multicall.patch @@ -0,0 +1,246 @@ +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -14,6 +14,7 @@ CFLAGS += -I../src/utils + # CFLAGS += -DUSE_KERNEL_HEADERS -I/usr/src/linux/include + + -include .config ++-include $(if $(MULTICALL), ../wpa_supplicant/.config) + + ifndef CONFIG_OS + ifdef CONFIG_NATIVE_WINDOWS +@@ -200,10 +201,14 @@ ifdef CONFIG_IEEE80211AC + CFLAGS += -DCONFIG_IEEE80211AC + endif + ++ifndef MULTICALL ++CFLAGS += -DNO_SUPPLICANT ++endif ++ + include ../src/drivers/drivers.mak +-OBJS += $(DRV_AP_OBJS) +-CFLAGS += $(DRV_AP_CFLAGS) +-LDFLAGS += $(DRV_AP_LDFLAGS) ++OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS))) ++CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS)) ++LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS)) + LIBS += $(DRV_AP_LIBS) + + ifdef CONFIG_L2_PACKET +@@ -890,6 +895,12 @@ install: all + + BCHECK=../src/drivers/build.hostapd + ++hostapd_multi.a: $(BCHECK) $(OBJS) ++ $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c ++ @$(E) " CC " $< ++ @rm -f $@ ++ @$(AR) cr $@ hostapd_multi.o $(OBJS) ++ + hostapd: $(BCHECK) $(OBJS) + $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) + @$(E) " LD " $@ +@@ -928,6 +939,12 @@ HOBJS += ../src/crypto/aes-internal.o + HOBJS += ../src/crypto/aes-internal-enc.o + endif + ++dump_cflags: ++ @echo -n $(CFLAGS) " " ++ ++dump_ldflags: ++ @echo -n $(LDFLAGS) $(LIBS) $(EXTRALIBS) " " ++ + nt_password_hash: $(NOBJS) + $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n) + @$(E) " LD " $@ +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -14,6 +14,7 @@ CFLAGS += -I../src + CFLAGS += -I../src/utils + + -include .config ++-include $(if $(MULTICALL),../hostapd/.config) + + BINALL=wpa_supplicant wpa_cli + +@@ -727,6 +728,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS + CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS + LIBS += -ldl -rdynamic + endif ++else ++ ifdef MULTICALL ++ OBJS += ../src/eap_common/eap_common.o ++ endif + endif + + ifdef CONFIG_AP +@@ -735,9 +740,11 @@ NEED_EAP_COMMON=y + NEED_RSN_AUTHENTICATOR=y + CFLAGS += -DCONFIG_AP + OBJS += ap.o ++ifndef MULTICALL + CFLAGS += -DCONFIG_NO_RADIUS + CFLAGS += -DCONFIG_NO_ACCOUNTING + CFLAGS += -DCONFIG_NO_VLAN ++endif + OBJS += ../src/ap/hostapd.o + OBJS += ../src/ap/wpa_auth_glue.o + OBJS += ../src/ap/utils.o +@@ -799,10 +806,18 @@ endif + ifdef CONFIG_HS20 + OBJS += ../src/ap/hs20.o + endif ++else ++ ifdef MULTICALL ++ OBJS += ../src/eap_server/eap_server.o ++ OBJS += ../src/eap_server/eap_server_identity.o ++ OBJS += ../src/eap_server/eap_server_methods.o ++ endif + endif + + ifdef NEED_RSN_AUTHENTICATOR ++ifndef MULTICALL + CFLAGS += -DCONFIG_NO_RADIUS ++endif + NEED_AES_WRAP=y + OBJS += ../src/ap/wpa_auth.o + OBJS += ../src/ap/wpa_auth_ie.o +@@ -1551,6 +1566,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) + + $(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config + ++wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs) ++ $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c ++ @$(E) " CC " $< ++ @rm -f $@ ++ @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) ++ + wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) + $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) + @$(E) " LD " $@ +@@ -1625,6 +1646,12 @@ eap_eke.so: ../src/eap_peer/eap_eke.c .. + %@.service: %.service.arg.in + sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ + ++dump_cflags: ++ @echo -n $(CFLAGS) " " ++ ++dump_ldflags: ++ @echo -n $(LDFLAGS) $(LIBS) $(EXTRALIBS) " " ++ + wpa_supplicant.exe: wpa_supplicant + mv -f $< $@ + wpa_cli.exe: wpa_cli +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -4079,8 +4079,8 @@ union wpa_event_data { + * Driver wrapper code should call this function whenever an event is received + * from the driver. + */ +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data); ++extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + + /* +--- a/src/ap/drv_callbacks.c ++++ b/src/ap/drv_callbacks.c +@@ -844,8 +844,8 @@ static void hostapd_event_dfs_nop_finish + #endif /* NEED_AP_MLME */ + + +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data) ++void hostapd_wpa_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data) + { + struct hostapd_data *hapd = ctx; + #ifndef CONFIG_NO_STDOUT_DEBUG +--- a/wpa_supplicant/wpa_priv.c ++++ b/wpa_supplicant/wpa_priv.c +@@ -817,8 +817,8 @@ static void wpa_priv_send_ft_response(st + } + + +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data) ++static void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data) + { + struct wpa_priv_interface *iface = ctx; + +@@ -960,6 +960,7 @@ int main(int argc, char *argv[]) + if (os_program_init()) + return -1; + ++ wpa_supplicant_event = supplicant_event; + wpa_priv_fd_workaround(); + + for (;;) { +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -2710,8 +2710,8 @@ static void wpa_supplicant_update_channe + } + + +-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, +- union wpa_event_data *data) ++void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data) + { + struct wpa_supplicant *wpa_s = ctx; + +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -3138,6 +3138,9 @@ static void wpa_supplicant_deinit_iface( + os_free(wpa_s); + } + ++extern void supplicant_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++ + + /** + * wpa_supplicant_add_iface - Add a new network interface +@@ -3329,6 +3332,7 @@ struct wpa_global * wpa_supplicant_init( + wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); + #endif /* CONFIG_NO_WPA_MSG */ + ++ wpa_supplicant_event = supplicant_event; + wpa_debug_open_file(params->wpa_debug_file_path); + if (params->wpa_debug_syslog) + wpa_debug_open_syslog(); +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -511,6 +511,9 @@ static int hostapd_get_ctrl_iface_group( + return 0; + } + ++void hostapd_wpa_event(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); ++ + + int main(int argc, char *argv[]) + { +@@ -541,6 +544,7 @@ int main(int argc, char *argv[]) + interfaces.global_iface_name = NULL; + interfaces.global_ctrl_sock = -1; + ++ wpa_supplicant_event = hostapd_wpa_event; + for (;;) { + c = getopt(argc, argv, "b:Bde:f:hKP:Ttvg:G:"); + if (c < 0) +--- a/src/drivers/drivers.c ++++ b/src/drivers/drivers.c +@@ -7,7 +7,11 @@ + */ + + #include "includes.h" ++#include "common.h" ++#include "driver.h" + ++void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, ++ union wpa_event_data *data); + + #ifdef CONFIG_DRIVER_WEXT + extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */ diff --git a/package/network/services/hostapd/patches/300-nl80211_multicall_fixes.patch b/package/network/services/hostapd/patches/300-nl80211_multicall_fixes.patch deleted file mode 100644 index b351534073..0000000000 --- a/package/network/services/hostapd/patches/300-nl80211_multicall_fixes.patch +++ /dev/null @@ -1,101 +0,0 @@ ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -754,7 +754,6 @@ nla_put_failure: - } - - --#ifndef HOSTAPD - static int nl80211_get_macaddr(struct i802_bss *bss) - { - struct nl_msg *msg; -@@ -776,7 +775,6 @@ nla_put_failure: - nlmsg_free(msg); - return NL80211_IFTYPE_UNSPECIFIED; - } --#endif /* HOSTAPD */ - - - static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv, -@@ -3613,6 +3611,7 @@ static void * wpa_driver_nl80211_init(vo - drv->monitor_sock = -1; - drv->eapol_tx_sock = -1; - drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED; -+ drv->nlmode = NL80211_IFTYPE_STATION; - - if (wpa_driver_nl80211_init_nl(drv)) { - os_free(drv); -@@ -4003,31 +4002,16 @@ static int i802_set_iface_flags(struct i - - - static int --wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv) -+wpa_driver_nl80211_finish_drv_init_sta(struct wpa_driver_nl80211_data *drv, -+ int *send_rfkill_event) - { --#ifndef HOSTAPD - enum nl80211_iftype nlmode = NL80211_IFTYPE_STATION; --#endif /* HOSTAPD */ - struct i802_bss *bss = &drv->first_bss; -- int send_rfkill_event = 0; - int dynamic_if; - -- drv->ifindex = if_nametoindex(bss->ifname); -- bss->ifindex = drv->ifindex; -- bss->wdev_id = drv->global->if_add_wdevid; -- bss->wdev_id_set = drv->global->if_add_wdevid_set; -- - dynamic_if = drv->ifindex == drv->global->if_add_ifindex; - dynamic_if = dynamic_if || drv->global->if_add_wdevid_set; -- drv->global->if_add_wdevid_set = 0; - -- if (wpa_driver_nl80211_capa(drv)) -- return -1; -- -- wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s", -- bss->ifname, drv->phyname); -- --#ifndef HOSTAPD - if (dynamic_if) - nlmode = nl80211_get_ifmode(bss); - -@@ -4056,7 +4040,7 @@ wpa_driver_nl80211_finish_drv_init(struc - "interface '%s' due to rfkill", - bss->ifname); - drv->if_disabled = 1; -- send_rfkill_event = 1; -+ *send_rfkill_event = 1; - } else { - wpa_printf(MSG_ERROR, "nl80211: Could not set " - "interface '%s' UP", bss->ifname); -@@ -4066,7 +4050,30 @@ wpa_driver_nl80211_finish_drv_init(struc - - netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, - 1, IF_OPER_DORMANT); --#endif /* HOSTAPD */ -+ return 0; -+} -+ -+static int -+wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv) -+{ -+ struct i802_bss *bss = &drv->first_bss; -+ int send_rfkill_event = 0; -+ -+ drv->ifindex = if_nametoindex(bss->ifname); -+ bss->ifindex = drv->ifindex; -+ bss->wdev_id = drv->global->if_add_wdevid; -+ bss->wdev_id_set = drv->global->if_add_wdevid_set; -+ drv->global->if_add_wdevid_set = 0; -+ -+ if (wpa_driver_nl80211_capa(drv)) -+ return -1; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s", -+ bss->ifname, drv->phyname); -+ -+ if (drv->nlmode == NL80211_IFTYPE_STATION && -+ wpa_driver_nl80211_finish_drv_init_sta(drv, &send_rfkill_event)) -+ return -1; - - if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, - bss->addr)) diff --git a/package/network/services/hostapd/patches/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch new file mode 100644 index 0000000000..17e766161c --- /dev/null +++ b/package/network/services/hostapd/patches/300-noscan.patch @@ -0,0 +1,32 @@ +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2412,6 +2412,8 @@ static int hostapd_config_fill(struct ho + } + #endif /* CONFIG_IEEE80211W */ + #ifdef CONFIG_IEEE80211N ++ } else if (os_strcmp(buf, "noscan") == 0) { ++ conf->noscan = atoi(pos); + } else if (os_strcmp(buf, "ieee80211n") == 0) { + conf->ieee80211n = atoi(pos); + } else if (os_strcmp(buf, "ht_capab") == 0) { +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -527,6 +527,7 @@ struct hostapd_config { + + int ht_op_mode_fixed; + u16 ht_capab; ++ int noscan; + int ieee80211n; + int secondary_channel; + int require_ht; +--- a/src/ap/hw_features.c ++++ b/src/ap/hw_features.c +@@ -577,7 +577,7 @@ static int ieee80211n_check_40mhz(struct + { + struct wpa_driver_scan_params params; + +- if (!iface->conf->secondary_channel) ++ if (!iface->conf->secondary_channel || iface->conf->noscan) + return 0; /* HT40 not used */ + + hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); diff --git a/package/network/services/hostapd/patches/310-multicall_bridge_fix.patch b/package/network/services/hostapd/patches/310-multicall_bridge_fix.patch deleted file mode 100644 index a4f9a00e00..0000000000 --- a/package/network/services/hostapd/patches/310-multicall_bridge_fix.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -1095,6 +1095,10 @@ static void wpa_driver_nl80211_event_rtm - return; - } - -+ if (ifi->ifi_family == AF_BRIDGE && -+ drv->nlmode != NL80211_IFTYPE_AP) -+ return; -+ - wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x " - "(%s%s%s%s)", - drv->operstate, ifi->ifi_flags, -@@ -1202,6 +1206,10 @@ static void wpa_driver_nl80211_event_rtm - attrlen = len; - attr = (struct rtattr *) buf; - -+ if (ifi->ifi_family == AF_BRIDGE && -+ drv->nlmode != NL80211_IFTYPE_AP) -+ return; -+ - rta_len = RTA_ALIGN(sizeof(struct rtattr)); - while (RTA_OK(attr, attrlen)) { - if (attr->rta_type == IFLA_IFNAME) { -@@ -3613,6 +3621,11 @@ static void * wpa_driver_nl80211_init(vo - drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED; - drv->nlmode = NL80211_IFTYPE_STATION; - -+#ifdef HOSTAPD -+ drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int); -+ drv->if_indices = drv->default_if_indices; -+#endif -+ - if (wpa_driver_nl80211_init_nl(drv)) { - os_free(drv); - return NULL; -@@ -8845,8 +8858,6 @@ static void *i802_init(struct hostapd_da - br_ifindex = 0; - } - -- drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int); -- drv->if_indices = drv->default_if_indices; - for (i = 0; i < params->num_bridge; i++) { - if (params->bridge[i]) { - ifindex = if_nametoindex(params->bridge[i]); diff --git a/package/network/services/hostapd/patches/310-rescan_immediately.patch b/package/network/services/hostapd/patches/310-rescan_immediately.patch new file mode 100644 index 0000000000..043f07c627 --- /dev/null +++ b/package/network/services/hostapd/patches/310-rescan_immediately.patch @@ -0,0 +1,11 @@ +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -2488,7 +2488,7 @@ static struct wpa_supplicant * wpa_suppl + if (wpa_s == NULL) + return NULL; + wpa_s->scan_req = INITIAL_SCAN_REQ; +- wpa_s->scan_interval = 5; ++ wpa_s->scan_interval = 1; + wpa_s->new_connection = 1; + wpa_s->parent = wpa_s; + wpa_s->sched_scanning = 0; diff --git a/package/network/services/hostapd/patches/320-madwifi_key_fixes.patch b/package/network/services/hostapd/patches/320-madwifi_key_fixes.patch deleted file mode 100644 index 45a7ac6c83..0000000000 --- a/package/network/services/hostapd/patches/320-madwifi_key_fixes.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/src/drivers/driver_madwifi.c -+++ b/src/drivers/driver_madwifi.c -@@ -453,7 +453,9 @@ wpa_driver_madwifi_set_key(const char *i - - memset(&wk, 0, sizeof(wk)); - wk.ik_type = cipher; -- wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; -+ wk.ik_flags = IEEE80211_KEY_RECV; -+ if (set_tx) -+ wk.ik_flags |= IEEE80211_KEY_XMIT; - if (addr == NULL || is_broadcast_ether_addr(addr)) { - memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); - wk.ik_keyix = key_idx; -@@ -465,6 +467,20 @@ wpa_driver_madwifi_set_key(const char *i - wk.ik_keylen = key_len; - memcpy(wk.ik_keydata, key, key_len); - -+#ifdef WORDS_BIGENDIAN -+#define WPA_KEY_RSC_LEN 8 -+ { -+ size_t i; -+ u8 tmp[WPA_KEY_RSC_LEN]; -+ os_memset(tmp, 0, sizeof(tmp)); -+ for (i = 0; i < seq_len; i++) -+ tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i]; -+ os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN); -+ } -+#else /* WORDS_BIGENDIAN */ -+ os_memcpy(&wk.ik_keyrsc, seq, seq_len); -+#endif /* WORDS_BIGENDIAN */ -+ - ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); - if (ret < 0) { - wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" diff --git a/package/network/services/hostapd/patches/320-optional_rfkill.patch b/package/network/services/hostapd/patches/320-optional_rfkill.patch new file mode 100644 index 0000000000..7ec51b1027 --- /dev/null +++ b/package/network/services/hostapd/patches/320-optional_rfkill.patch @@ -0,0 +1,261 @@ +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -254,7 +254,9 @@ struct wpa_driver_nl80211_data { + int if_removed; + int if_disabled; + int ignore_if_down_event; ++#ifdef CONFIG_RFKILL + struct rfkill_data *rfkill; ++#endif + struct wpa_driver_capa capa; + u8 *extended_capa, *extended_capa_mask; + unsigned int extended_capa_len; +@@ -3630,7 +3632,7 @@ static int wpa_driver_nl80211_init_nl(st + return 0; + } + +- ++#ifdef CONFIG_RFKILL + static void wpa_driver_nl80211_rfkill_blocked(void *ctx) + { + wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked"); +@@ -3652,6 +3654,7 @@ static void wpa_driver_nl80211_rfkill_un + } + /* rtnetlink ifup handler will report interface as enabled */ + } ++#endif /* CONFIG_RFKILL */ + + + static void wpa_driver_nl80211_handle_eapol_tx_status(int sock, +@@ -3740,7 +3743,9 @@ static void * wpa_driver_nl80211_drv_ini + const u8 *set_addr) + { + struct wpa_driver_nl80211_data *drv; ++#ifdef CONFIG_RFKILL + struct rfkill_config *rcfg; ++#endif + struct i802_bss *bss; + + if (global_priv == NULL) +@@ -3778,6 +3783,7 @@ static void * wpa_driver_nl80211_drv_ini + if (nl80211_init_bss(bss)) + goto failed; + ++#ifdef CONFIG_RFKILL + rcfg = os_zalloc(sizeof(*rcfg)); + if (rcfg == NULL) + goto failed; +@@ -3790,6 +3796,7 @@ static void * wpa_driver_nl80211_drv_ini + wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available"); + os_free(rcfg); + } ++#endif /* CONFIG_RFKILL */ + + if (linux_iface_up(drv->global->ioctl_sock, ifname) > 0) + drv->start_iface_up = 1; +@@ -4116,10 +4123,12 @@ static void nl80211_mgmt_unsubscribe(str + } + + ++#ifdef CONFIG_RFKILL + static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx) + { + wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL); + } ++#endif /* CONFIG_RFKILL */ + + + static void nl80211_del_p2pdev(struct i802_bss *bss) +@@ -4246,13 +4255,16 @@ wpa_driver_nl80211_finish_drv_init(struc + } + + if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1)) { ++#ifdef CONFIG_RFKILL + if (rfkill_is_blocked(drv->rfkill)) { + wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable " + "interface '%s' due to rfkill", + bss->ifname); + drv->if_disabled = 1; + send_rfkill_event = 1; +- } else { ++ } else ++#endif ++ { + wpa_printf(MSG_ERROR, "nl80211: Could not set " + "interface '%s' UP", bss->ifname); + return -1; +@@ -4268,8 +4280,10 @@ wpa_driver_nl80211_finish_drv_init(struc + return -1; + + if (send_rfkill_event) { ++#ifdef CONFIG_RFKILL + eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill, + drv, drv->ctx); ++#endif + } + + return 0; +@@ -4347,7 +4361,9 @@ static void wpa_driver_nl80211_deinit(st + + netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0, + IF_OPER_UP); ++#ifdef CONFIG_RFKILL + rfkill_deinit(drv->rfkill); ++#endif + + eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx); + +--- a/src/drivers/driver_wext.c ++++ b/src/drivers/driver_wext.c +@@ -740,7 +740,7 @@ static void wpa_driver_wext_event_rtm_de + } + } + +- ++#ifdef CONFIG_RFKILL + static void wpa_driver_wext_rfkill_blocked(void *ctx) + { + wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked"); +@@ -762,7 +762,7 @@ static void wpa_driver_wext_rfkill_unblo + } + /* rtnetlink ifup handler will report interface as enabled */ + } +- ++#endif /* CONFIG_RFKILL */ + + static void wext_get_phy_name(struct wpa_driver_wext_data *drv) + { +@@ -808,7 +808,9 @@ void * wpa_driver_wext_init(void *ctx, c + { + struct wpa_driver_wext_data *drv; + struct netlink_config *cfg; ++#ifdef CONFIG_RFKILL + struct rfkill_config *rcfg; ++#endif + char path[128]; + struct stat buf; + +@@ -843,6 +845,7 @@ void * wpa_driver_wext_init(void *ctx, c + goto err2; + } + ++#ifdef CONFIG_RFKILL + rcfg = os_zalloc(sizeof(*rcfg)); + if (rcfg == NULL) + goto err3; +@@ -855,6 +858,7 @@ void * wpa_driver_wext_init(void *ctx, c + wpa_printf(MSG_DEBUG, "WEXT: RFKILL status not available"); + os_free(rcfg); + } ++#endif /* CONFIG_RFKILL */ + + drv->mlme_sock = -1; + +@@ -872,7 +876,9 @@ void * wpa_driver_wext_init(void *ctx, c + return drv; + + err3: ++#ifdef CONFIG_RFKILL + rfkill_deinit(drv->rfkill); ++#endif + netlink_deinit(drv->netlink); + err2: + close(drv->ioctl_sock); +@@ -882,10 +888,12 @@ err1: + } + + ++#ifdef CONFIG_RFKILL + static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void *timeout_ctx) + { + wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL); + } ++#endif /* CONFIG_RFKILL */ + + + static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv) +@@ -893,13 +901,16 @@ static int wpa_driver_wext_finish_drv_in + int send_rfkill_event = 0; + + if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) { ++#ifdef CONFIG_RFKILL + if (rfkill_is_blocked(drv->rfkill)) { + wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable " + "interface '%s' due to rfkill", + drv->ifname); + drv->if_disabled = 1; + send_rfkill_event = 1; +- } else { ++ } else ++#endif ++ { + wpa_printf(MSG_ERROR, "WEXT: Could not set " + "interface '%s' UP", drv->ifname); + return -1; +@@ -947,8 +958,10 @@ static int wpa_driver_wext_finish_drv_in + 1, IF_OPER_DORMANT); + + if (send_rfkill_event) { ++#ifdef CONFIG_RFKILL + eloop_register_timeout(0, 0, wpa_driver_wext_send_rfkill, + drv, drv->ctx); ++#endif + } + + return 0; +@@ -978,7 +991,9 @@ void wpa_driver_wext_deinit(void *priv) + + netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP); + netlink_deinit(drv->netlink); ++#ifdef CONFIG_RFKILL + rfkill_deinit(drv->rfkill); ++#endif + + if (drv->mlme_sock >= 0) + eloop_unregister_read_sock(drv->mlme_sock); +--- a/src/drivers/drivers.mak ++++ b/src/drivers/drivers.mak +@@ -25,7 +25,6 @@ NEED_SME=y + NEED_AP_MLME=y + NEED_NETLINK=y + NEED_LINUX_IOCTL=y +-NEED_RFKILL=y + + ifdef CONFIG_LIBNL32 + DRV_LIBS += -lnl-3 +@@ -109,7 +108,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT + CONFIG_WIRELESS_EXTENSION=y + NEED_NETLINK=y + NEED_LINUX_IOCTL=y +-NEED_RFKILL=y + endif + + ifdef CONFIG_DRIVER_NDIS +@@ -135,7 +133,6 @@ endif + ifdef CONFIG_WIRELESS_EXTENSION + DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION + DRV_WPA_OBJS += ../src/drivers/driver_wext.o +-NEED_RFKILL=y + endif + + ifdef NEED_NETLINK +@@ -148,6 +145,7 @@ endif + + ifdef NEED_RFKILL + DRV_OBJS += ../src/drivers/rfkill.o ++DRV_WPA_CFLAGS += -DCONFIG_RFKILL + endif + + ifdef CONFIG_VLAN_NETLINK +--- a/src/drivers/driver_wext.h ++++ b/src/drivers/driver_wext.h +@@ -22,7 +22,9 @@ struct wpa_driver_wext_data { + int ifindex2; + int if_removed; + int if_disabled; ++#ifdef CONFIG_RFKILL + struct rfkill_data *rfkill; ++#endif + u8 *assoc_req_ies; + size_t assoc_req_ies_len; + u8 *assoc_resp_ies; diff --git a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch new file mode 100644 index 0000000000..a505a6089d --- /dev/null +++ b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch @@ -0,0 +1,20 @@ +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -6860,7 +6860,7 @@ static int wpa_driver_nl80211_set_freq(s + + nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY); + +- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); ++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex); + if (nl80211_put_freq_params(msg, freq) < 0) + goto nla_put_failure; + +@@ -11322,7 +11322,7 @@ static int nl80211_switch_channel(void * + return -ENOMEM; + + nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH); +- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); ++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex); + NLA_PUT_U32(msg, NL80211_ATTR_CH_SWITCH_COUNT, settings->cs_count); + ret = nl80211_put_freq_params(msg, &settings->freq_params); + if (ret) diff --git a/package/network/services/hostapd/patches/340-reload_freq_change.patch b/package/network/services/hostapd/patches/340-reload_freq_change.patch new file mode 100644 index 0000000000..d36b0460fa --- /dev/null +++ b/package/network/services/hostapd/patches/340-reload_freq_change.patch @@ -0,0 +1,19 @@ +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -72,6 +72,16 @@ static void hostapd_reload_bss(struct ho + #endif /* CONFIG_NO_RADIUS */ + + ssid = &hapd->conf->ssid; ++ ++ hostapd_set_freq(hapd, hapd->iconf->hw_mode, hapd->iface->freq, ++ hapd->iconf->channel, ++ hapd->iconf->ieee80211n, ++ hapd->iconf->ieee80211ac, ++ hapd->iconf->secondary_channel, ++ hapd->iconf->vht_oper_chwidth, ++ hapd->iconf->vht_oper_centr_freq_seg0_idx, ++ hapd->iconf->vht_oper_centr_freq_seg1_idx); ++ + if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && + ssid->wpa_passphrase_set && ssid->wpa_passphrase) { + /* diff --git a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch new file mode 100644 index 0000000000..885922cdf1 --- /dev/null +++ b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch @@ -0,0 +1,50 @@ +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -4290,18 +4290,20 @@ wpa_driver_nl80211_finish_drv_init(struc + } + + +-static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv) ++static int wpa_driver_nl80211_del_bss_beacon(struct i802_bss *bss) + { ++ struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + + msg = nlmsg_alloc(); + if (!msg) + return -ENOMEM; + ++ bss->beacon_set = 0; + wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", +- drv->ifindex); ++ bss->ifindex); + nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_BEACON); +- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); ++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex); + + return send_and_recv_msgs(drv, msg, NULL, NULL); + nla_put_failure: +@@ -4309,6 +4311,15 @@ static int wpa_driver_nl80211_del_beacon + return -ENOBUFS; + } + ++static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv) ++{ ++ struct i802_bss *bss; ++ ++ for (bss = drv->first_bss; bss; bss = bss->next) ++ wpa_driver_nl80211_del_bss_beacon(bss); ++ ++ return 0; ++} + + /** + * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface +@@ -9911,7 +9922,6 @@ static int wpa_driver_nl80211_stop_ap(vo + if (!is_ap_interface(drv->nlmode)) + return -1; + wpa_driver_nl80211_del_beacon(drv); +- bss->beacon_set = 0; + return 0; + } + diff --git a/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch new file mode 100644 index 0000000000..170d4f2f0c --- /dev/null +++ b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch @@ -0,0 +1,98 @@ +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -34,6 +34,7 @@ + #include "wps/wps.h" + #include "config_file.h" + #include "ctrl_iface.h" ++#include "config_file.h" + + + struct wpa_ctrl_dst { +@@ -44,6 +45,7 @@ struct wpa_ctrl_dst { + int errors; + }; + ++static char *reload_opts = NULL; + + static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level, + const char *buf, size_t len); +@@ -153,6 +155,68 @@ static int hostapd_ctrl_iface_new_sta(st + return 0; + } + ++static int hostapd_ctrl_iface_set_down(struct hostapd_data *hapd) ++{ ++ if (hapd->driver->stop_ap) ++ hapd->driver->stop_ap(hapd->drv_priv); ++ return 0; ++} ++ ++static char *get_option(char *opt, char *str) ++{ ++ int len = strlen(str); ++ ++ if (!strncmp(opt, str, len)) ++ return opt + len; ++ else ++ return NULL; ++} ++ ++static struct hostapd_config *hostapd_ctrl_iface_config_read(const char *fname) ++{ ++ struct hostapd_config *conf; ++ char *opt, *val; ++ ++ conf = hostapd_config_read(fname); ++ if (!conf) ++ return NULL; ++ ++ for (opt = strtok(reload_opts, " "); ++ opt; ++ opt = strtok(NULL, " ")) { ++ ++ if ((val = get_option(opt, "channel="))) ++ conf->channel = atoi(val); ++ else if ((val = get_option(opt, "ht_capab="))) ++ conf->ht_capab = atoi(val); ++ else if ((val = get_option(opt, "ht_capab_mask="))) ++ conf->ht_capab &= atoi(val); ++ else if ((val = get_option(opt, "sec_chan="))) ++ conf->secondary_channel = atoi(val); ++ else if ((val = get_option(opt, "hw_mode="))) ++ conf->hw_mode = atoi(val); ++ else if ((val = get_option(opt, "ieee80211n="))) ++ conf->ieee80211n = atoi(val); ++ else ++ break; ++ } ++ ++ return conf; ++} ++ ++static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt) ++{ ++ struct hostapd_config * (*config_read_cb)(const char *config_fname); ++ struct hostapd_iface *iface = hapd->iface; ++ ++ config_read_cb = iface->interfaces->config_read_cb; ++ iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; ++ reload_opts = txt; ++ ++ hostapd_reload_config(iface); ++ ++ iface->interfaces->config_read_cb = config_read_cb; ++} + + #ifdef CONFIG_IEEE80211W + #ifdef NEED_AP_MLME +@@ -1199,6 +1263,10 @@ static void hostapd_ctrl_iface_receive(i + reply_len += res; + } + #endif /* CONFIG_NO_RADIUS */ ++ } else if (os_strcmp(buf, "DOWN") == 0) { ++ hostapd_ctrl_iface_set_down(hapd); ++ } else if (os_strncmp(buf, "UPDATE ", 7) == 0) { ++ hostapd_ctrl_iface_update(hapd, buf + 7); + } else if (os_strcmp(buf, "STA-FIRST") == 0) { + reply_len = hostapd_ctrl_iface_sta_first(hapd, reply, + reply_size); diff --git a/package/network/services/hostapd/patches/370-ap_sta_support.patch b/package/network/services/hostapd/patches/370-ap_sta_support.patch new file mode 100644 index 0000000000..95bde3f659 --- /dev/null +++ b/package/network/services/hostapd/patches/370-ap_sta_support.patch @@ -0,0 +1,210 @@ +--- a/wpa_supplicant/wpa_supplicant_i.h ++++ b/wpa_supplicant/wpa_supplicant_i.h +@@ -96,6 +96,11 @@ struct wpa_interface { + const char *ifname; + + /** ++ * hostapd_ctrl - path to hostapd control socket for notification ++ */ ++ const char *hostapd_ctrl; ++ ++ /** + * bridge_ifname - Optional bridge interface name + * + * If the driver interface (ifname) is included in a Linux bridge +@@ -325,6 +330,8 @@ struct wpa_supplicant { + #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ + char bridge_ifname[16]; + ++ struct wpa_ctrl *hostapd; ++ + char *confname; + char *confanother; + struct wpa_config *conf; +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -13,6 +13,10 @@ PKG_CONFIG ?= pkg-config + CFLAGS += -I../src + CFLAGS += -I../src/utils + ++ifdef MULTICALL ++CFLAGS += -DMULTICALL ++endif ++ + -include .config + -include $(if $(MULTICALL),../hostapd/.config) + +@@ -76,6 +80,8 @@ OBJS_c = wpa_cli.o ../src/common/wpa_ctr + OBJS_c += ../src/utils/wpa_debug.o + OBJS_c += ../src/utils/common.o + ++OBJS += ../src/common/wpa_ctrl.o ++ + ifndef CONFIG_OS + ifdef CONFIG_NATIVE_WINDOWS + CONFIG_OS=win32 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -109,6 +109,46 @@ extern int wpa_debug_show_keys; + extern int wpa_debug_timestamp; + extern struct wpa_driver_ops *wpa_drivers[]; + ++static int hostapd_stop(struct wpa_supplicant *wpa_s) ++{ ++ const char *cmd = "DOWN"; ++ char buf[256]; ++ int len = sizeof(buf); ++ ++ if (wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL) < 0) { ++ wpa_printf(MSG_ERROR, "\nFailed to stop hostapd AP interfaces\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++static int hostapd_reload(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) ++{ ++ char *cmd = NULL; ++ char buf[256]; ++ int len = sizeof(buf); ++ enum hostapd_hw_mode hw_mode; ++ u8 channel; ++ int ret; ++ ++ if (!bss) ++ return; ++ ++ hw_mode = ieee80211_freq_to_chan(bss->freq, &channel); ++ if (asprintf(&cmd, "UPDATE channel=%d sec_chan=0 hw_mode=%d ieee80211n=%d", ++ channel, hw_mode, !!bss->ht_capab) < 0) ++ return -1; ++ ++ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); ++ free(cmd); ++ ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); ++ return -1; ++ } ++ return 0; ++} ++ + /* Configure default/group WEP keys for static WEP */ + int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + { +@@ -685,8 +725,12 @@ void wpa_supplicant_set_state(struct wpa + #endif /* CONFIG_P2P */ + + sme_sched_obss_scan(wpa_s, 1); ++ if (wpa_s->hostapd) ++ hostapd_reload(wpa_s, wpa_s->current_bss); + } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || + state == WPA_ASSOCIATED) { ++ if (wpa_s->hostapd) ++ hostapd_stop(wpa_s); + wpa_s->new_connection = 1; + wpa_drv_set_operstate(wpa_s, 0); + #ifndef IEEE8021X_EAPOL +@@ -2906,6 +2950,20 @@ static int wpa_supplicant_init_iface(str + sizeof(wpa_s->bridge_ifname)); + } + ++ if (iface->hostapd_ctrl) { ++ char *cmd = "DOWN"; ++ char buf[256]; ++ int len = sizeof(buf); ++ ++ wpa_s->hostapd = wpa_ctrl_open(iface->hostapd_ctrl); ++ if (!wpa_s->hostapd) { ++ wpa_printf(MSG_ERROR, "\nFailed to connect to hostapd\n"); ++ return -1; ++ } ++ if (hostapd_stop(wpa_s) < 0) ++ return -1; ++ } ++ + /* RSNA Supplicant Key Management - INITIALIZE */ + eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); + eapol_sm_notify_portValid(wpa_s->eapol, FALSE); +--- a/wpa_supplicant/bss.c ++++ b/wpa_supplicant/bss.c +@@ -11,6 +11,7 @@ + #include "utils/common.h" + #include "utils/eloop.h" + #include "common/ieee802_11_defs.h" ++#include "common/ieee802_11_common.h" + #include "drivers/driver.h" + #include "wpa_supplicant_i.h" + #include "config.h" +@@ -245,6 +246,9 @@ static void calculate_update_time(const + static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, + struct os_time *fetch_time) + { ++ struct ieee80211_ht_capabilities *capab; ++ struct ieee802_11_elems elems; ++ + dst->flags = src->flags; + os_memcpy(dst->bssid, src->bssid, ETH_ALEN); + dst->freq = src->freq; +@@ -255,6 +259,12 @@ static void wpa_bss_copy_res(struct wpa_ + dst->level = src->level; + dst->tsf = src->tsf; + ++ memset(&elems, 0, sizeof(elems)); ++ ieee802_11_parse_elems((u8 *) (src + 1), src->ie_len, &elems, 0); ++ capab = (struct ieee80211_ht_capabilities *) elems.ht_capabilities; ++ if (capab) ++ dst->ht_capab = le_to_host16(capab->ht_capabilities_info); ++ + calculate_update_time(fetch_time, src->age, &dst->last_update); + } + +--- a/wpa_supplicant/main.c ++++ b/wpa_supplicant/main.c +@@ -27,7 +27,7 @@ static void usage(void) + " wpa_supplicant [-BddhKLqqstuvW] [-P] " + "[-g] \\\n" + " [-G] \\\n" +- " -i -c [-C] [-D] " ++ " -i -c [-C] [-D] [-H] " + "[-p] \\\n" + " [-b] [-f] [-e] " + "\\\n" +@@ -72,6 +72,7 @@ static void usage(void) + #endif /* CONFIG_DEBUG_LINUX_TRACING */ + printf(" -t = include timestamp in debug messages\n" + " -h = show this help text\n" ++ " -H = connect to a hostapd instance to manage state changes\n" + " -L = show license (BSD)\n" + " -o = override driver parameter for new interfaces\n" + " -O = override ctrl_interface parameter for new interfaces\n" +@@ -160,7 +161,7 @@ int main(int argc, char *argv[]) + + for (;;) { + c = getopt(argc, argv, +- "b:Bc:C:D:de:f:g:G:hi:I:KLNo:O:p:P:qsTtuvW"); ++ "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuvW"); + if (c < 0) + break; + switch (c) { +@@ -207,6 +208,9 @@ int main(int argc, char *argv[]) + usage(); + exitcode = 0; + goto out; ++ case 'H': ++ iface->hostapd_ctrl = optarg; ++ break; + case 'i': + iface->ifname = optarg; + break; +--- a/wpa_supplicant/bss.h ++++ b/wpa_supplicant/bss.h +@@ -69,6 +69,8 @@ struct wpa_bss { + u8 ssid[32]; + /** Length of SSID */ + size_t ssid_len; ++ /** HT caapbilities */ ++ u16 ht_capab; + /** Frequency of the channel in MHz (e.g., 2412 = channel 1) */ + int freq; + /** Beacon interval in TUs (host byte order) */ diff --git a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch new file mode 100644 index 0000000000..27f21bdb8f --- /dev/null +++ b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch @@ -0,0 +1,168 @@ +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -144,6 +144,9 @@ endif + ifdef CONFIG_NO_CTRL_IFACE + CFLAGS += -DCONFIG_NO_CTRL_IFACE + else ++ifdef CONFIG_CTRL_IFACE_MIB ++CFLAGS += -DCONFIG_CTRL_IFACE_MIB ++endif + OBJS += ctrl_iface.o + OBJS += ../src/ap/ctrl_iface_ap.o + endif +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -1234,6 +1234,7 @@ static void hostapd_ctrl_iface_receive(i + } else if (os_strcmp(buf, "STATUS") == 0) { + reply_len = hostapd_ctrl_iface_status(hapd, reply, + reply_size); ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "MIB") == 0) { + reply_len = ieee802_11_get_mib(hapd, reply, reply_size); + if (reply_len >= 0) { +@@ -1263,10 +1264,12 @@ static void hostapd_ctrl_iface_receive(i + reply_len += res; + } + #endif /* CONFIG_NO_RADIUS */ ++#endif + } else if (os_strcmp(buf, "DOWN") == 0) { + hostapd_ctrl_iface_set_down(hapd); + } else if (os_strncmp(buf, "UPDATE ", 7) == 0) { + hostapd_ctrl_iface_update(hapd, buf + 7); ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "STA-FIRST") == 0) { + reply_len = hostapd_ctrl_iface_sta_first(hapd, reply, + reply_size); +@@ -1276,6 +1279,7 @@ static void hostapd_ctrl_iface_receive(i + } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { + reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, + reply_size); ++#endif + } else if (os_strcmp(buf, "ATTACH") == 0) { + if (hostapd_ctrl_iface_attach(hapd, &from, fromlen)) + reply_len = -1; +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -778,6 +778,9 @@ ifdef CONFIG_WNM + OBJS += ../src/ap/wnm_ap.o + endif + ifdef CONFIG_CTRL_IFACE ++ifdef CONFIG_CTRL_IFACE_MIB ++CFLAGS += -DCONFIG_CTRL_IFACE_MIB ++endif + OBJS += ../src/ap/ctrl_iface_ap.o + endif + +--- a/wpa_supplicant/ctrl_iface.c ++++ b/wpa_supplicant/ctrl_iface.c +@@ -5262,6 +5262,7 @@ char * wpa_supplicant_ctrl_iface_process + reply_len = -1; + } else if (os_strncmp(buf, "NOTE ", 5) == 0) { + wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "MIB") == 0) { + reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); + if (reply_len >= 0) { +@@ -5273,6 +5274,7 @@ char * wpa_supplicant_ctrl_iface_process + else + reply_len += res; + } ++#endif + } else if (os_strncmp(buf, "STATUS", 6) == 0) { + reply_len = wpa_supplicant_ctrl_iface_status( + wpa_s, buf + 6, reply, reply_size); +@@ -5687,6 +5689,7 @@ char * wpa_supplicant_ctrl_iface_process + reply_len = wpa_supplicant_ctrl_iface_bss( + wpa_s, buf + 4, reply, reply_size); + #ifdef CONFIG_AP ++#ifdef CONFIG_CTRL_IFACE_MIB + } else if (os_strcmp(buf, "STA-FIRST") == 0) { + reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); + } else if (os_strncmp(buf, "STA ", 4) == 0) { +@@ -5695,6 +5698,7 @@ char * wpa_supplicant_ctrl_iface_process + } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { + reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, + reply_size); ++#endif + } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { + if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15)) + reply_len = -1; +--- a/src/ap/ctrl_iface_ap.c ++++ b/src/ap/ctrl_iface_ap.c +@@ -20,6 +20,7 @@ + #include "ctrl_iface_ap.h" + #include "ap_drv_ops.h" + ++#ifdef CONFIG_CTRL_IFACE_MIB + + static int hostapd_get_sta_conn_time(struct sta_info *sta, + char *buf, size_t buflen) +@@ -129,6 +130,7 @@ int hostapd_ctrl_iface_sta_next(struct h + return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); + } + ++#endif + + #ifdef CONFIG_P2P_MANAGER + static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, +@@ -423,3 +425,4 @@ int hostapd_parse_csa_settings(const cha + + return 0; + } ++ +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -1938,6 +1938,7 @@ static const char * bool_txt(Boolean boo + return bool_val ? "TRUE" : "FALSE"; + } + ++#ifdef CONFIG_CTRL_IFACE_MIB + + int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) + { +@@ -2090,6 +2091,7 @@ int ieee802_1x_get_mib_sta(struct hostap + return len; + } + ++#endif + + static void ieee802_1x_finished(struct hostapd_data *hapd, + struct sta_info *sta, int success) +--- a/src/ap/wpa_auth.c ++++ b/src/ap/wpa_auth.c +@@ -2708,6 +2708,7 @@ static const char * wpa_bool_txt(int boo + return bool ? "TRUE" : "FALSE"; + } + ++#ifdef CONFIG_CTRL_IFACE_MIB + + #define RSN_SUITE "%02x-%02x-%02x-%d" + #define RSN_SUITE_ARG(s) \ +@@ -2852,7 +2853,7 @@ int wpa_get_mib_sta(struct wpa_state_mac + + return len; + } +- ++#endif + + void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) + { +--- a/src/rsn_supp/wpa.c ++++ b/src/rsn_supp/wpa.c +@@ -1844,6 +1844,8 @@ static u32 wpa_key_mgmt_suite(struct wpa + } + + ++#ifdef CONFIG_CTRL_IFACE_MIB ++ + #define RSN_SUITE "%02x-%02x-%02x-%d" + #define RSN_SUITE_ARG(s) \ + ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff +@@ -1927,6 +1929,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch + + return (int) len; + } ++#endif + #endif /* CONFIG_CTRL_IFACE */ + + diff --git a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch new file mode 100644 index 0000000000..00a32229d4 --- /dev/null +++ b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch @@ -0,0 +1,56 @@ +--- a/src/common/wpa_common.c ++++ b/src/common/wpa_common.c +@@ -959,6 +959,31 @@ const char * wpa_key_mgmt_txt(int key_mg + } + + ++static void wpa_fixup_wpa_ie_rsn(u8 *assoc_ie, const u8 *wpa_msg_ie, ++ size_t rsn_ie_len) ++{ ++ int pos, count; ++ ++ pos = sizeof(struct rsn_ie_hdr) + RSN_SELECTOR_LEN; ++ if (rsn_ie_len < pos + 2) ++ return; ++ ++ count = WPA_GET_LE16(wpa_msg_ie + pos); ++ pos += 2 + count * RSN_SELECTOR_LEN; ++ if (rsn_ie_len < pos + 2) ++ return; ++ ++ count = WPA_GET_LE16(wpa_msg_ie + pos); ++ pos += 2 + count * RSN_SELECTOR_LEN; ++ if (rsn_ie_len < pos + 2) ++ return; ++ ++ if (!assoc_ie[pos] && !assoc_ie[pos + 1] && ++ (wpa_msg_ie[pos] || wpa_msg_ie[pos + 1])) ++ memcpy(&assoc_ie[pos], &wpa_msg_ie[pos], 2); ++} ++ ++ + int wpa_compare_rsn_ie(int ft_initial_assoc, + const u8 *ie1, size_t ie1len, + const u8 *ie2, size_t ie2len) +@@ -966,8 +991,19 @@ int wpa_compare_rsn_ie(int ft_initial_as + if (ie1 == NULL || ie2 == NULL) + return -1; + +- if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0) +- return 0; /* identical IEs */ ++ if (ie1len == ie2len) { ++ u8 *ie_tmp; ++ ++ if (os_memcmp(ie1, ie2, ie1len) == 0) ++ return 0; /* identical IEs */ ++ ++ ie_tmp = alloca(ie1len); ++ memcpy(ie_tmp, ie1, ie1len); ++ wpa_fixup_wpa_ie_rsn(ie_tmp, ie2, ie1len); ++ ++ if (os_memcmp(ie_tmp, ie2, ie1len) == 0) ++ return 0; /* only mismatch in RSN capabilties */ ++ } + + #ifdef CONFIG_IEEE80211R + if (ft_initial_assoc) { diff --git a/package/network/services/hostapd/patches/400-noscan.patch b/package/network/services/hostapd/patches/400-noscan.patch deleted file mode 100644 index 2c580299a5..0000000000 --- a/package/network/services/hostapd/patches/400-noscan.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2477,6 +2477,8 @@ static int hostapd_config_fill(struct ho - } - #endif /* CONFIG_IEEE80211W */ - #ifdef CONFIG_IEEE80211N -+ } else if (os_strcmp(buf, "noscan") == 0) { -+ conf->noscan = atoi(pos); - } else if (os_strcmp(buf, "ieee80211n") == 0) { - conf->ieee80211n = atoi(pos); - } else if (os_strcmp(buf, "ht_capab") == 0) { ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -515,6 +515,7 @@ struct hostapd_config { - - int ht_op_mode_fixed; - u16 ht_capab; -+ int noscan; - int ieee80211n; - int secondary_channel; - int require_ht; ---- a/src/ap/hw_features.c -+++ b/src/ap/hw_features.c -@@ -494,7 +494,7 @@ static int ieee80211n_check_40mhz(struct - { - struct wpa_driver_scan_params params; - -- if (!iface->conf->secondary_channel) -+ if (!iface->conf->secondary_channel || iface->conf->noscan) - return 0; /* HT40 not used */ - - wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling " diff --git a/package/network/services/hostapd/patches/400-terminate_on_setup_failure.patch b/package/network/services/hostapd/patches/400-terminate_on_setup_failure.patch new file mode 100644 index 0000000000..1270861e1e --- /dev/null +++ b/package/network/services/hostapd/patches/400-terminate_on_setup_failure.patch @@ -0,0 +1,85 @@ +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -1100,13 +1100,8 @@ int hostapd_setup_interface_complete(str + size_t j; + u8 *prev_addr; + +- if (err) { +- wpa_printf(MSG_ERROR, "Interface initialization failed"); +- hostapd_set_state(iface, HAPD_IFACE_DISABLED); +- if (iface->interfaces && iface->interfaces->terminate_on_error) +- eloop_terminate(); +- return -1; +- } ++ if (err) ++ goto error; + + wpa_printf(MSG_DEBUG, "Completing interface initialization"); + if (iface->conf->channel) { +@@ -1137,7 +1132,7 @@ int hostapd_setup_interface_complete(str + hapd->iconf->vht_oper_centr_freq_seg1_idx)) { + wpa_printf(MSG_ERROR, "Could not set channel for " + "kernel driver"); +- return -1; ++ goto error; + } + } + +@@ -1148,7 +1143,7 @@ int hostapd_setup_interface_complete(str + hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_WARNING, + "Failed to prepare rates table."); +- return -1; ++ goto error; + } + } + +@@ -1156,14 +1151,14 @@ int hostapd_setup_interface_complete(str + hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) { + wpa_printf(MSG_ERROR, "Could not set RTS threshold for " + "kernel driver"); +- return -1; ++ goto error; + } + + if (hapd->iconf->fragm_threshold > -1 && + hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) { + wpa_printf(MSG_ERROR, "Could not set fragmentation threshold " + "for kernel driver"); +- return -1; ++ goto error; + } + + prev_addr = hapd->own_addr; +@@ -1173,7 +1168,7 @@ int hostapd_setup_interface_complete(str + if (j) + os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); + if (hostapd_setup_bss(hapd, j == 0)) +- return -1; ++ goto error; + if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) + prev_addr = hapd->own_addr; + } +@@ -1188,7 +1183,7 @@ int hostapd_setup_interface_complete(str + if (hostapd_driver_commit(hapd) < 0) { + wpa_printf(MSG_ERROR, "%s: Failed to commit driver " + "configuration", __func__); +- return -1; ++ goto error; + } + + /* +@@ -1213,6 +1208,13 @@ int hostapd_setup_interface_complete(str + iface->interfaces->terminate_on_error--; + + return 0; ++ ++error: ++ wpa_printf(MSG_ERROR, "Interface initialization failed"); ++ hostapd_set_state(iface, HAPD_IFACE_DISABLED); ++ if (iface->interfaces && iface->interfaces->terminate_on_error) ++ eloop_terminate(); ++ return -1; + } + + diff --git a/package/network/services/hostapd/patches/410-bring_down_interface.patch b/package/network/services/hostapd/patches/410-bring_down_interface.patch new file mode 100644 index 0000000000..31033a01a4 --- /dev/null +++ b/package/network/services/hostapd/patches/410-bring_down_interface.patch @@ -0,0 +1,25 @@ +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -8480,12 +8480,7 @@ static int wpa_driver_nl80211_set_mode(s + /* Try to set the mode again while the interface is + * down */ + ret = nl80211_set_mode(drv, drv->ifindex, nlmode); +- if (ret == -EACCES) +- break; +- res = i802_set_iface_flags(bss, 1); +- if (res && !ret) +- ret = -1; +- else if (ret != -EBUSY) ++ if (ret != -EBUSY) + break; + } else + wpa_printf(MSG_DEBUG, "nl80211: Failed to set " +@@ -8498,6 +8493,8 @@ static int wpa_driver_nl80211_set_mode(s + "interface is down"); + drv->nlmode = nlmode; + drv->ignore_if_down_event = 1; ++ if (i802_set_iface_flags(bss, 1)) ++ ret = -1; + } + + done: diff --git a/package/network/services/hostapd/patches/410-multicall.patch b/package/network/services/hostapd/patches/410-multicall.patch deleted file mode 100644 index 62d37cb6d8..0000000000 --- a/package/network/services/hostapd/patches/410-multicall.patch +++ /dev/null @@ -1,246 +0,0 @@ ---- a/hostapd/Makefile -+++ b/hostapd/Makefile -@@ -14,6 +14,7 @@ CFLAGS += -I../src/utils - # CFLAGS += -DUSE_KERNEL_HEADERS -I/usr/src/linux/include - - -include .config -+-include $(if $(MULTICALL), ../wpa_supplicant/.config) - - ifndef CONFIG_OS - ifdef CONFIG_NATIVE_WINDOWS -@@ -192,10 +193,14 @@ ifdef CONFIG_IEEE80211AC - CFLAGS += -DCONFIG_IEEE80211AC - endif - -+ifndef MULTICALL -+CFLAGS += -DNO_SUPPLICANT -+endif -+ - include ../src/drivers/drivers.mak --OBJS += $(DRV_AP_OBJS) --CFLAGS += $(DRV_AP_CFLAGS) --LDFLAGS += $(DRV_AP_LDFLAGS) -+OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS))) -+CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS)) -+LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS)) - LIBS += $(DRV_AP_LIBS) - - ifdef CONFIG_L2_PACKET -@@ -871,6 +876,12 @@ install: all - - BCHECK=../src/drivers/build.hostapd - -+hostapd_multi.a: $(BCHECK) $(OBJS) -+ $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c -+ @$(E) " CC " $< -+ @rm -f $@ -+ @$(AR) cr $@ hostapd_multi.o $(OBJS) -+ - hostapd: $(BCHECK) $(OBJS) - $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) - @$(E) " LD " $@ -@@ -909,6 +920,12 @@ HOBJS += ../src/crypto/aes-internal.o - HOBJS += ../src/crypto/aes-internal-enc.o - endif - -+dump_cflags: -+ @echo -n $(CFLAGS) " " -+ -+dump_ldflags: -+ @echo -n $(LDFLAGS) $(LIBS) $(EXTRALIBS) " " -+ - nt_password_hash: $(NOBJS) - $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n) - @$(E) " LD " $@ ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -14,6 +14,7 @@ CFLAGS += -I../src - CFLAGS += -I../src/utils - - -include .config -+-include $(if $(MULTICALL),../hostapd/.config) - - BINALL=wpa_supplicant wpa_cli - -@@ -720,6 +721,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS - CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS - LIBS += -ldl -rdynamic - endif -+else -+ ifdef MULTICALL -+ OBJS += ../src/eap_common/eap_common.o -+ endif - endif - - ifdef CONFIG_AP -@@ -728,9 +733,11 @@ NEED_EAP_COMMON=y - NEED_RSN_AUTHENTICATOR=y - CFLAGS += -DCONFIG_AP - OBJS += ap.o -+ifndef MULTICALL - CFLAGS += -DCONFIG_NO_RADIUS - CFLAGS += -DCONFIG_NO_ACCOUNTING - CFLAGS += -DCONFIG_NO_VLAN -+endif - OBJS += ../src/ap/hostapd.o - OBJS += ../src/ap/wpa_auth_glue.o - OBJS += ../src/ap/utils.o -@@ -785,10 +792,18 @@ endif - ifdef CONFIG_HS20 - OBJS += ../src/ap/hs20.o - endif -+else -+ ifdef MULTICALL -+ OBJS += ../src/eap_server/eap_server.o -+ OBJS += ../src/eap_server/eap_server_identity.o -+ OBJS += ../src/eap_server/eap_server_methods.o -+ endif - endif - - ifdef NEED_RSN_AUTHENTICATOR -+ifndef MULTICALL - CFLAGS += -DCONFIG_NO_RADIUS -+endif - NEED_AES_WRAP=y - OBJS += ../src/ap/wpa_auth.o - OBJS += ../src/ap/wpa_auth_ie.o -@@ -1537,6 +1552,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) - - $(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config - -+wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs) -+ $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c -+ @$(E) " CC " $< -+ @rm -f $@ -+ @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) -+ - wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) - $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) - @$(E) " LD " $@ -@@ -1611,6 +1632,12 @@ eap_eke.so: ../src/eap_peer/eap_eke.c .. - %@.service: %.service.arg.in - sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ - -+dump_cflags: -+ @echo -n $(CFLAGS) " " -+ -+dump_ldflags: -+ @echo -n $(LDFLAGS) $(LIBS) $(EXTRALIBS) " " -+ - wpa_supplicant.exe: wpa_supplicant - mv -f $< $@ - wpa_cli.exe: wpa_cli ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -3868,8 +3868,8 @@ union wpa_event_data { - * Driver wrapper code should call this function whenever an event is received - * from the driver. - */ --void wpa_supplicant_event(void *ctx, enum wpa_event_type event, -- union wpa_event_data *data); -+extern void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); - - - /* ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c -@@ -715,8 +715,8 @@ static void hostapd_event_eapol_rx(struc - } - - --void wpa_supplicant_event(void *ctx, enum wpa_event_type event, -- union wpa_event_data *data) -+void hostapd_wpa_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data) - { - struct hostapd_data *hapd = ctx; - #ifndef CONFIG_NO_STDOUT_DEBUG ---- a/wpa_supplicant/wpa_priv.c -+++ b/wpa_supplicant/wpa_priv.c -@@ -817,8 +817,8 @@ static void wpa_priv_send_ft_response(st - } - - --void wpa_supplicant_event(void *ctx, enum wpa_event_type event, -- union wpa_event_data *data) -+static void supplicant_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data) - { - struct wpa_priv_interface *iface = ctx; - -@@ -960,6 +960,7 @@ int main(int argc, char *argv[]) - if (os_program_init()) - return -1; - -+ wpa_supplicant_event = supplicant_event; - wpa_priv_fd_workaround(); - - for (;;) { ---- a/wpa_supplicant/events.c -+++ b/wpa_supplicant/events.c -@@ -2561,8 +2561,8 @@ static void wpas_event_deauth(struct wpa - } - - --void wpa_supplicant_event(void *ctx, enum wpa_event_type event, -- union wpa_event_data *data) -+void supplicant_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data) - { - struct wpa_supplicant *wpa_s = ctx; - ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -3106,6 +3106,9 @@ static void wpa_supplicant_deinit_iface( - os_free(wpa_s); - } - -+extern void supplicant_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); -+ - - /** - * wpa_supplicant_add_iface - Add a new network interface -@@ -3297,6 +3300,7 @@ struct wpa_global * wpa_supplicant_init( - wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); - #endif /* CONFIG_NO_WPA_MSG */ - -+ wpa_supplicant_event = supplicant_event; - wpa_debug_open_file(params->wpa_debug_file_path); - if (params->wpa_debug_syslog) - wpa_debug_open_syslog(); ---- a/hostapd/main.c -+++ b/hostapd/main.c -@@ -562,6 +562,9 @@ static int hostapd_get_ctrl_iface_group( - return 0; - } - -+void hostapd_wpa_event(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); -+ - - int main(int argc, char *argv[]) - { -@@ -587,6 +590,7 @@ int main(int argc, char *argv[]) - interfaces.global_iface_name = NULL; - interfaces.global_ctrl_sock = -1; - -+ wpa_supplicant_event = hostapd_wpa_event; - for (;;) { - c = getopt(argc, argv, "Bde:f:hKP:tvg:G:"); - if (c < 0) ---- a/src/drivers/drivers.c -+++ b/src/drivers/drivers.c -@@ -7,7 +7,11 @@ - */ - - #include "includes.h" -+#include "common.h" -+#include "driver.h" - -+void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event, -+ union wpa_event_data *data); - - #ifdef CONFIG_DRIVER_WEXT - extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */ diff --git a/package/network/services/hostapd/patches/420-fix_wps_pin_crash.patch b/package/network/services/hostapd/patches/420-fix_wps_pin_crash.patch new file mode 100644 index 0000000000..130bd53e08 --- /dev/null +++ b/package/network/services/hostapd/patches/420-fix_wps_pin_crash.patch @@ -0,0 +1,12 @@ +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -480,6 +480,9 @@ static int hostapd_ctrl_iface_wps_ap_pin + char *pos; + const char *pin_txt; + ++ if (!hapd->wps) ++ return -1; ++ + pos = os_strchr(txt, ' '); + if (pos) + *pos++ = '\0'; diff --git a/package/network/services/hostapd/patches/420-timestamp_check.patch b/package/network/services/hostapd/patches/420-timestamp_check.patch deleted file mode 100644 index 7ca9127037..0000000000 --- a/package/network/services/hostapd/patches/420-timestamp_check.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/src/tls/x509v3.c -+++ b/src/tls/x509v3.c -@@ -1847,6 +1847,9 @@ int x509_certificate_chain_validate(stru - if (chain_trusted) - continue; - -+#ifdef NO_TIMESTAMP_CHECK -+ disable_time_checks = 1; -+#endif - if (!disable_time_checks && - ((unsigned long) now.sec < - (unsigned long) cert->not_before || diff --git a/package/network/services/hostapd/patches/430-rescan_immediately.patch b/package/network/services/hostapd/patches/430-rescan_immediately.patch deleted file mode 100644 index fc49995fa4..0000000000 --- a/package/network/services/hostapd/patches/430-rescan_immediately.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -2457,7 +2457,7 @@ static struct wpa_supplicant * wpa_suppl - if (wpa_s == NULL) - return NULL; - wpa_s->scan_req = INITIAL_SCAN_REQ; -- wpa_s->scan_interval = 5; -+ wpa_s->scan_interval = 1; - wpa_s->new_connection = 1; - wpa_s->parent = wpa_s; - wpa_s->sched_scanning = 0; diff --git a/package/network/services/hostapd/patches/430-wps_single_auth_enc_type.patch b/package/network/services/hostapd/patches/430-wps_single_auth_enc_type.patch new file mode 100644 index 0000000000..6e86658857 --- /dev/null +++ b/package/network/services/hostapd/patches/430-wps_single_auth_enc_type.patch @@ -0,0 +1,25 @@ +--- a/src/ap/wps_hostapd.c ++++ b/src/ap/wps_hostapd.c +@@ -1069,11 +1069,9 @@ int hostapd_init_wps(struct hostapd_data + + if (conf->rsn_pairwise & WPA_CIPHER_CCMP) + wps->encr_types |= WPS_ENCR_AES; +- if (conf->rsn_pairwise & WPA_CIPHER_TKIP) ++ else if (conf->rsn_pairwise & WPA_CIPHER_TKIP) + wps->encr_types |= WPS_ENCR_TKIP; +- } +- +- if (conf->wpa & WPA_PROTO_WPA) { ++ } else if (conf->wpa & WPA_PROTO_WPA) { + if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) + wps->auth_types |= WPS_AUTH_WPAPSK; + if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) +@@ -1081,7 +1079,7 @@ int hostapd_init_wps(struct hostapd_data + + if (conf->wpa_pairwise & WPA_CIPHER_CCMP) + wps->encr_types |= WPS_ENCR_AES; +- if (conf->wpa_pairwise & WPA_CIPHER_TKIP) ++ else if (conf->wpa_pairwise & WPA_CIPHER_TKIP) + wps->encr_types |= WPS_ENCR_TKIP; + } + diff --git a/package/network/services/hostapd/patches/440-dynamic_20_40_mhz.patch b/package/network/services/hostapd/patches/440-dynamic_20_40_mhz.patch new file mode 100644 index 0000000000..f2d7795e81 --- /dev/null +++ b/package/network/services/hostapd/patches/440-dynamic_20_40_mhz.patch @@ -0,0 +1,206 @@ +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2422,6 +2422,10 @@ static int hostapd_config_fill(struct ho + "ht_capab", line); + errors++; + } ++ } else if (os_strcmp(buf, "dynamic_ht40") == 0) { ++ conf->dynamic_ht40 = atoi(pos); ++ if (conf->dynamic_ht40 == 1) ++ conf->dynamic_ht40 = 1500; + } else if (os_strcmp(buf, "require_ht") == 0) { + conf->require_ht = atoi(pos); + } else if (os_strcmp(buf, "obss_interval") == 0) { +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -531,6 +531,7 @@ struct hostapd_config { + int ieee80211n; + int secondary_channel; + int require_ht; ++ int dynamic_ht40; + int obss_interval; + u32 vht_capab; + int ieee80211ac; +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -23,6 +23,7 @@ + #include "beacon.h" + #include "iapp.h" + #include "ieee802_1x.h" ++#include "ieee802_11.h" + #include "ieee802_11_auth.h" + #include "vlan_init.h" + #include "wpa_auth.h" +@@ -329,6 +330,7 @@ static void hostapd_cleanup(struct hosta + static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) + { + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); ++ hostapd_deinit_ht(iface); + hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); + iface->hw_features = NULL; + os_free(iface->current_rates); +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -326,6 +326,9 @@ struct hostapd_iface { + /* Overlapping BSS information */ + int olbc_ht; + ++ int force_20mhz; ++ struct os_time last_20mhz_trigger; ++ + u16 ht_op_mode; + + /* surveying helpers */ +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -1538,6 +1538,9 @@ static void handle_beacon(struct hostapd + sizeof(mgmt->u.beacon)), &elems, + 0); + ++ if (!elems.ht_capabilities) ++ hostapd_trigger_20mhz(hapd->iface); ++ + ap_list_process_beacon(hapd->iface, mgmt, &elems, fi); + } + +--- a/src/ap/ieee802_11.h ++++ b/src/ap/ieee802_11.h +@@ -82,4 +82,17 @@ int hostapd_update_time_adv(struct hosta + void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr); + u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid); + ++#ifdef CONFIG_IEEE80211N ++void hostapd_trigger_20mhz(struct hostapd_iface *iface); ++void hostapd_deinit_ht(struct hostapd_iface *iface); ++ ++#else ++static inline void hostapd_deinit_ht(struct hostapd_iface *iface) ++{ ++} ++static inline void hostapd_trigger_20mhz(struct hostapd_iface *iface) ++{ ++} ++#endif /* CONFIG_IEEE80211N */ ++ + #endif /* IEEE802_11_H */ +--- a/src/ap/ieee802_11_ht.c ++++ b/src/ap/ieee802_11_ht.c +@@ -20,9 +20,11 @@ + #include "drivers/driver.h" + #include "hostapd.h" + #include "ap_config.h" ++#include "ap_drv_ops.h" + #include "sta_info.h" + #include "beacon.h" + #include "ieee802_11.h" ++#include "utils/eloop.h" + + + u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid) +@@ -86,12 +88,15 @@ u8 * hostapd_eid_ht_operation(struct hos + + oper->control_chan = hapd->iconf->channel; + oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode); +- if (hapd->iconf->secondary_channel == 1) +- oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE | +- HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH; +- if (hapd->iconf->secondary_channel == -1) +- oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | +- HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH; ++ ++ if (!hapd->iface->force_20mhz) { ++ if (hapd->iconf->secondary_channel == 1) ++ oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE | ++ HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH; ++ if (hapd->iconf->secondary_channel == -1) ++ oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | ++ HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH; ++ } + + pos += sizeof(*oper); + +@@ -286,3 +291,84 @@ void hostapd_get_ht_capab(struct hostapd + + neg_ht_cap->ht_capabilities_info = host_to_le16(cap); + } ++ ++static void hostapd_set_force_20mhz(struct hostapd_iface *iface); ++ ++static void hostapd_restore_40mhz(void *eloop_data, void *user_ctx) ++{ ++ struct hostapd_iface *iface = eloop_data; ++ struct os_time time; ++ int timeout; ++ ++ if (!iface->last_20mhz_trigger.sec) ++ return; ++ ++ os_get_time(&time); ++ timeout = iface->last_20mhz_trigger.sec + iface->conf->dynamic_ht40 - ++ time.sec; ++ ++ if (timeout > 0) { ++ eloop_register_timeout(timeout, 0, hostapd_restore_40mhz, ++ iface, NULL); ++ return; ++ } ++ ++ iface->last_20mhz_trigger.sec = 0; ++ iface->last_20mhz_trigger.usec = 0; ++ ++ iface->force_20mhz = 0; ++ hostapd_set_force_20mhz(iface); ++} ++ ++static void hostapd_set_force_20mhz(struct hostapd_iface *iface) ++{ ++ int secondary_channel; ++ int i; ++ ++ ieee802_11_set_beacons(iface); ++ ++ for (i = 0; i < iface->num_bss; i++) { ++ struct hostapd_data *hapd = iface->bss[i]; ++ ++ if (iface->force_20mhz) ++ secondary_channel = 0; ++ else ++ secondary_channel = hapd->iconf->secondary_channel; ++ ++ if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq, ++ hapd->iconf->channel, ++ hapd->iconf->ieee80211n, ++ hapd->iconf->ieee80211ac, ++ secondary_channel, ++ hapd->iconf->vht_oper_chwidth, ++ hapd->iconf->vht_oper_centr_freq_seg0_idx, ++ hapd->iconf->vht_oper_centr_freq_seg1_idx)) { ++ wpa_printf(MSG_ERROR, "Could not set channel for " ++ "kernel driver"); ++ } ++ } ++} ++ ++void hostapd_deinit_ht(struct hostapd_iface *iface) ++{ ++ eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL); ++} ++ ++void hostapd_trigger_20mhz(struct hostapd_iface *iface) ++{ ++ if (!iface->conf->dynamic_ht40) ++ return; ++ ++ if (!iface->force_20mhz) { ++ iface->force_20mhz = 1; ++ hostapd_set_force_20mhz(iface); ++ } ++ ++ if (!iface->last_20mhz_trigger.sec) { ++ eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL); ++ eloop_register_timeout(iface->conf->dynamic_ht40, 0, ++ hostapd_restore_40mhz, iface, NULL); ++ } ++ ++ os_get_time(&iface->last_20mhz_trigger); ++} diff --git a/package/network/services/hostapd/patches/440-optional_rfkill.patch b/package/network/services/hostapd/patches/440-optional_rfkill.patch deleted file mode 100644 index 6bff863e3d..0000000000 --- a/package/network/services/hostapd/patches/440-optional_rfkill.patch +++ /dev/null @@ -1,261 +0,0 @@ ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -216,7 +216,9 @@ struct wpa_driver_nl80211_data { - int if_removed; - int if_disabled; - int ignore_if_down_event; -+#ifdef CONFIG_RFKILL - struct rfkill_data *rfkill; -+#endif - struct wpa_driver_capa capa; - u8 *extended_capa, *extended_capa_mask; - unsigned int extended_capa_len; -@@ -3482,7 +3484,7 @@ static int wpa_driver_nl80211_init_nl(st - return 0; - } - -- -+#ifdef CONFIG_RFKILL - static void wpa_driver_nl80211_rfkill_blocked(void *ctx) - { - wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked"); -@@ -3505,6 +3507,7 @@ static void wpa_driver_nl80211_rfkill_un - } - /* rtnetlink ifup handler will report interface as enabled */ - } -+#endif /* CONFIG_RFKILL */ - - - static void wpa_driver_nl80211_handle_eapol_tx_status(int sock, -@@ -3600,7 +3603,9 @@ static void * wpa_driver_nl80211_init(vo - void *global_priv) - { - struct wpa_driver_nl80211_data *drv; -+#ifdef CONFIG_RFKILL - struct rfkill_config *rcfg; -+#endif - struct i802_bss *bss; - - if (global_priv == NULL) -@@ -3634,6 +3639,7 @@ static void * wpa_driver_nl80211_init(vo - if (nl80211_init_bss(bss)) - goto failed; - -+#ifdef CONFIG_RFKILL - rcfg = os_zalloc(sizeof(*rcfg)); - if (rcfg == NULL) - goto failed; -@@ -3646,6 +3652,7 @@ static void * wpa_driver_nl80211_init(vo - wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available"); - os_free(rcfg); - } -+#endif /* CONFIG_RFKILL */ - - if (wpa_driver_nl80211_finish_drv_init(drv)) - goto failed; -@@ -3937,10 +3944,12 @@ static void nl80211_mgmt_unsubscribe(str - } - - -+#ifdef CONFIG_RFKILL - static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx) - { - wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL); - } -+#endif /* CONFIG_RFKILL */ - - - static void nl80211_del_p2pdev(struct i802_bss *bss) -@@ -4048,13 +4057,16 @@ wpa_driver_nl80211_finish_drv_init_sta(s - } - - if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1)) { -+#ifdef CONFIG_RFKILL - if (rfkill_is_blocked(drv->rfkill)) { - wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable " - "interface '%s' due to rfkill", - bss->ifname); - drv->if_disabled = 1; - *send_rfkill_event = 1; -- } else { -+ } else -+#endif -+ { - wpa_printf(MSG_ERROR, "nl80211: Could not set " - "interface '%s' UP", bss->ifname); - return -1; -@@ -4093,8 +4105,10 @@ wpa_driver_nl80211_finish_drv_init(struc - return -1; - - if (send_rfkill_event) { -+#ifdef CONFIG_RFKILL - eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill, - drv, drv->ctx); -+#endif - } - - return 0; -@@ -4180,7 +4194,9 @@ static void wpa_driver_nl80211_deinit(st - - netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0, - IF_OPER_UP); -+#ifdef CONFIG_RFKILL - rfkill_deinit(drv->rfkill); -+#endif - - eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx); - ---- a/src/drivers/driver_wext.c -+++ b/src/drivers/driver_wext.c -@@ -740,7 +740,7 @@ static void wpa_driver_wext_event_rtm_de - } - } - -- -+#ifdef CONFIG_RFKILL - static void wpa_driver_wext_rfkill_blocked(void *ctx) - { - wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked"); -@@ -762,7 +762,7 @@ static void wpa_driver_wext_rfkill_unblo - } - /* rtnetlink ifup handler will report interface as enabled */ - } -- -+#endif /* CONFIG_RFKILL */ - - static void wext_get_phy_name(struct wpa_driver_wext_data *drv) - { -@@ -808,7 +808,9 @@ void * wpa_driver_wext_init(void *ctx, c - { - struct wpa_driver_wext_data *drv; - struct netlink_config *cfg; -+#ifdef CONFIG_RFKILL - struct rfkill_config *rcfg; -+#endif - char path[128]; - struct stat buf; - -@@ -843,6 +845,7 @@ void * wpa_driver_wext_init(void *ctx, c - goto err2; - } - -+#ifdef CONFIG_RFKILL - rcfg = os_zalloc(sizeof(*rcfg)); - if (rcfg == NULL) - goto err3; -@@ -855,6 +858,7 @@ void * wpa_driver_wext_init(void *ctx, c - wpa_printf(MSG_DEBUG, "WEXT: RFKILL status not available"); - os_free(rcfg); - } -+#endif /* CONFIG_RFKILL */ - - drv->mlme_sock = -1; - -@@ -872,7 +876,9 @@ void * wpa_driver_wext_init(void *ctx, c - return drv; - - err3: -+#ifdef CONFIG_RFKILL - rfkill_deinit(drv->rfkill); -+#endif - netlink_deinit(drv->netlink); - err2: - close(drv->ioctl_sock); -@@ -882,10 +888,12 @@ err1: - } - - -+#ifdef CONFIG_RFKILL - static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void *timeout_ctx) - { - wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL); - } -+#endif /* CONFIG_RFKILL */ - - - static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv) -@@ -893,13 +901,16 @@ static int wpa_driver_wext_finish_drv_in - int send_rfkill_event = 0; - - if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) { -+#ifdef CONFIG_RFKILL - if (rfkill_is_blocked(drv->rfkill)) { - wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable " - "interface '%s' due to rfkill", - drv->ifname); - drv->if_disabled = 1; - send_rfkill_event = 1; -- } else { -+ } else -+#endif -+ { - wpa_printf(MSG_ERROR, "WEXT: Could not set " - "interface '%s' UP", drv->ifname); - return -1; -@@ -947,8 +958,10 @@ static int wpa_driver_wext_finish_drv_in - 1, IF_OPER_DORMANT); - - if (send_rfkill_event) { -+#ifdef CONFIG_RFKILL - eloop_register_timeout(0, 0, wpa_driver_wext_send_rfkill, - drv, drv->ctx); -+#endif - } - - return 0; -@@ -978,7 +991,9 @@ void wpa_driver_wext_deinit(void *priv) - - netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP); - netlink_deinit(drv->netlink); -+#ifdef CONFIG_RFKILL - rfkill_deinit(drv->rfkill); -+#endif - - if (drv->mlme_sock >= 0) - eloop_unregister_read_sock(drv->mlme_sock); ---- a/src/drivers/drivers.mak -+++ b/src/drivers/drivers.mak -@@ -25,7 +25,6 @@ NEED_SME=y - NEED_AP_MLME=y - NEED_NETLINK=y - NEED_LINUX_IOCTL=y --NEED_RFKILL=y - - ifdef CONFIG_LIBNL32 - DRV_LIBS += -lnl-3 -@@ -109,7 +108,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT - CONFIG_WIRELESS_EXTENSION=y - NEED_NETLINK=y - NEED_LINUX_IOCTL=y --NEED_RFKILL=y - endif - - ifdef CONFIG_DRIVER_NDIS -@@ -135,7 +133,6 @@ endif - ifdef CONFIG_WIRELESS_EXTENSION - DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION - DRV_WPA_OBJS += ../src/drivers/driver_wext.o --NEED_RFKILL=y - endif - - ifdef NEED_NETLINK -@@ -148,6 +145,7 @@ endif - - ifdef NEED_RFKILL - DRV_OBJS += ../src/drivers/rfkill.o -+DRV_WPA_CFLAGS += -DCONFIG_RFKILL - endif - - ifdef CONFIG_VLAN_NETLINK ---- a/src/drivers/driver_wext.h -+++ b/src/drivers/driver_wext.h -@@ -22,7 +22,9 @@ struct wpa_driver_wext_data { - int ifindex2; - int if_removed; - int if_disabled; -+#ifdef CONFIG_RFKILL - struct rfkill_data *rfkill; -+#endif - u8 *assoc_req_ies; - size_t assoc_req_ies_len; - u8 *assoc_resp_ies; diff --git a/package/network/services/hostapd/patches/450-limit_debug_messages.patch b/package/network/services/hostapd/patches/450-limit_debug_messages.patch new file mode 100644 index 0000000000..aaea94137f --- /dev/null +++ b/package/network/services/hostapd/patches/450-limit_debug_messages.patch @@ -0,0 +1,213 @@ +--- a/src/utils/wpa_debug.c ++++ b/src/utils/wpa_debug.c +@@ -201,7 +201,7 @@ void wpa_debug_close_linux_tracing(void) + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +-void wpa_printf(int level, const char *fmt, ...) ++void _wpa_printf(int level, const char *fmt, ...) + { + va_list ap; + +@@ -248,8 +248,8 @@ void wpa_printf(int level, const char *f + } + + +-static void _wpa_hexdump(int level, const char *title, const u8 *buf, +- size_t len, int show) ++void _wpa_hexdump(int level, const char *title, const u8 *buf, ++ size_t len, int show) + { + size_t i; + +@@ -375,20 +375,9 @@ static void _wpa_hexdump(int level, cons + #endif /* CONFIG_ANDROID_LOG */ + } + +-void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len) +-{ +- _wpa_hexdump(level, title, buf, len, 1); +-} +- +- +-void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) +-{ +- _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); +-} + +- +-static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, +- size_t len, int show) ++void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, ++ size_t len, int show) + { + size_t i, llen; + const u8 *pos = buf; +@@ -495,19 +484,6 @@ static void _wpa_hexdump_ascii(int level + } + + +-void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len) +-{ +- _wpa_hexdump_ascii(level, title, buf, len, 1); +-} +- +- +-void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, +- size_t len) +-{ +- _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); +-} +- +- + #ifdef CONFIG_DEBUG_FILE + static char *last_path = NULL; + #endif /* CONFIG_DEBUG_FILE */ +@@ -591,7 +567,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_ + } + + +-void wpa_msg(void *ctx, int level, const char *fmt, ...) ++void _wpa_msg(void *ctx, int level, const char *fmt, ...) + { + va_list ap; + char *buf; +@@ -625,7 +601,7 @@ void wpa_msg(void *ctx, int level, const + } + + +-void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) ++void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) + { + va_list ap; + char *buf; +--- a/src/utils/wpa_debug.h ++++ b/src/utils/wpa_debug.h +@@ -43,6 +43,17 @@ int wpa_debug_open_file(const char *path + int wpa_debug_reopen_file(void); + void wpa_debug_close_file(void); + ++/* internal */ ++void _wpa_hexdump(int level, const char *title, const u8 *buf, ++ size_t len, int show); ++void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, ++ size_t len, int show); ++extern int wpa_debug_show_keys; ++ ++#ifndef CONFIG_MSG_MIN_PRIORITY ++#define CONFIG_MSG_MIN_PRIORITY 0 ++#endif ++ + /** + * wpa_debug_printf_timestamp - Print timestamp for debug output + * +@@ -63,9 +74,15 @@ void wpa_debug_print_timestamp(void); + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +-void wpa_printf(int level, const char *fmt, ...) ++void _wpa_printf(int level, const char *fmt, ...) + PRINTF_FORMAT(2, 3); + ++#define wpa_printf(level, ...) \ ++ do { \ ++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ ++ _wpa_printf(level, __VA_ARGS__); \ ++ } while(0) ++ + /** + * wpa_hexdump - conditional hex dump + * @level: priority level (MSG_*) of the message +@@ -77,7 +94,13 @@ PRINTF_FORMAT(2, 3); + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump. + */ +-void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len); ++static inline void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len) ++{ ++ if (level < CONFIG_MSG_MIN_PRIORITY) ++ return; ++ ++ _wpa_hexdump(level, title, buf, len, 1); ++} + + static inline void wpa_hexdump_buf(int level, const char *title, + const struct wpabuf *buf) +@@ -99,7 +122,13 @@ static inline void wpa_hexdump_buf(int l + * like wpa_hexdump(), but by default, does not include secret keys (passwords, + * etc.) in debug output. + */ +-void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len); ++static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) ++{ ++ if (level < CONFIG_MSG_MIN_PRIORITY) ++ return; ++ ++ _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); ++} + + static inline void wpa_hexdump_buf_key(int level, const char *title, + const struct wpabuf *buf) +@@ -121,8 +150,14 @@ static inline void wpa_hexdump_buf_key(i + * the hex numbers and ASCII characters (for printable range) are shown. 16 + * bytes per line will be shown. + */ +-void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, +- size_t len); ++static inline void wpa_hexdump_ascii(int level, const char *title, ++ const u8 *buf, size_t len) ++{ ++ if (level < CONFIG_MSG_MIN_PRIORITY) ++ return; ++ ++ _wpa_hexdump_ascii(level, title, buf, len, 1); ++} + + /** + * wpa_hexdump_ascii_key - conditional hex dump, hide keys +@@ -138,8 +173,14 @@ void wpa_hexdump_ascii(int level, const + * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by + * default, does not include secret keys (passwords, etc.) in debug output. + */ +-void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, +- size_t len); ++static inline void wpa_hexdump_ascii_key(int level, const char *title, ++ const u8 *buf, size_t len) ++{ ++ if (level < CONFIG_MSG_MIN_PRIORITY) ++ return; ++ ++ _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); ++} + + /* + * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce +@@ -174,7 +215,12 @@ void wpa_hexdump_ascii_key(int level, co + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +-void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); ++void _wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); ++#define wpa_msg(ctx, level, ...) \ ++ do { \ ++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ ++ _wpa_msg(ctx, level, __VA_ARGS__); \ ++ } while(0) + + /** + * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors +@@ -188,8 +234,13 @@ void wpa_msg(void *ctx, int level, const + * attached ctrl_iface monitors. In other words, it can be used for frequent + * events that do not need to be sent to syslog. + */ +-void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) ++void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) + PRINTF_FORMAT(3, 4); ++#define wpa_msg_ctrl(ctx, level, ...) \ ++ do { \ ++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ ++ _wpa_msg_ctrl(ctx, level, __VA_ARGS__); \ ++ } while(0) + + /** + * wpa_msg_global - Global printf for ctrl_iface monitors diff --git a/package/network/services/hostapd/patches/450-reload_freq_change.patch b/package/network/services/hostapd/patches/450-reload_freq_change.patch deleted file mode 100644 index e981375692..0000000000 --- a/package/network/services/hostapd/patches/450-reload_freq_change.patch +++ /dev/null @@ -1,85 +0,0 @@ ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -133,38 +133,51 @@ static void hostapd_clear_old(struct hos - int hostapd_reload_config(struct hostapd_iface *iface) - { - struct hostapd_data *hapd = iface->bss[0]; -- struct hostapd_config *newconf, *oldconf; -+ struct hostapd_config *conf = hapd->iconf, *oldconf = NULL; - size_t j; - -- if (iface->config_fname == NULL) { -- /* Only in-memory config in use - assume it has been updated */ -+ if (iface->config_fname) { -+ if (iface->interfaces == NULL || -+ iface->interfaces->config_read_cb == NULL) -+ return -1; -+ conf = iface->interfaces->config_read_cb(iface->config_fname); -+ if (conf == NULL) -+ return -1; -+ - hostapd_clear_old(iface); -- for (j = 0; j < iface->num_bss; j++) -- hostapd_reload_bss(iface->bss[j]); -- return 0; -- } - -- if (iface->interfaces == NULL || -- iface->interfaces->config_read_cb == NULL) -- return -1; -- newconf = iface->interfaces->config_read_cb(iface->config_fname); -- if (newconf == NULL) -- return -1; -+ oldconf = hapd->iconf; -+ iface->conf = conf; -+ } - -- hostapd_clear_old(iface); -+ hostapd_select_hw_mode(iface); -+ iface->freq = hostapd_hw_get_freq(hapd, conf->channel); - -- oldconf = hapd->iconf; -- iface->conf = newconf; -+ if (iface->current_mode) -+ hostapd_prepare_rates(iface, iface->current_mode); - - for (j = 0; j < iface->num_bss; j++) { - hapd = iface->bss[j]; -- hapd->iconf = newconf; -- hapd->conf = &newconf->bss[j]; -+ hapd->iconf = iface->conf; -+ hapd->conf = &iface->conf->bss[j]; -+ -+ if (hostapd_set_freq(hapd, conf->hw_mode, iface->freq, -+ conf->channel, -+ conf->ieee80211n, -+ conf->ieee80211ac, -+ conf->secondary_channel, -+ conf->vht_oper_chwidth, -+ conf->vht_oper_centr_freq_seg0_idx, -+ conf->vht_oper_centr_freq_seg1_idx)) { -+ wpa_printf(MSG_ERROR, "Could not set channel for " -+ "kernel driver"); -+ } -+ - hostapd_reload_bss(hapd); - } - -- hostapd_config_free(oldconf); -- -+ if (oldconf) -+ hostapd_config_free(oldconf); - - return 0; - } ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -6511,7 +6511,7 @@ static int wpa_driver_nl80211_set_freq(s - - nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY); - -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); -+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex); - NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq); - if (freq->vht_enabled) { - switch (freq->bandwidth) { diff --git a/package/network/services/hostapd/patches/451-nl80211_del_beacon_bss.patch b/package/network/services/hostapd/patches/451-nl80211_del_beacon_bss.patch deleted file mode 100644 index 0e33f0afaa..0000000000 --- a/package/network/services/hostapd/patches/451-nl80211_del_beacon_bss.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4115,16 +4115,18 @@ wpa_driver_nl80211_finish_drv_init(struc - } - - --static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv) -+static int wpa_driver_nl80211_del_bss_beacon(struct i802_bss *bss) - { -+ struct wpa_driver_nl80211_data *drv = bss->drv; - struct nl_msg *msg; - -+ bss->beacon_set = 0; - msg = nlmsg_alloc(); - if (!msg) - return -ENOMEM; - - nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_BEACON); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); -+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex); - - return send_and_recv_msgs(drv, msg, NULL, NULL); - nla_put_failure: -@@ -4132,6 +4134,15 @@ static int wpa_driver_nl80211_del_beacon - return -ENOBUFS; - } - -+static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv) -+{ -+ struct i802_bss *bss; -+ -+ for (bss = &drv->first_bss; bss; bss = bss->next) -+ wpa_driver_nl80211_del_bss_beacon(bss); -+ -+ return 0; -+} - - /** - * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface -@@ -9575,7 +9586,6 @@ static int wpa_driver_nl80211_stop_ap(vo - if (!is_ap_interface(drv->nlmode)) - return -1; - wpa_driver_nl80211_del_beacon(drv); -- bss->beacon_set = 0; - return 0; - } - diff --git a/package/network/services/hostapd/patches/452-ctrl_iface_reload.patch b/package/network/services/hostapd/patches/452-ctrl_iface_reload.patch deleted file mode 100644 index 7459a0f7cd..0000000000 --- a/package/network/services/hostapd/patches/452-ctrl_iface_reload.patch +++ /dev/null @@ -1,98 +0,0 @@ ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -34,6 +34,7 @@ - #include "wps/wps.h" - #include "config_file.h" - #include "ctrl_iface.h" -+#include "config_file.h" - - - struct wpa_ctrl_dst { -@@ -44,6 +45,7 @@ struct wpa_ctrl_dst { - int errors; - }; - -+static char *reload_opts = NULL; - - static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level, - const char *buf, size_t len); -@@ -153,6 +155,68 @@ static int hostapd_ctrl_iface_new_sta(st - return 0; - } - -+static int hostapd_ctrl_iface_set_down(struct hostapd_data *hapd) -+{ -+ if (hapd->driver->stop_ap) -+ hapd->driver->stop_ap(hapd->drv_priv); -+ return 0; -+} -+ -+static char *get_option(char *opt, char *str) -+{ -+ int len = strlen(str); -+ -+ if (!strncmp(opt, str, len)) -+ return opt + len; -+ else -+ return NULL; -+} -+ -+static struct hostapd_config *hostapd_ctrl_iface_config_read(const char *fname) -+{ -+ struct hostapd_config *conf; -+ char *opt, *val; -+ -+ conf = hostapd_config_read(fname); -+ if (!conf) -+ return NULL; -+ -+ for (opt = strtok(reload_opts, " "); -+ opt; -+ opt = strtok(NULL, " ")) { -+ -+ if ((val = get_option(opt, "channel="))) -+ conf->channel = atoi(val); -+ else if ((val = get_option(opt, "ht_capab="))) -+ conf->ht_capab = atoi(val); -+ else if ((val = get_option(opt, "ht_capab_mask="))) -+ conf->ht_capab &= atoi(val); -+ else if ((val = get_option(opt, "sec_chan="))) -+ conf->secondary_channel = atoi(val); -+ else if ((val = get_option(opt, "hw_mode="))) -+ conf->hw_mode = atoi(val); -+ else if ((val = get_option(opt, "ieee80211n="))) -+ conf->ieee80211n = atoi(val); -+ else -+ break; -+ } -+ -+ return conf; -+} -+ -+static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt) -+{ -+ struct hostapd_config * (*config_read_cb)(const char *config_fname); -+ struct hostapd_iface *iface = hapd->iface; -+ -+ config_read_cb = iface->interfaces->config_read_cb; -+ iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; -+ reload_opts = txt; -+ -+ hostapd_reload_config(iface); -+ -+ iface->interfaces->config_read_cb = config_read_cb; -+} - - #ifdef CONFIG_IEEE80211W - #ifdef NEED_AP_MLME -@@ -949,6 +1013,10 @@ static void hostapd_ctrl_iface_receive(i - reply_len += res; - } - #endif /* CONFIG_NO_RADIUS */ -+ } else if (os_strcmp(buf, "DOWN") == 0) { -+ hostapd_ctrl_iface_set_down(hapd); -+ } else if (os_strncmp(buf, "UPDATE ", 7) == 0) { -+ hostapd_ctrl_iface_update(hapd, buf + 7); - } else if (os_strcmp(buf, "STA-FIRST") == 0) { - reply_len = hostapd_ctrl_iface_sta_first(hapd, reply, - reply_size); diff --git a/package/network/services/hostapd/patches/453-ap_sta_support.patch b/package/network/services/hostapd/patches/453-ap_sta_support.patch deleted file mode 100644 index d4b6c1da04..0000000000 --- a/package/network/services/hostapd/patches/453-ap_sta_support.patch +++ /dev/null @@ -1,210 +0,0 @@ ---- a/wpa_supplicant/wpa_supplicant_i.h -+++ b/wpa_supplicant/wpa_supplicant_i.h -@@ -96,6 +96,11 @@ struct wpa_interface { - const char *ifname; - - /** -+ * hostapd_ctrl - path to hostapd control socket for notification -+ */ -+ const char *hostapd_ctrl; -+ -+ /** - * bridge_ifname - Optional bridge interface name - * - * If the driver interface (ifname) is included in a Linux bridge -@@ -328,6 +333,8 @@ struct wpa_supplicant { - #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ - char bridge_ifname[16]; - -+ struct wpa_ctrl *hostapd; -+ - char *confname; - char *confanother; - struct wpa_config *conf; ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -13,6 +13,10 @@ PKG_CONFIG ?= pkg-config - CFLAGS += -I../src - CFLAGS += -I../src/utils - -+ifdef MULTICALL -+CFLAGS += -DMULTICALL -+endif -+ - -include .config - -include $(if $(MULTICALL),../hostapd/.config) - -@@ -76,6 +80,8 @@ OBJS_c = wpa_cli.o ../src/common/wpa_ctr - OBJS_c += ../src/utils/wpa_debug.o - OBJS_c += ../src/utils/common.o - -+OBJS += ../src/common/wpa_ctrl.o -+ - ifndef CONFIG_OS - ifdef CONFIG_NATIVE_WINDOWS - CONFIG_OS=win32 ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -109,6 +109,46 @@ extern int wpa_debug_show_keys; - extern int wpa_debug_timestamp; - extern struct wpa_driver_ops *wpa_drivers[]; - -+static int hostapd_stop(struct wpa_supplicant *wpa_s) -+{ -+ const char *cmd = "DOWN"; -+ char buf[256]; -+ int len = sizeof(buf); -+ -+ if (wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL) < 0) { -+ wpa_printf(MSG_ERROR, "\nFailed to stop hostapd AP interfaces\n"); -+ return -1; -+ } -+ return 0; -+} -+ -+static int hostapd_reload(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) -+{ -+ char *cmd = NULL; -+ char buf[256]; -+ int len = sizeof(buf); -+ enum hostapd_hw_mode hw_mode; -+ u8 channel; -+ int ret; -+ -+ if (!bss) -+ return; -+ -+ hw_mode = ieee80211_freq_to_chan(bss->freq, &channel); -+ if (asprintf(&cmd, "UPDATE channel=%d sec_chan=0 hw_mode=%d ieee80211n=%d", -+ channel, hw_mode, !!bss->ht_capab) < 0) -+ return -1; -+ -+ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); -+ free(cmd); -+ -+ if (ret < 0) { -+ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); -+ return -1; -+ } -+ return 0; -+} -+ - /* Configure default/group WEP keys for static WEP */ - int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) - { -@@ -676,8 +716,12 @@ void wpa_supplicant_set_state(struct wpa - #endif /* CONFIG_P2P */ - - sme_sched_obss_scan(wpa_s, 1); -+ if (wpa_s->hostapd) -+ hostapd_reload(wpa_s, wpa_s->current_bss); - } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || - state == WPA_ASSOCIATED) { -+ if (wpa_s->hostapd) -+ hostapd_stop(wpa_s); - wpa_s->new_connection = 1; - wpa_drv_set_operstate(wpa_s, 0); - #ifndef IEEE8021X_EAPOL -@@ -2875,6 +2919,20 @@ static int wpa_supplicant_init_iface(str - sizeof(wpa_s->bridge_ifname)); - } - -+ if (iface->hostapd_ctrl) { -+ char *cmd = "DOWN"; -+ char buf[256]; -+ int len = sizeof(buf); -+ -+ wpa_s->hostapd = wpa_ctrl_open(iface->hostapd_ctrl); -+ if (!wpa_s->hostapd) { -+ wpa_printf(MSG_ERROR, "\nFailed to connect to hostapd\n"); -+ return -1; -+ } -+ if (hostapd_stop(wpa_s) < 0) -+ return -1; -+ } -+ - /* RSNA Supplicant Key Management - INITIALIZE */ - eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); - eapol_sm_notify_portValid(wpa_s->eapol, FALSE); ---- a/wpa_supplicant/bss.c -+++ b/wpa_supplicant/bss.c -@@ -11,6 +11,7 @@ - #include "utils/common.h" - #include "utils/eloop.h" - #include "common/ieee802_11_defs.h" -+#include "common/ieee802_11_common.h" - #include "drivers/driver.h" - #include "wpa_supplicant_i.h" - #include "config.h" -@@ -245,6 +246,9 @@ static void calculate_update_time(const - static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, - struct os_time *fetch_time) - { -+ struct ieee80211_ht_capabilities *capab; -+ struct ieee802_11_elems elems; -+ - dst->flags = src->flags; - os_memcpy(dst->bssid, src->bssid, ETH_ALEN); - dst->freq = src->freq; -@@ -255,6 +259,12 @@ static void wpa_bss_copy_res(struct wpa_ - dst->level = src->level; - dst->tsf = src->tsf; - -+ memset(&elems, 0, sizeof(elems)); -+ ieee802_11_parse_elems((u8 *) (src + 1), src->ie_len, &elems, 0); -+ capab = (struct ieee80211_ht_capabilities *) elems.ht_capabilities; -+ if (capab) -+ dst->ht_capab = le_to_host16(capab->ht_capabilities_info); -+ - calculate_update_time(fetch_time, src->age, &dst->last_update); - } - ---- a/wpa_supplicant/main.c -+++ b/wpa_supplicant/main.c -@@ -27,7 +27,7 @@ static void usage(void) - " wpa_supplicant [-BddhKLqqstuvW] [-P] " - "[-g] \\\n" - " [-G] \\\n" -- " -i -c [-C] [-D] " -+ " -i -c [-C] [-D] [-H] " - "[-p] \\\n" - " [-b] [-f] [-e] " - "\\\n" -@@ -72,6 +72,7 @@ static void usage(void) - #endif /* CONFIG_DEBUG_LINUX_TRACING */ - printf(" -t = include timestamp in debug messages\n" - " -h = show this help text\n" -+ " -H = connect to a hostapd instance to manage state changes\n" - " -L = show license (BSD)\n" - " -o = override driver parameter for new interfaces\n" - " -O = override ctrl_interface parameter for new interfaces\n" -@@ -160,7 +161,7 @@ int main(int argc, char *argv[]) - - for (;;) { - c = getopt(argc, argv, -- "b:Bc:C:D:de:f:g:G:hi:I:KLNo:O:p:P:qsTtuvW"); -+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuvW"); - if (c < 0) - break; - switch (c) { -@@ -207,6 +208,9 @@ int main(int argc, char *argv[]) - usage(); - exitcode = 0; - goto out; -+ case 'H': -+ iface->hostapd_ctrl = optarg; -+ break; - case 'i': - iface->ifname = optarg; - break; ---- a/wpa_supplicant/bss.h -+++ b/wpa_supplicant/bss.h -@@ -69,6 +69,8 @@ struct wpa_bss { - u8 ssid[32]; - /** Length of SSID */ - size_t ssid_len; -+ /** HT caapbilities */ -+ u16 ht_capab; - /** Frequency of the channel in MHz (e.g., 2412 = channel 1) */ - int freq; - /** Beacon interval in TUs (host byte order) */ diff --git a/package/network/services/hostapd/patches/460-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/460-disable_ctrl_iface_mib.patch deleted file mode 100644 index 8dc0a5de07..0000000000 --- a/package/network/services/hostapd/patches/460-disable_ctrl_iface_mib.patch +++ /dev/null @@ -1,168 +0,0 @@ ---- a/hostapd/Makefile -+++ b/hostapd/Makefile -@@ -136,6 +136,9 @@ endif - ifdef CONFIG_NO_CTRL_IFACE - CFLAGS += -DCONFIG_NO_CTRL_IFACE - else -+ifdef CONFIG_CTRL_IFACE_MIB -+CFLAGS += -DCONFIG_CTRL_IFACE_MIB -+endif - OBJS += ctrl_iface.o - OBJS += ../src/ap/ctrl_iface_ap.o - endif ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -984,6 +984,7 @@ static void hostapd_ctrl_iface_receive(i - } else if (os_strncmp(buf, "RELOG", 5) == 0) { - if (wpa_debug_reopen_file() < 0) - reply_len = -1; -+#ifdef CONFIG_CTRL_IFACE_MIB - } else if (os_strcmp(buf, "MIB") == 0) { - reply_len = ieee802_11_get_mib(hapd, reply, reply_size); - if (reply_len >= 0) { -@@ -1013,10 +1014,12 @@ static void hostapd_ctrl_iface_receive(i - reply_len += res; - } - #endif /* CONFIG_NO_RADIUS */ -+#endif - } else if (os_strcmp(buf, "DOWN") == 0) { - hostapd_ctrl_iface_set_down(hapd); - } else if (os_strncmp(buf, "UPDATE ", 7) == 0) { - hostapd_ctrl_iface_update(hapd, buf + 7); -+#ifdef CONFIG_CTRL_IFACE_MIB - } else if (os_strcmp(buf, "STA-FIRST") == 0) { - reply_len = hostapd_ctrl_iface_sta_first(hapd, reply, - reply_size); -@@ -1026,6 +1029,7 @@ static void hostapd_ctrl_iface_receive(i - } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { - reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, - reply_size); -+#endif - } else if (os_strcmp(buf, "ATTACH") == 0) { - if (hostapd_ctrl_iface_attach(hapd, &from, fromlen)) - reply_len = -1; ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -768,6 +768,9 @@ ifdef CONFIG_WNM - OBJS += ../src/ap/wnm_ap.o - endif - ifdef CONFIG_CTRL_IFACE -+ifdef CONFIG_CTRL_IFACE_MIB -+CFLAGS += -DCONFIG_CTRL_IFACE_MIB -+endif - OBJS += ../src/ap/ctrl_iface_ap.o - endif - ---- a/wpa_supplicant/ctrl_iface.c -+++ b/wpa_supplicant/ctrl_iface.c -@@ -5193,6 +5193,7 @@ char * wpa_supplicant_ctrl_iface_process - reply_len = -1; - } else if (os_strncmp(buf, "NOTE ", 5) == 0) { - wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); -+#ifdef CONFIG_CTRL_IFACE_MIB - } else if (os_strcmp(buf, "MIB") == 0) { - reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); - if (reply_len >= 0) { -@@ -5204,6 +5205,7 @@ char * wpa_supplicant_ctrl_iface_process - else - reply_len += res; - } -+#endif - } else if (os_strncmp(buf, "STATUS", 6) == 0) { - reply_len = wpa_supplicant_ctrl_iface_status( - wpa_s, buf + 6, reply, reply_size); -@@ -5607,6 +5609,7 @@ char * wpa_supplicant_ctrl_iface_process - reply_len = wpa_supplicant_ctrl_iface_bss( - wpa_s, buf + 4, reply, reply_size); - #ifdef CONFIG_AP -+#ifdef CONFIG_CTRL_IFACE_MIB - } else if (os_strcmp(buf, "STA-FIRST") == 0) { - reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); - } else if (os_strncmp(buf, "STA ", 4) == 0) { -@@ -5615,6 +5618,7 @@ char * wpa_supplicant_ctrl_iface_process - } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { - reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, - reply_size); -+#endif - } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) { - if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15)) - reply_len = -1; ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -20,6 +20,7 @@ - #include "ctrl_iface_ap.h" - #include "ap_drv_ops.h" - -+#ifdef CONFIG_CTRL_IFACE_MIB - - static int hostapd_get_sta_conn_time(struct sta_info *sta, - char *buf, size_t buflen) -@@ -129,6 +130,7 @@ int hostapd_ctrl_iface_sta_next(struct h - return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen); - } - -+#endif - - #ifdef CONFIG_P2P_MANAGER - static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype, -@@ -303,3 +305,4 @@ int hostapd_ctrl_iface_disassociate(stru - - return 0; - } -+ ---- a/src/ap/ieee802_1x.c -+++ b/src/ap/ieee802_1x.c -@@ -1939,6 +1939,7 @@ static const char * bool_txt(Boolean boo - return bool ? "TRUE" : "FALSE"; - } - -+#ifdef CONFIG_CTRL_IFACE_MIB - - int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) - { -@@ -2091,6 +2092,7 @@ int ieee802_1x_get_mib_sta(struct hostap - return len; - } - -+#endif - - static void ieee802_1x_finished(struct hostapd_data *hapd, - struct sta_info *sta, int success) ---- a/src/ap/wpa_auth.c -+++ b/src/ap/wpa_auth.c -@@ -2697,6 +2697,7 @@ static const char * wpa_bool_txt(int boo - return bool ? "TRUE" : "FALSE"; - } - -+#ifdef CONFIG_CTRL_IFACE_MIB - - #define RSN_SUITE "%02x-%02x-%02x-%d" - #define RSN_SUITE_ARG(s) \ -@@ -2841,7 +2842,7 @@ int wpa_get_mib_sta(struct wpa_state_mac - - return len; - } -- -+#endif - - void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth) - { ---- a/src/rsn_supp/wpa.c -+++ b/src/rsn_supp/wpa.c -@@ -1842,6 +1842,8 @@ static u32 wpa_key_mgmt_suite(struct wpa - } - - -+#ifdef CONFIG_CTRL_IFACE_MIB -+ - #define RSN_SUITE "%02x-%02x-%02x-%d" - #define RSN_SUITE_ARG(s) \ - ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff -@@ -1925,6 +1927,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch - - return (int) len; - } -+#endif - #endif /* CONFIG_CTRL_IFACE */ - - diff --git a/package/network/services/hostapd/patches/460-indicate-features.patch b/package/network/services/hostapd/patches/460-indicate-features.patch new file mode 100644 index 0000000000..7a44da122b --- /dev/null +++ b/package/network/services/hostapd/patches/460-indicate-features.patch @@ -0,0 +1,82 @@ +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -14,6 +14,7 @@ + + #include "utils/common.h" + #include "utils/eloop.h" ++#include "utils/build_features.h" + #include "crypto/random.h" + #include "crypto/tls.h" + #include "common/version.h" +@@ -546,7 +547,7 @@ int main(int argc, char *argv[]) + + wpa_supplicant_event = hostapd_wpa_event; + for (;;) { +- c = getopt(argc, argv, "b:Bde:f:hKP:Ttvg:G:"); ++ c = getopt(argc, argv, "b:Bde:f:hKP:Ttg:G:v::"); + if (c < 0) + break; + switch (c) { +@@ -583,6 +584,8 @@ int main(int argc, char *argv[]) + break; + #endif /* CONFIG_DEBUG_LINUX_TRACING */ + case 'v': ++ if (optarg) ++ exit(!has_feature(optarg)); + show_version(); + exit(1); + break; +--- a/wpa_supplicant/main.c ++++ b/wpa_supplicant/main.c +@@ -12,6 +12,7 @@ + #endif /* __linux__ */ + + #include "common.h" ++#include "build_features.h" + #include "wpa_supplicant_i.h" + #include "driver_i.h" + #include "p2p_supplicant.h" +@@ -161,7 +162,7 @@ int main(int argc, char *argv[]) + + for (;;) { + c = getopt(argc, argv, +- "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuvW"); ++ "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuv::W"); + if (c < 0) + break; + switch (c) { +@@ -259,8 +260,12 @@ int main(int argc, char *argv[]) + break; + #endif /* CONFIG_DBUS */ + case 'v': +- printf("%s\n", wpa_supplicant_version); +- exitcode = 0; ++ if (optarg) { ++ exitcode = !has_feature(optarg); ++ } else { ++ printf("%s\n", wpa_supplicant_version); ++ exitcode = 0; ++ } + goto out; + case 'W': + params.wait_for_monitor++; +--- /dev/null ++++ b/src/utils/build_features.h +@@ -0,0 +1,17 @@ ++#ifndef BUILD_FEATURES_H ++#define BUILD_FEATURES_H ++ ++static inline int has_feature(const char *feat) ++{ ++#ifdef IEEE8021X_EAPOL ++ if (!strcmp(feat, "eap")) ++ return 1; ++#endif ++#ifdef IEEE80211N ++ if (!strcmp(feat, "11n")) ++ return 1; ++#endif ++ return 0; ++} ++ ++#endif /* BUILD_FEATURES_H */ diff --git a/package/network/services/hostapd/patches/470-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/470-hostapd_cli_ifdef.patch new file mode 100644 index 0000000000..5ac0fddf70 --- /dev/null +++ b/package/network/services/hostapd/patches/470-hostapd_cli_ifdef.patch @@ -0,0 +1,50 @@ +--- a/hostapd/hostapd_cli.c ++++ b/hostapd/hostapd_cli.c +@@ -67,7 +67,6 @@ static const char *commands_help = + #ifdef CONFIG_IEEE80211W + " sa_query send SA Query to a station\n" + #endif /* CONFIG_IEEE80211W */ +-#ifdef CONFIG_WPS + " wps_pin [timeout] [addr] add WPS Enrollee PIN\n" + " wps_check_pin verify PIN checksum\n" + " wps_pbc indicate button pushed to initiate PBC\n" +@@ -80,7 +79,6 @@ static const char *commands_help = + " wps_ap_pin [params..] enable/disable AP PIN\n" + " wps_config configure AP\n" + " wps_get_status show current WPS status\n" +-#endif /* CONFIG_WPS */ + " get_config show current configuration\n" + " help show this usage help\n" + " interface [ifname] show interfaces/select interface\n" +@@ -352,7 +350,6 @@ static int hostapd_cli_cmd_sa_query(stru + #endif /* CONFIG_IEEE80211W */ + + +-#ifdef CONFIG_WPS + static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, + char *argv[]) + { +@@ -578,7 +575,6 @@ static int hostapd_cli_cmd_wps_config(st + ssid_hex, argv[1]); + return wpa_ctrl_command(ctrl, buf); + } +-#endif /* CONFIG_WPS */ + + + static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, +@@ -903,7 +899,6 @@ static struct hostapd_cli_cmd hostapd_cl + #ifdef CONFIG_IEEE80211W + { "sa_query", hostapd_cli_cmd_sa_query }, + #endif /* CONFIG_IEEE80211W */ +-#ifdef CONFIG_WPS + { "wps_pin", hostapd_cli_cmd_wps_pin }, + { "wps_check_pin", hostapd_cli_cmd_wps_check_pin }, + { "wps_pbc", hostapd_cli_cmd_wps_pbc }, +@@ -917,7 +912,6 @@ static struct hostapd_cli_cmd hostapd_cl + { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin }, + { "wps_config", hostapd_cli_cmd_wps_config }, + { "wps_get_status", hostapd_cli_cmd_wps_get_status }, +-#endif /* CONFIG_WPS */ + { "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent }, + { "ess_disassoc", hostapd_cli_cmd_ess_disassoc }, + { "get_config", hostapd_cli_cmd_get_config }, diff --git a/package/network/services/hostapd/patches/470-wpa_ie_cap_workaround.patch b/package/network/services/hostapd/patches/470-wpa_ie_cap_workaround.patch deleted file mode 100644 index 00a32229d4..0000000000 --- a/package/network/services/hostapd/patches/470-wpa_ie_cap_workaround.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/src/common/wpa_common.c -+++ b/src/common/wpa_common.c -@@ -959,6 +959,31 @@ const char * wpa_key_mgmt_txt(int key_mg - } - - -+static void wpa_fixup_wpa_ie_rsn(u8 *assoc_ie, const u8 *wpa_msg_ie, -+ size_t rsn_ie_len) -+{ -+ int pos, count; -+ -+ pos = sizeof(struct rsn_ie_hdr) + RSN_SELECTOR_LEN; -+ if (rsn_ie_len < pos + 2) -+ return; -+ -+ count = WPA_GET_LE16(wpa_msg_ie + pos); -+ pos += 2 + count * RSN_SELECTOR_LEN; -+ if (rsn_ie_len < pos + 2) -+ return; -+ -+ count = WPA_GET_LE16(wpa_msg_ie + pos); -+ pos += 2 + count * RSN_SELECTOR_LEN; -+ if (rsn_ie_len < pos + 2) -+ return; -+ -+ if (!assoc_ie[pos] && !assoc_ie[pos + 1] && -+ (wpa_msg_ie[pos] || wpa_msg_ie[pos + 1])) -+ memcpy(&assoc_ie[pos], &wpa_msg_ie[pos], 2); -+} -+ -+ - int wpa_compare_rsn_ie(int ft_initial_assoc, - const u8 *ie1, size_t ie1len, - const u8 *ie2, size_t ie2len) -@@ -966,8 +991,19 @@ int wpa_compare_rsn_ie(int ft_initial_as - if (ie1 == NULL || ie2 == NULL) - return -1; - -- if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0) -- return 0; /* identical IEs */ -+ if (ie1len == ie2len) { -+ u8 *ie_tmp; -+ -+ if (os_memcmp(ie1, ie2, ie1len) == 0) -+ return 0; /* identical IEs */ -+ -+ ie_tmp = alloca(ie1len); -+ memcpy(ie_tmp, ie1, ie1len); -+ wpa_fixup_wpa_ie_rsn(ie_tmp, ie2, ie1len); -+ -+ if (os_memcmp(ie_tmp, ie2, ie1len) == 0) -+ return 0; /* only mismatch in RSN capabilties */ -+ } - - #ifdef CONFIG_IEEE80211R - if (ft_initial_assoc) { diff --git a/package/network/services/hostapd/patches/480-max_num_sta_probe.patch b/package/network/services/hostapd/patches/480-max_num_sta_probe.patch new file mode 100644 index 0000000000..e5ca8b4434 --- /dev/null +++ b/package/network/services/hostapd/patches/480-max_num_sta_probe.patch @@ -0,0 +1,13 @@ +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c +@@ -501,6 +501,10 @@ void handle_probe_req(struct hostapd_dat + return; + } + ++ if (!sta && hapd->num_sta >= hapd->conf->max_num_sta) ++ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " ignored," ++ " too many connected stations.", MAC2STR(mgmt->sa)); ++ + #ifdef CONFIG_INTERWORKING + if (elems.interworking && elems.interworking_len >= 1) { + u8 ant = elems.interworking[0] & 0x0f; diff --git a/package/network/services/hostapd/patches/480-terminate_on_setup_failure.patch b/package/network/services/hostapd/patches/480-terminate_on_setup_failure.patch deleted file mode 100644 index a8f395237c..0000000000 --- a/package/network/services/hostapd/patches/480-terminate_on_setup_failure.patch +++ /dev/null @@ -1,81 +0,0 @@ ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -951,11 +951,8 @@ int hostapd_setup_interface_complete(str - size_t j; - u8 *prev_addr; - -- if (err) { -- wpa_printf(MSG_ERROR, "Interface initialization failed"); -- eloop_terminate(); -- return -1; -- } -+ if (err) -+ goto error; - - wpa_printf(MSG_DEBUG, "Completing interface initialization"); - if (hapd->iconf->channel) { -@@ -975,7 +972,7 @@ int hostapd_setup_interface_complete(str - hapd->iconf->vht_oper_centr_freq_seg1_idx)) { - wpa_printf(MSG_ERROR, "Could not set channel for " - "kernel driver"); -- return -1; -+ goto error; - } - } - -@@ -986,7 +983,7 @@ int hostapd_setup_interface_complete(str - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_WARNING, - "Failed to prepare rates table."); -- return -1; -+ goto error; - } - } - -@@ -994,14 +991,14 @@ int hostapd_setup_interface_complete(str - hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) { - wpa_printf(MSG_ERROR, "Could not set RTS threshold for " - "kernel driver"); -- return -1; -+ goto error; - } - - if (hapd->iconf->fragm_threshold > -1 && - hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) { - wpa_printf(MSG_ERROR, "Could not set fragmentation threshold " - "for kernel driver"); -- return -1; -+ goto error; - } - - prev_addr = hapd->own_addr; -@@ -1011,7 +1008,7 @@ int hostapd_setup_interface_complete(str - if (j) - os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); - if (hostapd_setup_bss(hapd, j == 0)) -- return -1; -+ goto error; - if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) - prev_addr = hapd->own_addr; - } -@@ -1025,7 +1022,7 @@ int hostapd_setup_interface_complete(str - if (hostapd_driver_commit(hapd) < 0) { - wpa_printf(MSG_ERROR, "%s: Failed to commit driver " - "configuration", __func__); -- return -1; -+ goto error; - } - - /* -@@ -1046,6 +1043,11 @@ int hostapd_setup_interface_complete(str - iface->bss[0]->conf->iface); - - return 0; -+ -+error: -+ wpa_printf(MSG_ERROR, "Interface initialization failed"); -+ eloop_terminate(); -+ return -1; - } - - diff --git a/package/network/services/hostapd/patches/490-scan_wait.patch b/package/network/services/hostapd/patches/490-scan_wait.patch new file mode 100644 index 0000000000..61715d6a98 --- /dev/null +++ b/package/network/services/hostapd/patches/490-scan_wait.patch @@ -0,0 +1,66 @@ +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -33,6 +33,8 @@ + extern int wpa_debug_level; + extern int wpa_debug_show_keys; + extern int wpa_debug_timestamp; ++static int daemonize = 0; ++static char *pid_file = NULL; + + extern struct wpa_driver_ops *wpa_drivers[]; + +@@ -147,6 +149,14 @@ static void hostapd_logger_cb(void *ctx, + } + #endif /* CONFIG_NO_HOSTAPD_LOGGER */ + ++static void hostapd_setup_complete_cb(void *ctx) ++{ ++ if (daemonize && os_daemonize(pid_file)) { ++ perror("daemon"); ++ return; ++ } ++ daemonize = 0; ++} + + /** + * hostapd_driver_init - Preparate driver interface +@@ -165,6 +175,8 @@ static int hostapd_driver_init(struct ho + return -1; + } + ++ hapd->setup_complete_cb = hostapd_setup_complete_cb; ++ + /* Initialize the driver interface */ + if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) + b = NULL; +@@ -381,8 +393,6 @@ static void hostapd_global_deinit(const + #endif /* CONFIG_NATIVE_WINDOWS */ + + eap_server_unregister_methods(); +- +- os_daemonize_terminate(pid_file); + } + + +@@ -408,11 +418,6 @@ static int hostapd_global_run(struct hap + } + #endif /* EAP_SERVER_TNC */ + +- if (daemonize && os_daemonize(pid_file)) { +- perror("daemon"); +- return -1; +- } +- + eloop_run(); + + return 0; +@@ -521,8 +526,7 @@ int main(int argc, char *argv[]) + struct hapd_interfaces interfaces; + int ret = 1; + size_t i, j; +- int c, debug = 0, daemonize = 0; +- char *pid_file = NULL; ++ int c, debug = 0; + const char *log_file = NULL; + const char *entropy_file = NULL; + char **bss_config = NULL, **tmp_bss; diff --git a/package/network/services/hostapd/patches/500-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/package/network/services/hostapd/patches/500-wpa_supplicant-add-new-config-params-to-be-used-with.patch new file mode 100644 index 0000000000..544151ef2b --- /dev/null +++ b/package/network/services/hostapd/patches/500-wpa_supplicant-add-new-config-params-to-be-used-with.patch @@ -0,0 +1,209 @@ +From 4bb69d15477e0f2b00e166845341dc933de47c58 Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Sun, 3 Jun 2012 18:22:56 +0200 +Subject: [PATCHv2 601/602] wpa_supplicant: add new config params to be used + with the ibss join command + +Signed-hostap: Antonio Quartulli +--- + src/drivers/driver.h | 6 +++ + wpa_supplicant/config.c | 96 +++++++++++++++++++++++++++++++++++++++ + wpa_supplicant/config_ssid.h | 6 +++ + wpa_supplicant/wpa_supplicant.c | 23 +++++++--- + 4 files changed, 124 insertions(+), 7 deletions(-) + +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -19,6 +19,7 @@ + + #define WPA_SUPPLICANT_DRIVER_VERSION 4 + ++#include "drivers/nl80211_copy.h" + #include "common/defs.h" + #include "utils/list.h" + +@@ -404,6 +405,11 @@ struct wpa_driver_associate_params { + */ + int freq; + ++ int beacon_interval; ++ int fixed_freq; ++ unsigned char rates[NL80211_MAX_SUPP_RATES]; ++ int mcast_rate; ++ + /** + * bg_scan_period - Background scan period in seconds, 0 to disable + * background scan, or -1 to indicate no change to default driver +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -14,6 +14,7 @@ + #include "rsn_supp/wpa.h" + #include "eap_peer/eap.h" + #include "p2p/p2p.h" ++#include "drivers/nl80211_copy.h" + #include "config.h" + + +@@ -1512,6 +1513,97 @@ static char * wpa_config_write_psk_list( + + #endif /* CONFIG_P2P */ + ++static int wpa_config_parse_mcast_rate(const struct parse_data *data, ++ struct wpa_ssid *ssid, int line, ++ const char *value) ++{ ++ ssid->mcast_rate = (int)(strtod(value, NULL) * 10); ++ ++ return 0; ++} ++ ++#ifndef NO_CONFIG_WRITE ++static char * wpa_config_write_mcast_rate(const struct parse_data *data, ++ struct wpa_ssid *ssid) ++{ ++ char *value; ++ int res; ++ ++ if (!ssid->mcast_rate == 0) ++ return NULL; ++ ++ value = os_malloc(6); /* longest: 300.0 */ ++ if (value == NULL) ++ return NULL; ++ res = os_snprintf(value, 5, "%.1f", (double)ssid->mcast_rate / 10); ++ if (res < 0) { ++ os_free(value); ++ return NULL; ++ } ++ return value; ++} ++#endif /* NO_CONFIG_WRITE */ ++ ++static int wpa_config_parse_rates(const struct parse_data *data, ++ struct wpa_ssid *ssid, int line, ++ const char *value) ++{ ++ int i; ++ char *pos, *r, *sptr, *end; ++ double rate; ++ ++ pos = (char *)value; ++ r = strtok_r(pos, ",", &sptr); ++ i = 0; ++ while (pos && i < NL80211_MAX_SUPP_RATES) { ++ rate = 0.0; ++ if (r) ++ rate = strtod(r, &end); ++ ssid->rates[i] = rate * 2; ++ if (*end != '\0' || rate * 2 != ssid->rates[i]) ++ return 1; ++ ++ i++; ++ r = strtok_r(NULL, ",", &sptr); ++ } ++ ++ return 0; ++} ++ ++#ifndef NO_CONFIG_WRITE ++static char * wpa_config_write_rates(const struct parse_data *data, ++ struct wpa_ssid *ssid) ++{ ++ char *value, *pos; ++ int res, i; ++ ++ if (ssid->rates[0] <= 0) ++ return NULL; ++ ++ value = os_malloc(6 * NL80211_MAX_SUPP_RATES + 1); ++ if (value == NULL) ++ return NULL; ++ pos = value; ++ for (i = 0; i < NL80211_MAX_SUPP_RATES - 1; i++) { ++ res = os_snprintf(pos, 6, "%.1f,", (double)ssid->rates[i] / 2); ++ if (res < 0) { ++ os_free(value); ++ return NULL; ++ } ++ pos += res; ++ } ++ res = os_snprintf(pos, 6, "%.1f", ++ (double)ssid->rates[NL80211_MAX_SUPP_RATES - 1] / 2); ++ if (res < 0) { ++ os_free(value); ++ return NULL; ++ } ++ ++ value[6 * NL80211_MAX_SUPP_RATES] = '\0'; ++ return value; ++} ++#endif /* NO_CONFIG_WRITE */ ++ + /* Helper macros for network block parser */ + + #ifdef OFFSET +@@ -1715,6 +1807,9 @@ static const struct parse_data ssid_fiel + { INT(ap_max_inactivity) }, + { INT(dtim_period) }, + { INT(beacon_int) }, ++ { INT_RANGE(fixed_freq, 0, 1) }, ++ { FUNC(rates) }, ++ { FUNC(mcast_rate) }, + }; + + #undef OFFSET +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -12,6 +12,7 @@ + #include "common/defs.h" + #include "utils/list.h" + #include "eap_peer/eap_config.h" ++#include "drivers/nl80211_copy.h" + + #define MAX_SSID_LEN 32 + +@@ -620,6 +621,10 @@ struct wpa_ssid { + * dereferences since it may not be updated in all cases. + */ + void *parent_cred; ++ ++ int fixed_freq; ++ unsigned char rates[NL80211_MAX_SUPP_RATES]; ++ double mcast_rate; + }; + + #endif /* CONFIG_SSID_H */ +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -1623,15 +1623,24 @@ void wpa_supplicant_associate(struct wpa + params.ssid_len = ssid->ssid_len; + } + +- if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set && +- wpa_s->conf->ap_scan == 2) { +- params.bssid = ssid->bssid; +- params.fixed_bssid = 1; ++ if (ssid->mode == WPAS_MODE_IBSS) { ++ if (ssid->bssid_set && wpa_s->conf->ap_scan == 2) { ++ params.bssid = ssid->bssid; ++ params.fixed_bssid = 1; ++ } ++ if (ssid->frequency > 0 && params.freq == 0) ++ /* Initial channel for IBSS */ ++ params.freq = ssid->frequency; ++ params.fixed_freq = ssid->fixed_freq; ++ params.beacon_interval = ssid->beacon_int; ++ i = 0; ++ while (i < NL80211_MAX_SUPP_RATES) { ++ params.rates[i] = ssid->rates[i]; ++ i++; ++ } ++ params.mcast_rate = ssid->mcast_rate; + } + +- if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 && +- params.freq == 0) +- params.freq = ssid->frequency; /* Initial channel for IBSS */ + params.wpa_ie = wpa_ie; + params.wpa_ie_len = wpa_ie_len; + params.pairwise_suite = cipher_pairwise; diff --git a/package/network/services/hostapd/patches/501-driver_nl80211-use-new-parameters-during-ibss-join.patch b/package/network/services/hostapd/patches/501-driver_nl80211-use-new-parameters-during-ibss-join.patch new file mode 100644 index 0000000000..565bbc9762 --- /dev/null +++ b/package/network/services/hostapd/patches/501-driver_nl80211-use-new-parameters-during-ibss-join.patch @@ -0,0 +1,59 @@ +From ffc4445958a3ed4064f2e1bf73fa478a61c5cf7b Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Sun, 3 Jun 2012 18:42:25 +0200 +Subject: [PATCHv2 602/602] driver_nl80211: use new parameters during ibss join + +Signed-hostap: Antonio Quartulli +--- + src/drivers/driver_nl80211.c | 33 ++++++++++++++++++++++++++++++++- + 1 file changed, 32 insertions(+), 1 deletion(-) + +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -7903,7 +7903,7 @@ static int wpa_driver_nl80211_ibss(struc + struct wpa_driver_associate_params *params) + { + struct nl_msg *msg; +- int ret = -1; ++ int ret = -1, i; + int count = 0; + + wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); +@@ -7936,6 +7936,37 @@ retry: + wpa_printf(MSG_DEBUG, " * freq=%d", params->freq); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq); + ++ if (params->fixed_freq) { ++ wpa_printf(MSG_DEBUG, " * fixed_freq"); ++ NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED); ++ } ++ ++ if (params->beacon_interval > 0) { ++ wpa_printf(MSG_DEBUG, " * beacon_interval=%d", ++ params->beacon_interval); ++ NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, ++ params->beacon_interval); ++ } ++ ++ if (params->rates[0] > 0) { ++ wpa_printf(MSG_DEBUG, " * basic_rates:"); ++ i = 0; ++ while (i < NL80211_MAX_SUPP_RATES && ++ params->rates[i] > 0) { ++ wpa_printf(MSG_DEBUG, " %.1f", ++ (double)params->rates[i] / 2); ++ i++; ++ } ++ NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, i, ++ params->rates); ++ } ++ ++ if (params->mcast_rate > 0) { ++ wpa_printf(MSG_DEBUG, " * mcast_rates=%.1f", ++ (double)params->mcast_rate / 10); ++ NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate); ++ } ++ + ret = nl80211_set_conn_keys(params, msg); + if (ret) + goto nla_put_failure; diff --git a/package/network/services/hostapd/patches/502-wpa_s-support-htmode-param.patch b/package/network/services/hostapd/patches/502-wpa_s-support-htmode-param.patch new file mode 100644 index 0000000000..adb20a25c5 --- /dev/null +++ b/package/network/services/hostapd/patches/502-wpa_s-support-htmode-param.patch @@ -0,0 +1,156 @@ +From b9329c5dfeed7d5c55d2117d8dfe326fc40c8fb1 Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Tue, 3 Jul 2012 00:36:24 +0200 +Subject: [PATCH] wpa_s: support htmode param + +possible values are HT20, HT40-, HT40+ and NOHT + +Signed-off-by: Antonio Quartulli +--- + src/drivers/driver.h | 2 ++ + src/drivers/driver_nl80211.c | 16 ++++++++++ + wpa_supplicant/config.c | 66 +++++++++++++++++++++++++++++++++++++++ + wpa_supplicant/config_ssid.h | 2 ++ + wpa_supplicant/wpa_supplicant.c | 2 ++ + 5 files changed, 88 insertions(+) + +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -409,6 +409,8 @@ struct wpa_driver_associate_params { + int fixed_freq; + unsigned char rates[NL80211_MAX_SUPP_RATES]; + int mcast_rate; ++ int ht_set; ++ unsigned int htmode; + + /** + * bg_scan_period - Background scan period in seconds, 0 to disable +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -7967,6 +7967,22 @@ retry: + NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate); + } + ++ if (params->ht_set) { ++ switch(params->htmode) { ++ case NL80211_CHAN_HT20: ++ wpa_printf(MSG_DEBUG, " * ht=HT20"); ++ break; ++ case NL80211_CHAN_HT40PLUS: ++ wpa_printf(MSG_DEBUG, " * ht=HT40+"); ++ break; ++ case NL80211_CHAN_HT40MINUS: ++ wpa_printf(MSG_DEBUG, " * ht=HT40-"); ++ break; ++ } ++ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, ++ params->htmode); ++ } ++ + ret = nl80211_set_conn_keys(params, msg); + if (ret) + goto nla_put_failure; +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -1544,6 +1544,71 @@ static char * wpa_config_write_mcast_rat + } + #endif /* NO_CONFIG_WRITE */ + ++static int wpa_config_parse_htmode(const struct parse_data *data, ++ struct wpa_ssid *ssid, int line, ++ const char *value) ++{ ++ int i; ++ static const struct { ++ const char *name; ++ unsigned int val; ++ } htmap[] = { ++ { .name = "HT20", .val = NL80211_CHAN_HT20, }, ++ { .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, }, ++ { .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, }, ++ { .name = "NOHT", .val = NL80211_CHAN_NO_HT, }, ++ }; ++ ssid->ht_set = 0;; ++ for (i = 0; i < 4; i++) { ++ if (strcasecmp(htmap[i].name, value) == 0) { ++ ssid->htmode = htmap[i].val; ++ ssid->ht_set = 1; ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++#ifndef NO_CONFIG_WRITE ++static char * wpa_config_write_htmode(const struct parse_data *data, ++ struct wpa_ssid *ssid) ++{ ++ char *value; ++ int res; ++ ++ value = os_malloc(6); /* longest: HT40+ */ ++ if (value == NULL) ++ return NULL; ++ ++ switch(ssid->htmode) { ++ case NL80211_CHAN_HT20: ++ res = os_snprintf(value, 4, "HT20"); ++ break; ++ case NL80211_CHAN_HT40PLUS: ++ res = os_snprintf(value, 5, "HT40+"); ++ break; ++ case NL80211_CHAN_HT40MINUS: ++ res = os_snprintf(value, 5, "HT40-"); ++ break; ++ case NL80211_CHAN_NO_HT: ++ res = os_snprintf(value, 4, "NOHT"); ++ break; ++ default: ++ os_free(value); ++ return NULL; ++ } ++ ++ if (res < 0) { ++ os_free(value); ++ return NULL; ++ } ++ ++ return value; ++} ++#endif /* NO_CONFIG_WRITE */ ++ ++ + static int wpa_config_parse_rates(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +@@ -1810,6 +1875,7 @@ static const struct parse_data ssid_fiel + { INT_RANGE(fixed_freq, 0, 1) }, + { FUNC(rates) }, + { FUNC(mcast_rate) }, ++ { FUNC(htmode) }, + }; + + #undef OFFSET +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -625,6 +625,8 @@ struct wpa_ssid { + int fixed_freq; + unsigned char rates[NL80211_MAX_SUPP_RATES]; + double mcast_rate; ++ int ht_set; ++ unsigned int htmode; + }; + + #endif /* CONFIG_SSID_H */ +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -1639,6 +1639,8 @@ void wpa_supplicant_associate(struct wpa + i++; + } + params.mcast_rate = ssid->mcast_rate; ++ params.ht_set = ssid->ht_set; ++ params.htmode = ssid->htmode; + } + + params.wpa_ie = wpa_ie; diff --git a/package/network/services/hostapd/patches/510-bring_down_interface.patch b/package/network/services/hostapd/patches/510-bring_down_interface.patch deleted file mode 100644 index e7520df341..0000000000 --- a/package/network/services/hostapd/patches/510-bring_down_interface.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -8145,12 +8145,7 @@ static int wpa_driver_nl80211_set_mode(s - /* Try to set the mode again while the interface is - * down */ - ret = nl80211_set_mode(drv, drv->ifindex, nlmode); -- if (ret == -EACCES) -- break; -- res = i802_set_iface_flags(bss, 1); -- if (res && !ret) -- ret = -1; -- else if (ret != -EBUSY) -+ if (ret != -EBUSY) - break; - } else - wpa_printf(MSG_DEBUG, "nl80211: Failed to set " -@@ -8163,6 +8158,8 @@ static int wpa_driver_nl80211_set_mode(s - "interface is down"); - drv->nlmode = nlmode; - drv->ignore_if_down_event = 1; -+ if (i802_set_iface_flags(bss, 1)) -+ ret = -1; - } - - done: diff --git a/package/network/services/hostapd/patches/520-fix_wps_pin_crash.patch b/package/network/services/hostapd/patches/520-fix_wps_pin_crash.patch deleted file mode 100644 index 130bd53e08..0000000000 --- a/package/network/services/hostapd/patches/520-fix_wps_pin_crash.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -480,6 +480,9 @@ static int hostapd_ctrl_iface_wps_ap_pin - char *pos; - const char *pin_txt; - -+ if (!hapd->wps) -+ return -1; -+ - pos = os_strchr(txt, ' '); - if (pos) - *pos++ = '\0'; diff --git a/package/network/services/hostapd/patches/530-wps_single_auth_enc_type.patch b/package/network/services/hostapd/patches/530-wps_single_auth_enc_type.patch deleted file mode 100644 index 6f4a6557d5..0000000000 --- a/package/network/services/hostapd/patches/530-wps_single_auth_enc_type.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/src/ap/wps_hostapd.c -+++ b/src/ap/wps_hostapd.c -@@ -989,11 +989,9 @@ int hostapd_init_wps(struct hostapd_data - - if (conf->rsn_pairwise & WPA_CIPHER_CCMP) - wps->encr_types |= WPS_ENCR_AES; -- if (conf->rsn_pairwise & WPA_CIPHER_TKIP) -+ else if (conf->rsn_pairwise & WPA_CIPHER_TKIP) - wps->encr_types |= WPS_ENCR_TKIP; -- } -- -- if (conf->wpa & WPA_PROTO_WPA) { -+ } else if (conf->wpa & WPA_PROTO_WPA) { - if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) - wps->auth_types |= WPS_AUTH_WPAPSK; - if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) -@@ -1001,7 +999,7 @@ int hostapd_init_wps(struct hostapd_data - - if (conf->wpa_pairwise & WPA_CIPHER_CCMP) - wps->encr_types |= WPS_ENCR_AES; -- if (conf->wpa_pairwise & WPA_CIPHER_TKIP) -+ else if (conf->wpa_pairwise & WPA_CIPHER_TKIP) - wps->encr_types |= WPS_ENCR_TKIP; - } - diff --git a/package/network/services/hostapd/patches/540-dynamic_20_40_mhz.patch b/package/network/services/hostapd/patches/540-dynamic_20_40_mhz.patch deleted file mode 100644 index 0ce8772c60..0000000000 --- a/package/network/services/hostapd/patches/540-dynamic_20_40_mhz.patch +++ /dev/null @@ -1,206 +0,0 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2487,6 +2487,10 @@ static int hostapd_config_fill(struct ho - "ht_capab", line); - errors++; - } -+ } else if (os_strcmp(buf, "dynamic_ht40") == 0) { -+ conf->dynamic_ht40 = atoi(pos); -+ if (conf->dynamic_ht40 == 1) -+ conf->dynamic_ht40 = 1500; - } else if (os_strcmp(buf, "require_ht") == 0) { - conf->require_ht = atoi(pos); - #endif /* CONFIG_IEEE80211N */ ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -519,6 +519,7 @@ struct hostapd_config { - int ieee80211n; - int secondary_channel; - int require_ht; -+ int dynamic_ht40; - u32 vht_capab; - int ieee80211ac; - int require_vht; ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -22,6 +22,7 @@ - #include "beacon.h" - #include "iapp.h" - #include "ieee802_1x.h" -+#include "ieee802_11.h" - #include "ieee802_11_auth.h" - #include "vlan_init.h" - #include "wpa_auth.h" -@@ -319,6 +320,7 @@ static void hostapd_cleanup_iface_pre(st - - static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) - { -+ hostapd_deinit_ht(iface); - hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); - iface->hw_features = NULL; - os_free(iface->current_rates); ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -274,6 +274,9 @@ struct hostapd_iface { - /* Overlapping BSS information */ - int olbc_ht; - -+ int force_20mhz; -+ struct os_time last_20mhz_trigger; -+ - u16 ht_op_mode; - void (*scan_cb)(struct hostapd_iface *iface); - }; ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -1513,6 +1513,9 @@ static void handle_beacon(struct hostapd - sizeof(mgmt->u.beacon)), &elems, - 0); - -+ if (!elems.ht_capabilities) -+ hostapd_trigger_20mhz(hapd->iface); -+ - ap_list_process_beacon(hapd->iface, mgmt, &elems, fi); - } - ---- a/src/ap/ieee802_11.h -+++ b/src/ap/ieee802_11.h -@@ -81,4 +81,17 @@ int hostapd_update_time_adv(struct hosta - void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr); - u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid); - -+#ifdef CONFIG_IEEE80211N -+void hostapd_trigger_20mhz(struct hostapd_iface *iface); -+void hostapd_deinit_ht(struct hostapd_iface *iface); -+ -+#else -+static inline void hostapd_deinit_ht(struct hostapd_iface *iface) -+{ -+} -+static inline void hostapd_trigger_20mhz(struct hostapd_iface *iface) -+{ -+} -+#endif /* CONFIG_IEEE80211N */ -+ - #endif /* IEEE802_11_H */ ---- a/src/ap/ieee802_11_ht.c -+++ b/src/ap/ieee802_11_ht.c -@@ -20,9 +20,11 @@ - #include "drivers/driver.h" - #include "hostapd.h" - #include "ap_config.h" -+#include "ap_drv_ops.h" - #include "sta_info.h" - #include "beacon.h" - #include "ieee802_11.h" -+#include "utils/eloop.h" - - - u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid) -@@ -70,12 +72,15 @@ u8 * hostapd_eid_ht_operation(struct hos - - oper->control_chan = hapd->iconf->channel; - oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode); -- if (hapd->iconf->secondary_channel == 1) -- oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE | -- HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH; -- if (hapd->iconf->secondary_channel == -1) -- oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | -- HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH; -+ -+ if (!hapd->iface->force_20mhz) { -+ if (hapd->iconf->secondary_channel == 1) -+ oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE | -+ HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH; -+ if (hapd->iconf->secondary_channel == -1) -+ oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | -+ HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH; -+ } - - pos += sizeof(*oper); - -@@ -270,3 +275,84 @@ void hostapd_get_ht_capab(struct hostapd - - neg_ht_cap->ht_capabilities_info = host_to_le16(cap); - } -+ -+static void hostapd_set_force_20mhz(struct hostapd_iface *iface); -+ -+static void hostapd_restore_40mhz(void *eloop_data, void *user_ctx) -+{ -+ struct hostapd_iface *iface = eloop_data; -+ struct os_time time; -+ int timeout; -+ -+ if (!iface->last_20mhz_trigger.sec) -+ return; -+ -+ os_get_time(&time); -+ timeout = iface->last_20mhz_trigger.sec + iface->conf->dynamic_ht40 - -+ time.sec; -+ -+ if (timeout > 0) { -+ eloop_register_timeout(timeout, 0, hostapd_restore_40mhz, -+ iface, NULL); -+ return; -+ } -+ -+ iface->last_20mhz_trigger.sec = 0; -+ iface->last_20mhz_trigger.usec = 0; -+ -+ iface->force_20mhz = 0; -+ hostapd_set_force_20mhz(iface); -+} -+ -+static void hostapd_set_force_20mhz(struct hostapd_iface *iface) -+{ -+ int secondary_channel; -+ int i; -+ -+ ieee802_11_set_beacons(iface); -+ -+ for (i = 0; i < iface->num_bss; i++) { -+ struct hostapd_data *hapd = iface->bss[i]; -+ -+ if (iface->force_20mhz) -+ secondary_channel = 0; -+ else -+ secondary_channel = hapd->iconf->secondary_channel; -+ -+ if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq, -+ hapd->iconf->channel, -+ hapd->iconf->ieee80211n, -+ hapd->iconf->ieee80211ac, -+ secondary_channel, -+ hapd->iconf->vht_oper_chwidth, -+ hapd->iconf->vht_oper_centr_freq_seg0_idx, -+ hapd->iconf->vht_oper_centr_freq_seg1_idx)) { -+ wpa_printf(MSG_ERROR, "Could not set channel for " -+ "kernel driver"); -+ } -+ } -+} -+ -+void hostapd_deinit_ht(struct hostapd_iface *iface) -+{ -+ eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL); -+} -+ -+void hostapd_trigger_20mhz(struct hostapd_iface *iface) -+{ -+ if (!iface->conf->dynamic_ht40) -+ return; -+ -+ if (!iface->force_20mhz) { -+ iface->force_20mhz = 1; -+ hostapd_set_force_20mhz(iface); -+ } -+ -+ if (!iface->last_20mhz_trigger.sec) { -+ eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL); -+ eloop_register_timeout(iface->conf->dynamic_ht40, 0, -+ hostapd_restore_40mhz, iface, NULL); -+ } -+ -+ os_get_time(&iface->last_20mhz_trigger); -+} diff --git a/package/network/services/hostapd/patches/550-limit_debug_messages.patch b/package/network/services/hostapd/patches/550-limit_debug_messages.patch deleted file mode 100644 index aaea94137f..0000000000 --- a/package/network/services/hostapd/patches/550-limit_debug_messages.patch +++ /dev/null @@ -1,213 +0,0 @@ ---- a/src/utils/wpa_debug.c -+++ b/src/utils/wpa_debug.c -@@ -201,7 +201,7 @@ void wpa_debug_close_linux_tracing(void) - * - * Note: New line '\n' is added to the end of the text when printing to stdout. - */ --void wpa_printf(int level, const char *fmt, ...) -+void _wpa_printf(int level, const char *fmt, ...) - { - va_list ap; - -@@ -248,8 +248,8 @@ void wpa_printf(int level, const char *f - } - - --static void _wpa_hexdump(int level, const char *title, const u8 *buf, -- size_t len, int show) -+void _wpa_hexdump(int level, const char *title, const u8 *buf, -+ size_t len, int show) - { - size_t i; - -@@ -375,20 +375,9 @@ static void _wpa_hexdump(int level, cons - #endif /* CONFIG_ANDROID_LOG */ - } - --void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len) --{ -- _wpa_hexdump(level, title, buf, len, 1); --} -- -- --void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) --{ -- _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); --} - -- --static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, -- size_t len, int show) -+void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, -+ size_t len, int show) - { - size_t i, llen; - const u8 *pos = buf; -@@ -495,19 +484,6 @@ static void _wpa_hexdump_ascii(int level - } - - --void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len) --{ -- _wpa_hexdump_ascii(level, title, buf, len, 1); --} -- -- --void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, -- size_t len) --{ -- _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); --} -- -- - #ifdef CONFIG_DEBUG_FILE - static char *last_path = NULL; - #endif /* CONFIG_DEBUG_FILE */ -@@ -591,7 +567,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_ - } - - --void wpa_msg(void *ctx, int level, const char *fmt, ...) -+void _wpa_msg(void *ctx, int level, const char *fmt, ...) - { - va_list ap; - char *buf; -@@ -625,7 +601,7 @@ void wpa_msg(void *ctx, int level, const - } - - --void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) -+void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) - { - va_list ap; - char *buf; ---- a/src/utils/wpa_debug.h -+++ b/src/utils/wpa_debug.h -@@ -43,6 +43,17 @@ int wpa_debug_open_file(const char *path - int wpa_debug_reopen_file(void); - void wpa_debug_close_file(void); - -+/* internal */ -+void _wpa_hexdump(int level, const char *title, const u8 *buf, -+ size_t len, int show); -+void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, -+ size_t len, int show); -+extern int wpa_debug_show_keys; -+ -+#ifndef CONFIG_MSG_MIN_PRIORITY -+#define CONFIG_MSG_MIN_PRIORITY 0 -+#endif -+ - /** - * wpa_debug_printf_timestamp - Print timestamp for debug output - * -@@ -63,9 +74,15 @@ void wpa_debug_print_timestamp(void); - * - * Note: New line '\n' is added to the end of the text when printing to stdout. - */ --void wpa_printf(int level, const char *fmt, ...) -+void _wpa_printf(int level, const char *fmt, ...) - PRINTF_FORMAT(2, 3); - -+#define wpa_printf(level, ...) \ -+ do { \ -+ if (level >= CONFIG_MSG_MIN_PRIORITY) \ -+ _wpa_printf(level, __VA_ARGS__); \ -+ } while(0) -+ - /** - * wpa_hexdump - conditional hex dump - * @level: priority level (MSG_*) of the message -@@ -77,7 +94,13 @@ PRINTF_FORMAT(2, 3); - * output may be directed to stdout, stderr, and/or syslog based on - * configuration. The contents of buf is printed out has hex dump. - */ --void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len); -+static inline void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len) -+{ -+ if (level < CONFIG_MSG_MIN_PRIORITY) -+ return; -+ -+ _wpa_hexdump(level, title, buf, len, 1); -+} - - static inline void wpa_hexdump_buf(int level, const char *title, - const struct wpabuf *buf) -@@ -99,7 +122,13 @@ static inline void wpa_hexdump_buf(int l - * like wpa_hexdump(), but by default, does not include secret keys (passwords, - * etc.) in debug output. - */ --void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len); -+static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) -+{ -+ if (level < CONFIG_MSG_MIN_PRIORITY) -+ return; -+ -+ _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); -+} - - static inline void wpa_hexdump_buf_key(int level, const char *title, - const struct wpabuf *buf) -@@ -121,8 +150,14 @@ static inline void wpa_hexdump_buf_key(i - * the hex numbers and ASCII characters (for printable range) are shown. 16 - * bytes per line will be shown. - */ --void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, -- size_t len); -+static inline void wpa_hexdump_ascii(int level, const char *title, -+ const u8 *buf, size_t len) -+{ -+ if (level < CONFIG_MSG_MIN_PRIORITY) -+ return; -+ -+ _wpa_hexdump_ascii(level, title, buf, len, 1); -+} - - /** - * wpa_hexdump_ascii_key - conditional hex dump, hide keys -@@ -138,8 +173,14 @@ void wpa_hexdump_ascii(int level, const - * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by - * default, does not include secret keys (passwords, etc.) in debug output. - */ --void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, -- size_t len); -+static inline void wpa_hexdump_ascii_key(int level, const char *title, -+ const u8 *buf, size_t len) -+{ -+ if (level < CONFIG_MSG_MIN_PRIORITY) -+ return; -+ -+ _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); -+} - - /* - * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce -@@ -174,7 +215,12 @@ void wpa_hexdump_ascii_key(int level, co - * - * Note: New line '\n' is added to the end of the text when printing to stdout. - */ --void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); -+void _wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); -+#define wpa_msg(ctx, level, ...) \ -+ do { \ -+ if (level >= CONFIG_MSG_MIN_PRIORITY) \ -+ _wpa_msg(ctx, level, __VA_ARGS__); \ -+ } while(0) - - /** - * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors -@@ -188,8 +234,13 @@ void wpa_msg(void *ctx, int level, const - * attached ctrl_iface monitors. In other words, it can be used for frequent - * events that do not need to be sent to syslog. - */ --void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) -+void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) - PRINTF_FORMAT(3, 4); -+#define wpa_msg_ctrl(ctx, level, ...) \ -+ do { \ -+ if (level >= CONFIG_MSG_MIN_PRIORITY) \ -+ _wpa_msg_ctrl(ctx, level, __VA_ARGS__); \ -+ } while(0) - - /** - * wpa_msg_global - Global printf for ctrl_iface monitors diff --git a/package/network/services/hostapd/patches/560-indicate-features.patch b/package/network/services/hostapd/patches/560-indicate-features.patch deleted file mode 100644 index a719afd1fd..0000000000 --- a/package/network/services/hostapd/patches/560-indicate-features.patch +++ /dev/null @@ -1,82 +0,0 @@ ---- a/hostapd/main.c -+++ b/hostapd/main.c -@@ -14,6 +14,7 @@ - - #include "utils/common.h" - #include "utils/eloop.h" -+#include "utils/build_features.h" - #include "crypto/random.h" - #include "crypto/tls.h" - #include "common/version.h" -@@ -592,7 +593,7 @@ int main(int argc, char *argv[]) - - wpa_supplicant_event = hostapd_wpa_event; - for (;;) { -- c = getopt(argc, argv, "Bde:f:hKP:tvg:G:"); -+ c = getopt(argc, argv, "Bde:f:hKP:tg:G:v::"); - if (c < 0) - break; - switch (c) { -@@ -624,6 +625,8 @@ int main(int argc, char *argv[]) - wpa_debug_timestamp++; - break; - case 'v': -+ if (optarg) -+ exit(!has_feature(optarg)); - show_version(); - exit(1); - break; ---- a/wpa_supplicant/main.c -+++ b/wpa_supplicant/main.c -@@ -12,6 +12,7 @@ - #endif /* __linux__ */ - - #include "common.h" -+#include "build_features.h" - #include "wpa_supplicant_i.h" - #include "driver_i.h" - #include "p2p_supplicant.h" -@@ -161,7 +162,7 @@ int main(int argc, char *argv[]) - - for (;;) { - c = getopt(argc, argv, -- "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuvW"); -+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuv::W"); - if (c < 0) - break; - switch (c) { -@@ -259,8 +260,12 @@ int main(int argc, char *argv[]) - break; - #endif /* CONFIG_DBUS */ - case 'v': -- printf("%s\n", wpa_supplicant_version); -- exitcode = 0; -+ if (optarg) { -+ exitcode = !has_feature(optarg); -+ } else { -+ printf("%s\n", wpa_supplicant_version); -+ exitcode = 0; -+ } - goto out; - case 'W': - params.wait_for_monitor++; ---- /dev/null -+++ b/src/utils/build_features.h -@@ -0,0 +1,17 @@ -+#ifndef BUILD_FEATURES_H -+#define BUILD_FEATURES_H -+ -+static inline int has_feature(const char *feat) -+{ -+#ifdef IEEE8021X_EAPOL -+ if (!strcmp(feat, "eap")) -+ return 1; -+#endif -+#ifdef IEEE80211N -+ if (!strcmp(feat, "11n")) -+ return 1; -+#endif -+ return 0; -+} -+ -+#endif /* BUILD_FEATURES_H */ diff --git a/package/network/services/hostapd/patches/570-genl_connect_debug.patch b/package/network/services/hostapd/patches/570-genl_connect_debug.patch deleted file mode 100644 index 5475cbe9eb..0000000000 --- a/package/network/services/hostapd/patches/570-genl_connect_debug.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -121,7 +121,7 @@ static struct nl_handle * nl_create_hand - } - - if (genl_connect(handle)) { -- wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic " -+ wpa_printf(MSG_DEBUG, "nl80211: Failed to connect to generic " - "netlink (%s)", dbg); - nl80211_handle_destroy(handle); - return NULL; diff --git a/package/network/services/hostapd/patches/590-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/590-hostapd_cli_ifdef.patch deleted file mode 100644 index cbf1e485cd..0000000000 --- a/package/network/services/hostapd/patches/590-hostapd_cli_ifdef.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- a/hostapd/hostapd_cli.c -+++ b/hostapd/hostapd_cli.c -@@ -67,7 +67,6 @@ static const char *commands_help = - #ifdef CONFIG_IEEE80211W - " sa_query send SA Query to a station\n" - #endif /* CONFIG_IEEE80211W */ --#ifdef CONFIG_WPS - " wps_pin [timeout] [addr] add WPS Enrollee PIN\n" - " wps_check_pin verify PIN checksum\n" - " wps_pbc indicate button pushed to initiate PBC\n" -@@ -79,7 +78,6 @@ static const char *commands_help = - #endif /* CONFIG_WPS_NFC */ - " wps_ap_pin [params..] enable/disable AP PIN\n" - " wps_config configure AP\n" --#endif /* CONFIG_WPS */ - " get_config show current configuration\n" - " help show this usage help\n" - " interface [ifname] show interfaces/select interface\n" -@@ -340,7 +338,6 @@ static int hostapd_cli_cmd_sa_query(stru - #endif /* CONFIG_IEEE80211W */ - - --#ifdef CONFIG_WPS - static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, - char *argv[]) - { -@@ -559,7 +556,6 @@ static int hostapd_cli_cmd_wps_config(st - ssid_hex, argv[1]); - return wpa_ctrl_command(ctrl, buf); - } --#endif /* CONFIG_WPS */ - - - static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, -@@ -805,7 +801,6 @@ static struct hostapd_cli_cmd hostapd_cl - #ifdef CONFIG_IEEE80211W - { "sa_query", hostapd_cli_cmd_sa_query }, - #endif /* CONFIG_IEEE80211W */ --#ifdef CONFIG_WPS - { "wps_pin", hostapd_cli_cmd_wps_pin }, - { "wps_check_pin", hostapd_cli_cmd_wps_check_pin }, - { "wps_pbc", hostapd_cli_cmd_wps_pbc }, -@@ -818,7 +813,6 @@ static struct hostapd_cli_cmd hostapd_cl - #endif /* CONFIG_WPS_NFC */ - { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin }, - { "wps_config", hostapd_cli_cmd_wps_config }, --#endif /* CONFIG_WPS */ - { "disassoc_imminent", hostapd_cli_cmd_disassoc_imminent }, - { "ess_disassoc", hostapd_cli_cmd_ess_disassoc }, - { "get_config", hostapd_cli_cmd_get_config }, diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch new file mode 100644 index 0000000000..04af5da7de --- /dev/null +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -0,0 +1,692 @@ +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -105,6 +105,11 @@ OBJS += ../src/common/wpa_common.o + + OBJS += ../src/eapol_auth/eapol_auth_sm.o + ++ifdef CONFIG_UBUS ++CFLAGS += -DUBUS_SUPPORT ++OBJS += ../src/ap/ubus.o ++LIBS += -lubox -lubus ++endif + + ifndef CONFIG_NO_DUMP_STATE + # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -11,6 +11,7 @@ + + #include "common/defs.h" + #include "ap_config.h" ++#include "ubus.h" + + struct wpa_driver_ops; + struct wpa_ctrl_dst; +@@ -105,6 +106,7 @@ struct hostapd_data { + struct hostapd_iface *iface; + struct hostapd_config *iconf; + struct hostapd_bss_config *conf; ++ struct hostapd_ubus_bss ubus; + int interface_added; /* virtual interface added for this BSS */ + unsigned int started:1; + +@@ -256,6 +258,8 @@ struct hostapd_iface { + struct hostapd_config *conf; + char phy[16]; /* Name of the PHY (radio) */ + ++ struct hostapd_ubus_iface ubus; ++ + enum hostapd_iface_state { + HAPD_IFACE_UNINITIALIZED, + HAPD_IFACE_DISABLED, +--- /dev/null ++++ b/src/ap/ubus.c +@@ -0,0 +1,373 @@ ++/* ++ * hostapd / ubus support ++ * Copyright (c) 2013, Felix Fietkau ++ * ++ * This software may be distributed under the terms of the BSD license. ++ * See README for more details. ++ */ ++ ++#include "utils/includes.h" ++#include "utils/common.h" ++#include "utils/eloop.h" ++#include "common/ieee802_11_defs.h" ++#include "hostapd.h" ++#include "sta_info.h" ++#include "ubus.h" ++ ++static struct ubus_context *ctx; ++static struct blob_buf b; ++static int ctx_ref; ++ ++struct ubus_banned_client { ++ struct avl_node avl; ++ u8 addr[ETH_ALEN]; ++}; ++ ++static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) ++{ ++ struct ubus_context *ctx = eloop_ctx; ++ ubus_handle_event(ctx); ++} ++ ++static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) ++{ ++ if (ubus_reconnect(ctx, NULL)) { ++ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); ++ return; ++ } ++ ++ eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); ++} ++ ++static void hostapd_ubus_connection_lost(struct ubus_context *ctx) ++{ ++ eloop_unregister_read_sock(ctx->sock.fd); ++ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); ++} ++ ++static bool hostapd_ubus_init(void) ++{ ++ if (ctx) ++ return true; ++ ++ ctx = ubus_connect(NULL); ++ if (!ctx) ++ return false; ++ ++ ctx->connection_lost = hostapd_ubus_connection_lost; ++ eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); ++ return true; ++} ++ ++static void hostapd_ubus_ref_inc(void) ++{ ++ ctx_ref++; ++} ++ ++static void hostapd_ubus_ref_dec(void) ++{ ++ ctx_ref--; ++ if (!ctx) ++ return; ++ ++ if (ctx_ref) ++ return; ++ ++ eloop_unregister_read_sock(ctx->sock.fd); ++ ubus_free(ctx); ++ ctx = NULL; ++} ++ ++void hostapd_ubus_add_iface(struct hostapd_iface *iface) ++{ ++ if (!hostapd_ubus_init()) ++ return; ++} ++ ++void hostapd_ubus_free_iface(struct hostapd_iface *iface) ++{ ++ if (!ctx) ++ return; ++} ++ ++static void ++hostapd_bss_del_ban(void *eloop_data, void *user_ctx) ++{ ++ struct ubus_banned_client *ban = eloop_data; ++ struct hostapd_data *hapd = user_ctx; ++ ++ avl_delete(&hapd->ubus.banned, &ban->avl); ++ free(ban); ++} ++ ++static void ++hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time) ++{ ++ struct ubus_banned_client *ban; ++ ++ if (time < 0) ++ time = 0; ++ ++ ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); ++ if (!ban) { ++ if (!time) ++ return; ++ ++ ban = os_zalloc(sizeof(*ban)); ++ memcpy(ban->addr, addr, sizeof(ban->addr)); ++ ban->avl.key = ban->addr; ++ avl_insert(&hapd->ubus.banned, &ban->avl); ++ } else { ++ eloop_cancel_timeout(hostapd_bss_del_ban, ban, hapd); ++ if (!time) { ++ hostapd_bss_del_ban(ban, hapd); ++ return; ++ } ++ } ++ ++ eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd); ++} ++ ++static int ++hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *req, const char *method, ++ struct blob_attr *msg) ++{ ++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); ++ struct sta_info *sta; ++ void *list, *c; ++ char mac_buf[20]; ++ static const struct { ++ const char *name; ++ uint32_t flag; ++ } sta_flags[] = { ++ { "auth", WLAN_STA_AUTH }, ++ { "assoc", WLAN_STA_ASSOC }, ++ { "authorized", WLAN_STA_AUTHORIZED }, ++ { "preauth", WLAN_STA_PREAUTH }, ++ { "wds", WLAN_STA_WDS }, ++ { "wmm", WLAN_STA_WMM }, ++ { "ht", WLAN_STA_HT }, ++ { "vht", WLAN_STA_VHT }, ++ { "wps", WLAN_STA_WPS }, ++ { "mfp", WLAN_STA_MFP }, ++ }; ++ ++ blob_buf_init(&b, 0); ++ blobmsg_add_u32(&b, "freq", hapd->iface->freq); ++ list = blobmsg_open_table(&b, "clients"); ++ for (sta = hapd->sta_list; sta; sta = sta->next) { ++ int i; ++ ++ sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); ++ c = blobmsg_open_table(&b, mac_buf); ++ for (i = 0; i < ARRAY_SIZE(sta_flags); i++) ++ blobmsg_add_u8(&b, sta_flags[i].name, ++ !!(sta->flags & sta_flags[i].flag)); ++ blobmsg_add_u32(&b, "aid", sta->aid); ++ blobmsg_close_table(&b, c); ++ } ++ blobmsg_close_array(&b, list); ++ ubus_send_reply(ctx, req, b.head); ++ ++ return 0; ++} ++ ++enum { ++ DEL_CLIENT_ADDR, ++ DEL_CLIENT_REASON, ++ DEL_CLIENT_DEAUTH, ++ DEL_CLIENT_BAN_TIME, ++ __DEL_CLIENT_MAX ++}; ++ ++static const struct blobmsg_policy del_policy[__DEL_CLIENT_MAX] = { ++ [DEL_CLIENT_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, ++ [DEL_CLIENT_REASON] = { "reason", BLOBMSG_TYPE_INT32 }, ++ [DEL_CLIENT_DEAUTH] = { "deauth", BLOBMSG_TYPE_INT8 }, ++ [DEL_CLIENT_BAN_TIME] = { "ban_time", BLOBMSG_TYPE_INT32 }, ++}; ++ ++static int ++hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *req, const char *method, ++ struct blob_attr *msg) ++{ ++ struct blob_attr *tb[__DEL_CLIENT_MAX]; ++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); ++ struct sta_info *sta; ++ bool deauth = false; ++ int reason; ++ u8 addr[ETH_ALEN]; ++ ++ blobmsg_parse(del_policy, __DEL_CLIENT_MAX, tb, blob_data(msg), blob_len(msg)); ++ ++ if (!tb[DEL_CLIENT_ADDR]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ if (hwaddr_aton(blobmsg_data(tb[DEL_CLIENT_ADDR]), addr)) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ if (tb[DEL_CLIENT_REASON]) ++ reason = blobmsg_get_u32(tb[DEL_CLIENT_REASON]); ++ ++ if (tb[DEL_CLIENT_DEAUTH]) ++ deauth = blobmsg_get_bool(tb[DEL_CLIENT_DEAUTH]); ++ ++ sta = ap_get_sta(hapd, addr); ++ if (sta) { ++ if (deauth) { ++ hostapd_drv_sta_deauth(hapd, addr, reason); ++ ap_sta_deauthenticate(hapd, sta, reason); ++ } else { ++ hostapd_drv_sta_disassoc(hapd, addr, reason); ++ ap_sta_disassociate(hapd, sta, reason); ++ } ++ } ++ ++ if (tb[DEL_CLIENT_BAN_TIME]) ++ hostapd_bss_ban_client(hapd, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME])); ++ ++ return 0; ++} ++ ++static void ++blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const u8 *addr) ++{ ++ char *s; ++ ++ s = blobmsg_alloc_string_buffer(buf, name, 20); ++ sprintf(s, MACSTR, MAC2STR(addr)); ++ blobmsg_add_string_buffer(buf); ++} ++ ++static int ++hostapd_bss_list_bans(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *req, const char *method, ++ struct blob_attr *msg) ++{ ++ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); ++ struct ubus_banned_client *ban; ++ void *c; ++ ++ blob_buf_init(&b, 0); ++ c = blobmsg_open_array(&b, "clients"); ++ avl_for_each_element(&hapd->ubus.banned, ban, avl) ++ blobmsg_add_macaddr(&b, NULL, ban->addr); ++ blobmsg_close_array(&b, c); ++ ubus_send_reply(ctx, req, b.head); ++ ++ return 0; ++} ++ ++static const struct ubus_method bss_methods[] = { ++ UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients), ++ UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy), ++ UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans), ++}; ++ ++static struct ubus_object_type bss_object_type = ++ UBUS_OBJECT_TYPE("hostapd_bss", bss_methods); ++ ++static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) ++{ ++ return memcmp(k1, k2, ETH_ALEN); ++} ++ ++void hostapd_ubus_add_bss(struct hostapd_data *hapd) ++{ ++ struct ubus_object *obj = &hapd->ubus.obj; ++ char *name; ++ int ret; ++ ++ if (!hostapd_ubus_init()) ++ return; ++ ++ if (asprintf(&name, "hostapd.%s", hapd->conf->iface) < 0) ++ return; ++ ++ avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); ++ obj->name = name; ++ obj->type = &bss_object_type; ++ obj->methods = bss_object_type.methods; ++ obj->n_methods = bss_object_type.n_methods; ++ ret = ubus_add_object(ctx, obj); ++ hostapd_ubus_ref_inc(); ++} ++ ++void hostapd_ubus_free_bss(struct hostapd_data *hapd) ++{ ++ struct ubus_object *obj = &hapd->ubus.obj; ++ char *name = (char *) obj->name; ++ ++ if (!ctx) ++ return; ++ ++ if (obj->id) { ++ ubus_remove_object(ctx, obj); ++ hostapd_ubus_ref_dec(); ++ } ++ ++ free(name); ++} ++ ++struct ubus_event_req { ++ struct ubus_notify_request nreq; ++ bool deny; ++}; ++ ++static void ++ubus_event_cb(struct ubus_notify_request *req, int idx, int ret) ++{ ++ struct ubus_event_req *ureq = container_of(req, struct ubus_event_req, nreq); ++ ++ if (ret) ++ ureq->deny = true; ++} ++ ++int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) ++{ ++ struct ubus_banned_client *ban; ++ const char *types[HOSTAPD_UBUS_TYPE_MAX] = { ++ [HOSTAPD_UBUS_PROBE_REQ] = "probe", ++ [HOSTAPD_UBUS_AUTH_REQ] = "auth", ++ [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", ++ }; ++ const char *type = "mgmt"; ++ struct ubus_event_req ureq = {}; ++ const u8 *addr; ++ ++ if (req->mgmt_frame) ++ addr = req->mgmt_frame->sa; ++ else ++ addr = req->addr; ++ ++ ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); ++ if (ban) ++ return -2; ++ ++ if (!hapd->ubus.obj.has_subscribers) ++ return 0; ++ ++ if (req->type < ARRAY_SIZE(types)) ++ type = types[req->type]; ++ ++ blob_buf_init(&b, 0); ++ blobmsg_add_macaddr(&b, "address", addr); ++ if (req->mgmt_frame) ++ blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da); ++ if (req->frame_info) ++ blobmsg_add_u32(&b, "signal", req->frame_info->ssi_signal); ++ blobmsg_add_u32(&b, "freq", hapd->iface->freq); ++ ++ if (ubus_notify_async(ctx, &hapd->ubus.obj, type, b.head, &ureq.nreq)) ++ return 0; ++ ++ ureq.nreq.status_cb = ubus_event_cb; ++ ubus_complete_request(ctx, &ureq.nreq.req, 100); ++ ++ if (ureq.deny) ++ return -1; ++ ++ return 0; ++} +--- /dev/null ++++ b/src/ap/ubus.h +@@ -0,0 +1,78 @@ ++/* ++ * hostapd / ubus support ++ * Copyright (c) 2013, Felix Fietkau ++ * ++ * This software may be distributed under the terms of the BSD license. ++ * See README for more details. ++ */ ++#ifndef __HOSTAPD_UBUS_H ++#define __HOSTAPD_UBUS_H ++ ++enum hostapd_ubus_event_type { ++ HOSTAPD_UBUS_PROBE_REQ, ++ HOSTAPD_UBUS_AUTH_REQ, ++ HOSTAPD_UBUS_ASSOC_REQ, ++ HOSTAPD_UBUS_TYPE_MAX ++}; ++ ++struct hostapd_ubus_request { ++ enum hostapd_ubus_event_type type; ++ const struct ieee80211_mgmt *mgmt_frame; ++ const struct hostapd_frame_info *frame_info; ++ const u8 *addr; ++}; ++ ++struct hostapd_iface; ++struct hostapd_data; ++ ++#ifdef UBUS_SUPPORT ++ ++#include ++#include ++ ++struct hostapd_ubus_iface { ++ struct ubus_object obj; ++}; ++ ++struct hostapd_ubus_bss { ++ struct ubus_object obj; ++ struct avl_tree banned; ++}; ++ ++void hostapd_ubus_add_iface(struct hostapd_iface *iface); ++void hostapd_ubus_free_iface(struct hostapd_iface *iface); ++void hostapd_ubus_add_bss(struct hostapd_data *hapd); ++void hostapd_ubus_free_bss(struct hostapd_data *hapd); ++ ++int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req); ++ ++#else ++ ++struct hostapd_ubus_iface {}; ++ ++struct hostapd_ubus_bss {}; ++ ++static inline void hostapd_ubus_add_iface(struct hostapd_iface *iface) ++{ ++} ++ ++static inline void hostapd_ubus_free_iface(struct hostapd_iface *iface) ++{ ++} ++ ++static inline void hostapd_ubus_add_bss(struct hostapd_data *hapd) ++{ ++} ++ ++static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd) ++{ ++} ++ ++static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) ++{ ++ return 0; ++} ++ ++#endif ++ ++#endif +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -262,6 +262,7 @@ static void hostapd_free_hapd_data(struc + hapd->started = 0; + + wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); ++ hostapd_ubus_free_bss(hapd); + iapp_deinit(hapd->iapp); + hapd->iapp = NULL; + accounting_deinit(hapd); +@@ -831,6 +832,8 @@ static int hostapd_setup_bss(struct host + if (hapd->driver && hapd->driver->set_operstate) + hapd->driver->set_operstate(hapd->drv_priv, 1); + ++ hostapd_ubus_add_bss(hapd); ++ + return 0; + } + +@@ -1105,6 +1108,7 @@ int hostapd_setup_interface_complete(str + if (err) + goto error; + ++ hostapd_ubus_add_iface(iface); + wpa_printf(MSG_DEBUG, "Completing interface initialization"); + if (iface->conf->channel) { + #ifdef NEED_AP_MLME +@@ -1213,6 +1217,7 @@ int hostapd_setup_interface_complete(str + + error: + wpa_printf(MSG_ERROR, "Interface initialization failed"); ++ hostapd_ubus_free_iface(iface); + hostapd_set_state(iface, HAPD_IFACE_DISABLED); + if (iface->interfaces && iface->interfaces->terminate_on_error) + eloop_terminate(); +@@ -1534,6 +1539,7 @@ void hostapd_interface_deinit_free(struc + (unsigned int) iface->conf->num_bss); + driver = iface->bss[0]->driver; + drv_priv = iface->bss[0]->drv_priv; ++ hostapd_ubus_free_iface(iface); + hostapd_interface_deinit(iface); + wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", + __func__, driver, drv_priv); +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -535,7 +535,8 @@ static void handle_auth_sae(struct hosta + + + static void handle_auth(struct hostapd_data *hapd, +- const struct ieee80211_mgmt *mgmt, size_t len) ++ const struct ieee80211_mgmt *mgmt, size_t len, ++ struct hostapd_frame_info *fi) + { + u16 auth_alg, auth_transaction, status_code; + u16 resp = WLAN_STATUS_SUCCESS; +@@ -550,6 +551,11 @@ static void handle_auth(struct hostapd_d + size_t resp_ies_len = 0; + char *identity = NULL; + char *radius_cui = NULL; ++ struct hostapd_ubus_request req = { ++ .type = HOSTAPD_UBUS_AUTH_REQ, ++ .mgmt_frame = mgmt, ++ .frame_info = fi, ++ }; + + if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { + wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", +@@ -633,6 +639,14 @@ static void handle_auth(struct hostapd_d + resp = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto fail; + } ++ ++ if (hostapd_ubus_handle_event(hapd, &req)) { ++ wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n", ++ MAC2STR(mgmt->sa)); ++ resp = WLAN_STATUS_UNSPECIFIED_FAILURE; ++ goto fail; ++ } ++ + if (res == HOSTAPD_ACL_PENDING) { + wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR + " waiting for an external authentication", +@@ -1245,13 +1259,18 @@ static void send_assoc_resp(struct hosta + + static void handle_assoc(struct hostapd_data *hapd, + const struct ieee80211_mgmt *mgmt, size_t len, +- int reassoc) ++ int reassoc, struct hostapd_frame_info *fi) + { + u16 capab_info, listen_interval; + u16 resp = WLAN_STATUS_SUCCESS; + const u8 *pos; + int left, i; + struct sta_info *sta; ++ struct hostapd_ubus_request req = { ++ .type = HOSTAPD_UBUS_ASSOC_REQ, ++ .mgmt_frame = mgmt, ++ .frame_info = fi, ++ }; + + if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : + sizeof(mgmt->u.assoc_req))) { +@@ -1350,6 +1369,13 @@ static void handle_assoc(struct hostapd_ + goto fail; + } + ++ if (hostapd_ubus_handle_event(hapd, &req)) { ++ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", ++ MAC2STR(mgmt->sa)); ++ resp = WLAN_STATUS_UNSPECIFIED_FAILURE; ++ goto fail; ++ } ++ + sta->capability = capab_info; + sta->listen_interval = listen_interval; + +@@ -1759,7 +1785,7 @@ void ieee802_11_mgmt(struct hostapd_data + + + if (stype == WLAN_FC_STYPE_PROBE_REQ) { +- handle_probe_req(hapd, mgmt, len, fi->ssi_signal); ++ handle_probe_req(hapd, mgmt, len, fi); + return; + } + +@@ -1774,15 +1800,15 @@ void ieee802_11_mgmt(struct hostapd_data + switch (stype) { + case WLAN_FC_STYPE_AUTH: + wpa_printf(MSG_DEBUG, "mgmt::auth"); +- handle_auth(hapd, mgmt, len); ++ handle_auth(hapd, mgmt, len, fi); + break; + case WLAN_FC_STYPE_ASSOC_REQ: + wpa_printf(MSG_DEBUG, "mgmt::assoc_req"); +- handle_assoc(hapd, mgmt, len, 0); ++ handle_assoc(hapd, mgmt, len, 0, fi); + break; + case WLAN_FC_STYPE_REASSOC_REQ: + wpa_printf(MSG_DEBUG, "mgmt::reassoc_req"); +- handle_assoc(hapd, mgmt, len, 1); ++ handle_assoc(hapd, mgmt, len, 1, fi); + break; + case WLAN_FC_STYPE_DISASSOC: + wpa_printf(MSG_DEBUG, "mgmt::disassoc"); +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c +@@ -398,7 +398,7 @@ static enum ssid_match_result ssid_match + + void handle_probe_req(struct hostapd_data *hapd, + const struct ieee80211_mgmt *mgmt, size_t len, +- int ssi_signal) ++ struct hostapd_frame_info *fi) + { + u8 *resp; + struct ieee802_11_elems elems; +@@ -406,8 +406,14 @@ void handle_probe_req(struct hostapd_dat + size_t ie_len; + struct sta_info *sta = NULL; + size_t i, resp_len; ++ int ssi_signal = fi->ssi_signal; + int noack; + enum ssid_match_result res; ++ struct hostapd_ubus_request req = { ++ .type = HOSTAPD_UBUS_PROBE_REQ, ++ .mgmt_frame = mgmt, ++ .frame_info = fi, ++ }; + + ie = mgmt->u.probe_req.variable; + if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) +@@ -546,6 +552,12 @@ void handle_probe_req(struct hostapd_dat + } + #endif /* CONFIG_P2P */ + ++ if (hostapd_ubus_handle_event(hapd, &req)) { ++ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n", ++ MAC2STR(mgmt->sa)); ++ return; ++ } ++ + /* TODO: verify that supp_rates contains at least one matching rate + * with AP configuration */ + +--- a/src/ap/beacon.h ++++ b/src/ap/beacon.h +@@ -20,7 +20,7 @@ struct ieee80211_mgmt; + + void handle_probe_req(struct hostapd_data *hapd, + const struct ieee80211_mgmt *mgmt, size_t len, +- int ssi_signal); ++ struct hostapd_frame_info *fi); + void ieee802_11_set_beacon(struct hostapd_data *hapd); + void ieee802_11_set_beacons(struct hostapd_iface *iface); + void ieee802_11_update_beacons(struct hostapd_iface *iface); diff --git a/package/network/services/hostapd/patches/601-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/package/network/services/hostapd/patches/601-wpa_supplicant-add-new-config-params-to-be-used-with.patch deleted file mode 100644 index 0e3f248fcf..0000000000 --- a/package/network/services/hostapd/patches/601-wpa_supplicant-add-new-config-params-to-be-used-with.patch +++ /dev/null @@ -1,209 +0,0 @@ -From 4bb69d15477e0f2b00e166845341dc933de47c58 Mon Sep 17 00:00:00 2001 -From: Antonio Quartulli -Date: Sun, 3 Jun 2012 18:22:56 +0200 -Subject: [PATCHv2 601/602] wpa_supplicant: add new config params to be used - with the ibss join command - -Signed-hostap: Antonio Quartulli ---- - src/drivers/driver.h | 6 +++ - wpa_supplicant/config.c | 96 +++++++++++++++++++++++++++++++++++++++ - wpa_supplicant/config_ssid.h | 6 +++ - wpa_supplicant/wpa_supplicant.c | 23 +++++++--- - 4 files changed, 124 insertions(+), 7 deletions(-) - ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -19,6 +19,7 @@ - - #define WPA_SUPPLICANT_DRIVER_VERSION 4 - -+#include "drivers/nl80211_copy.h" - #include "common/defs.h" - - #define HOSTAPD_CHAN_DISABLED 0x00000001 -@@ -370,6 +371,11 @@ struct wpa_driver_associate_params { - */ - int freq; - -+ int beacon_interval; -+ int fixed_freq; -+ unsigned char rates[NL80211_MAX_SUPP_RATES]; -+ int mcast_rate; -+ - /** - * bg_scan_period - Background scan period in seconds, 0 to disable - * background scan, or -1 to indicate no change to default driver ---- a/wpa_supplicant/config.c -+++ b/wpa_supplicant/config.c -@@ -14,6 +14,7 @@ - #include "rsn_supp/wpa.h" - #include "eap_peer/eap.h" - #include "p2p/p2p.h" -+#include "drivers/nl80211_copy.h" - #include "config.h" - - -@@ -1374,6 +1375,97 @@ static char * wpa_config_write_p2p_clien - - #endif /* CONFIG_P2P */ - -+static int wpa_config_parse_mcast_rate(const struct parse_data *data, -+ struct wpa_ssid *ssid, int line, -+ const char *value) -+{ -+ ssid->mcast_rate = (int)(strtod(value, NULL) * 10); -+ -+ return 0; -+} -+ -+#ifndef NO_CONFIG_WRITE -+static char * wpa_config_write_mcast_rate(const struct parse_data *data, -+ struct wpa_ssid *ssid) -+{ -+ char *value; -+ int res; -+ -+ if (!ssid->mcast_rate == 0) -+ return NULL; -+ -+ value = os_malloc(6); /* longest: 300.0 */ -+ if (value == NULL) -+ return NULL; -+ res = os_snprintf(value, 5, "%.1f", (double)ssid->mcast_rate / 10); -+ if (res < 0) { -+ os_free(value); -+ return NULL; -+ } -+ return value; -+} -+#endif /* NO_CONFIG_WRITE */ -+ -+static int wpa_config_parse_rates(const struct parse_data *data, -+ struct wpa_ssid *ssid, int line, -+ const char *value) -+{ -+ int i; -+ char *pos, *r, *sptr, *end; -+ double rate; -+ -+ pos = (char *)value; -+ r = strtok_r(pos, ",", &sptr); -+ i = 0; -+ while (pos && i < NL80211_MAX_SUPP_RATES) { -+ rate = 0.0; -+ if (r) -+ rate = strtod(r, &end); -+ ssid->rates[i] = rate * 2; -+ if (*end != '\0' || rate * 2 != ssid->rates[i]) -+ return 1; -+ -+ i++; -+ r = strtok_r(NULL, ",", &sptr); -+ } -+ -+ return 0; -+} -+ -+#ifndef NO_CONFIG_WRITE -+static char * wpa_config_write_rates(const struct parse_data *data, -+ struct wpa_ssid *ssid) -+{ -+ char *value, *pos; -+ int res, i; -+ -+ if (ssid->rates[0] <= 0) -+ return NULL; -+ -+ value = os_malloc(6 * NL80211_MAX_SUPP_RATES + 1); -+ if (value == NULL) -+ return NULL; -+ pos = value; -+ for (i = 0; i < NL80211_MAX_SUPP_RATES - 1; i++) { -+ res = os_snprintf(pos, 6, "%.1f,", (double)ssid->rates[i] / 2); -+ if (res < 0) { -+ os_free(value); -+ return NULL; -+ } -+ pos += res; -+ } -+ res = os_snprintf(pos, 6, "%.1f", -+ (double)ssid->rates[NL80211_MAX_SUPP_RATES - 1] / 2); -+ if (res < 0) { -+ os_free(value); -+ return NULL; -+ } -+ -+ value[6 * NL80211_MAX_SUPP_RATES] = '\0'; -+ return value; -+} -+#endif /* NO_CONFIG_WRITE */ -+ - /* Helper macros for network block parser */ - - #ifdef OFFSET -@@ -1573,6 +1665,9 @@ static const struct parse_data ssid_fiel - { INT(ap_max_inactivity) }, - { INT(dtim_period) }, - { INT(beacon_int) }, -+ { INT_RANGE(fixed_freq, 0, 1) }, -+ { FUNC(rates) }, -+ { FUNC(mcast_rate) }, - }; - - #undef OFFSET ---- a/wpa_supplicant/config_ssid.h -+++ b/wpa_supplicant/config_ssid.h -@@ -11,6 +11,7 @@ - - #include "common/defs.h" - #include "eap_peer/eap_config.h" -+#include "drivers/nl80211_copy.h" - - #define MAX_SSID_LEN 32 - -@@ -600,6 +601,10 @@ struct wpa_ssid { - * dereferences since it may not be updated in all cases. - */ - void *parent_cred; -+ -+ int fixed_freq; -+ unsigned char rates[NL80211_MAX_SUPP_RATES]; -+ double mcast_rate; - }; - - #endif /* CONFIG_SSID_H */ ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -1594,15 +1594,24 @@ void wpa_supplicant_associate(struct wpa - params.ssid_len = ssid->ssid_len; - } - -- if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set && -- wpa_s->conf->ap_scan == 2) { -- params.bssid = ssid->bssid; -- params.fixed_bssid = 1; -+ if (ssid->mode == WPAS_MODE_IBSS) { -+ if (ssid->bssid_set && wpa_s->conf->ap_scan == 2) { -+ params.bssid = ssid->bssid; -+ params.fixed_bssid = 1; -+ } -+ if (ssid->frequency > 0 && params.freq == 0) -+ /* Initial channel for IBSS */ -+ params.freq = ssid->frequency; -+ params.fixed_freq = ssid->fixed_freq; -+ params.beacon_interval = ssid->beacon_int; -+ i = 0; -+ while (i < NL80211_MAX_SUPP_RATES) { -+ params.rates[i] = ssid->rates[i]; -+ i++; -+ } -+ params.mcast_rate = ssid->mcast_rate; - } - -- if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 && -- params.freq == 0) -- params.freq = ssid->frequency; /* Initial channel for IBSS */ - params.wpa_ie = wpa_ie; - params.wpa_ie_len = wpa_ie_len; - params.pairwise_suite = cipher_pairwise; diff --git a/package/network/services/hostapd/patches/602-driver_nl80211-use-new-parameters-during-ibss-join.patch b/package/network/services/hostapd/patches/602-driver_nl80211-use-new-parameters-during-ibss-join.patch deleted file mode 100644 index a95860260b..0000000000 --- a/package/network/services/hostapd/patches/602-driver_nl80211-use-new-parameters-during-ibss-join.patch +++ /dev/null @@ -1,59 +0,0 @@ -From ffc4445958a3ed4064f2e1bf73fa478a61c5cf7b Mon Sep 17 00:00:00 2001 -From: Antonio Quartulli -Date: Sun, 3 Jun 2012 18:42:25 +0200 -Subject: [PATCHv2 602/602] driver_nl80211: use new parameters during ibss join - -Signed-hostap: Antonio Quartulli ---- - src/drivers/driver_nl80211.c | 33 ++++++++++++++++++++++++++++++++- - 1 file changed, 32 insertions(+), 1 deletion(-) - ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -7570,7 +7570,7 @@ static int wpa_driver_nl80211_ibss(struc - struct wpa_driver_associate_params *params) - { - struct nl_msg *msg; -- int ret = -1; -+ int ret = -1, i; - int count = 0; - - wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); -@@ -7603,6 +7603,37 @@ retry: - wpa_printf(MSG_DEBUG, " * freq=%d", params->freq); - NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq); - -+ if (params->fixed_freq) { -+ wpa_printf(MSG_DEBUG, " * fixed_freq"); -+ NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED); -+ } -+ -+ if (params->beacon_interval > 0) { -+ wpa_printf(MSG_DEBUG, " * beacon_interval=%d", -+ params->beacon_interval); -+ NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, -+ params->beacon_interval); -+ } -+ -+ if (params->rates[0] > 0) { -+ wpa_printf(MSG_DEBUG, " * basic_rates:"); -+ i = 0; -+ while (i < NL80211_MAX_SUPP_RATES && -+ params->rates[i] > 0) { -+ wpa_printf(MSG_DEBUG, " %.1f", -+ (double)params->rates[i] / 2); -+ i++; -+ } -+ NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, i, -+ params->rates); -+ } -+ -+ if (params->mcast_rate > 0) { -+ wpa_printf(MSG_DEBUG, " * mcast_rates=%.1f", -+ (double)params->mcast_rate / 10); -+ NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate); -+ } -+ - ret = nl80211_set_conn_keys(params, msg); - if (ret) - goto nla_put_failure; diff --git a/package/network/services/hostapd/patches/604-wpa_s-support-htmode-param.patch b/package/network/services/hostapd/patches/604-wpa_s-support-htmode-param.patch deleted file mode 100644 index 7b980926d5..0000000000 --- a/package/network/services/hostapd/patches/604-wpa_s-support-htmode-param.patch +++ /dev/null @@ -1,156 +0,0 @@ -From b9329c5dfeed7d5c55d2117d8dfe326fc40c8fb1 Mon Sep 17 00:00:00 2001 -From: Antonio Quartulli -Date: Tue, 3 Jul 2012 00:36:24 +0200 -Subject: [PATCH] wpa_s: support htmode param - -possible values are HT20, HT40-, HT40+ and NOHT - -Signed-off-by: Antonio Quartulli ---- - src/drivers/driver.h | 2 ++ - src/drivers/driver_nl80211.c | 16 ++++++++++ - wpa_supplicant/config.c | 66 +++++++++++++++++++++++++++++++++++++++ - wpa_supplicant/config_ssid.h | 2 ++ - wpa_supplicant/wpa_supplicant.c | 2 ++ - 5 files changed, 88 insertions(+) - ---- a/src/drivers/driver.h -+++ b/src/drivers/driver.h -@@ -375,6 +375,8 @@ struct wpa_driver_associate_params { - int fixed_freq; - unsigned char rates[NL80211_MAX_SUPP_RATES]; - int mcast_rate; -+ int ht_set; -+ unsigned int htmode; - - /** - * bg_scan_period - Background scan period in seconds, 0 to disable ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -7634,6 +7634,22 @@ retry: - NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate); - } - -+ if (params->ht_set) { -+ switch(params->htmode) { -+ case NL80211_CHAN_HT20: -+ wpa_printf(MSG_DEBUG, " * ht=HT20"); -+ break; -+ case NL80211_CHAN_HT40PLUS: -+ wpa_printf(MSG_DEBUG, " * ht=HT40+"); -+ break; -+ case NL80211_CHAN_HT40MINUS: -+ wpa_printf(MSG_DEBUG, " * ht=HT40-"); -+ break; -+ } -+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, -+ params->htmode); -+ } -+ - ret = nl80211_set_conn_keys(params, msg); - if (ret) - goto nla_put_failure; ---- a/wpa_supplicant/config.c -+++ b/wpa_supplicant/config.c -@@ -1406,6 +1406,71 @@ static char * wpa_config_write_mcast_rat - } - #endif /* NO_CONFIG_WRITE */ - -+static int wpa_config_parse_htmode(const struct parse_data *data, -+ struct wpa_ssid *ssid, int line, -+ const char *value) -+{ -+ int i; -+ static const struct { -+ const char *name; -+ unsigned int val; -+ } htmap[] = { -+ { .name = "HT20", .val = NL80211_CHAN_HT20, }, -+ { .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, }, -+ { .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, }, -+ { .name = "NOHT", .val = NL80211_CHAN_NO_HT, }, -+ }; -+ ssid->ht_set = 0;; -+ for (i = 0; i < 4; i++) { -+ if (strcasecmp(htmap[i].name, value) == 0) { -+ ssid->htmode = htmap[i].val; -+ ssid->ht_set = 1; -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+#ifndef NO_CONFIG_WRITE -+static char * wpa_config_write_htmode(const struct parse_data *data, -+ struct wpa_ssid *ssid) -+{ -+ char *value; -+ int res; -+ -+ value = os_malloc(6); /* longest: HT40+ */ -+ if (value == NULL) -+ return NULL; -+ -+ switch(ssid->htmode) { -+ case NL80211_CHAN_HT20: -+ res = os_snprintf(value, 4, "HT20"); -+ break; -+ case NL80211_CHAN_HT40PLUS: -+ res = os_snprintf(value, 5, "HT40+"); -+ break; -+ case NL80211_CHAN_HT40MINUS: -+ res = os_snprintf(value, 5, "HT40-"); -+ break; -+ case NL80211_CHAN_NO_HT: -+ res = os_snprintf(value, 4, "NOHT"); -+ break; -+ default: -+ os_free(value); -+ return NULL; -+ } -+ -+ if (res < 0) { -+ os_free(value); -+ return NULL; -+ } -+ -+ return value; -+} -+#endif /* NO_CONFIG_WRITE */ -+ -+ - static int wpa_config_parse_rates(const struct parse_data *data, - struct wpa_ssid *ssid, int line, - const char *value) -@@ -1668,6 +1733,7 @@ static const struct parse_data ssid_fiel - { INT_RANGE(fixed_freq, 0, 1) }, - { FUNC(rates) }, - { FUNC(mcast_rate) }, -+ { FUNC(htmode) }, - }; - - #undef OFFSET ---- a/wpa_supplicant/config_ssid.h -+++ b/wpa_supplicant/config_ssid.h -@@ -605,6 +605,8 @@ struct wpa_ssid { - int fixed_freq; - unsigned char rates[NL80211_MAX_SUPP_RATES]; - double mcast_rate; -+ int ht_set; -+ unsigned int htmode; - }; - - #endif /* CONFIG_SSID_H */ ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -1610,6 +1610,8 @@ void wpa_supplicant_associate(struct wpa - i++; - } - params.mcast_rate = ssid->mcast_rate; -+ params.ht_set = ssid->ht_set; -+ params.htmode = ssid->htmode; - } - - params.wpa_ie = wpa_ie; diff --git a/package/network/services/hostapd/patches/610-max_num_sta_probe.patch b/package/network/services/hostapd/patches/610-max_num_sta_probe.patch deleted file mode 100644 index 141eb5b6e3..0000000000 --- a/package/network/services/hostapd/patches/610-max_num_sta_probe.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -455,6 +455,10 @@ void handle_probe_req(struct hostapd_dat - return; - } - -+ if (!sta && hapd->num_sta >= hapd->conf->max_num_sta) -+ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " ignored," -+ " too many connected stations.", MAC2STR(mgmt->sa)); -+ - #ifdef CONFIG_INTERWORKING - if (elems.interworking && elems.interworking_len >= 1) { - u8 ant = elems.interworking[0] & 0x0f; diff --git a/package/network/services/hostapd/patches/620-scan_wait.patch b/package/network/services/hostapd/patches/620-scan_wait.patch deleted file mode 100644 index ea1528049c..0000000000 --- a/package/network/services/hostapd/patches/620-scan_wait.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- a/hostapd/main.c -+++ b/hostapd/main.c -@@ -33,6 +33,8 @@ - extern int wpa_debug_level; - extern int wpa_debug_show_keys; - extern int wpa_debug_timestamp; -+static int daemonize = 0; -+static char *pid_file = NULL; - - extern struct wpa_driver_ops *wpa_drivers[]; - -@@ -147,6 +149,14 @@ static void hostapd_logger_cb(void *ctx, - } - #endif /* CONFIG_NO_HOSTAPD_LOGGER */ - -+static void hostapd_setup_complete_cb(void *ctx) -+{ -+ if (daemonize && os_daemonize(pid_file)) { -+ perror("daemon"); -+ return; -+ } -+ daemonize = 0; -+} - - /** - * hostapd_init - Allocate and initialize per-interface data -@@ -190,6 +200,7 @@ static struct hostapd_iface * hostapd_in - if (hapd == NULL) - goto fail; - hapd->msg_ctx = hapd; -+ hapd->setup_complete_cb = hostapd_setup_complete_cb; - } - - return hapd_iface; -@@ -437,8 +448,6 @@ static void hostapd_global_deinit(const - #endif /* CONFIG_NATIVE_WINDOWS */ - - eap_server_unregister_methods(); -- -- os_daemonize_terminate(pid_file); - } - - -@@ -464,11 +473,6 @@ static int hostapd_global_run(struct hap - } - #endif /* EAP_SERVER_TNC */ - -- if (daemonize && os_daemonize(pid_file)) { -- perror("daemon"); -- return -1; -- } -- - eloop_run(); - - return 0; -@@ -572,8 +576,7 @@ int main(int argc, char *argv[]) - struct hapd_interfaces interfaces; - int ret = 1; - size_t i; -- int c, debug = 0, daemonize = 0; -- char *pid_file = NULL; -+ int c, debug = 0; - const char *log_file = NULL; - const char *entropy_file = NULL; - diff --git a/package/network/services/hostapd/patches/630-bool_fix.patch b/package/network/services/hostapd/patches/630-bool_fix.patch deleted file mode 100644 index 6b48006ed8..0000000000 --- a/package/network/services/hostapd/patches/630-bool_fix.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/src/ap/ieee802_1x.c -+++ b/src/ap/ieee802_1x.c -@@ -1934,9 +1934,9 @@ void ieee802_1x_notify_pre_auth(struct e - } - - --static const char * bool_txt(Boolean bool) -+static const char * bool_txt(Boolean bool_val) - { -- return bool ? "TRUE" : "FALSE"; -+ return bool_val ? "TRUE" : "FALSE"; - } - - #ifdef CONFIG_CTRL_IFACE_MIB diff --git a/package/network/services/hostapd/patches/700-ubus_support.patch b/package/network/services/hostapd/patches/700-ubus_support.patch deleted file mode 100644 index c1759c8fb8..0000000000 --- a/package/network/services/hostapd/patches/700-ubus_support.patch +++ /dev/null @@ -1,692 +0,0 @@ ---- a/hostapd/Makefile -+++ b/hostapd/Makefile -@@ -97,6 +97,11 @@ OBJS += ../src/common/wpa_common.o - - OBJS += ../src/eapol_auth/eapol_auth_sm.o - -+ifdef CONFIG_UBUS -+CFLAGS += -DUBUS_SUPPORT -+OBJS += ../src/ap/ubus.o -+LIBS += -lubox -lubus -+endif - - ifndef CONFIG_NO_DUMP_STATE - # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -11,6 +11,7 @@ - - #include "common/defs.h" - #include "ap_config.h" -+#include "ubus.h" - - struct wpa_driver_ops; - struct wpa_ctrl_dst; -@@ -75,6 +76,7 @@ struct hostapd_data { - struct hostapd_iface *iface; - struct hostapd_config *iconf; - struct hostapd_bss_config *conf; -+ struct hostapd_ubus_bss ubus; - int interface_added; /* virtual interface added for this BSS */ - - u8 own_addr[ETH_ALEN]; -@@ -216,6 +218,7 @@ struct hostapd_iface { - void *owner; - char *config_fname; - struct hostapd_config *conf; -+ struct hostapd_ubus_iface ubus; - - size_t num_bss; - struct hostapd_data **bss; ---- /dev/null -+++ b/src/ap/ubus.c -@@ -0,0 +1,373 @@ -+/* -+ * hostapd / ubus support -+ * Copyright (c) 2013, Felix Fietkau -+ * -+ * This software may be distributed under the terms of the BSD license. -+ * See README for more details. -+ */ -+ -+#include "utils/includes.h" -+#include "utils/common.h" -+#include "utils/eloop.h" -+#include "common/ieee802_11_defs.h" -+#include "hostapd.h" -+#include "sta_info.h" -+#include "ubus.h" -+ -+static struct ubus_context *ctx; -+static struct blob_buf b; -+static int ctx_ref; -+ -+struct ubus_banned_client { -+ struct avl_node avl; -+ u8 addr[ETH_ALEN]; -+}; -+ -+static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) -+{ -+ struct ubus_context *ctx = eloop_ctx; -+ ubus_handle_event(ctx); -+} -+ -+static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) -+{ -+ if (ubus_reconnect(ctx, NULL)) { -+ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -+ return; -+ } -+ -+ eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); -+} -+ -+static void hostapd_ubus_connection_lost(struct ubus_context *ctx) -+{ -+ eloop_unregister_read_sock(ctx->sock.fd); -+ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -+} -+ -+static bool hostapd_ubus_init(void) -+{ -+ if (ctx) -+ return true; -+ -+ ctx = ubus_connect(NULL); -+ if (!ctx) -+ return false; -+ -+ ctx->connection_lost = hostapd_ubus_connection_lost; -+ eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); -+ return true; -+} -+ -+static void hostapd_ubus_ref_inc(void) -+{ -+ ctx_ref++; -+} -+ -+static void hostapd_ubus_ref_dec(void) -+{ -+ ctx_ref--; -+ if (!ctx) -+ return; -+ -+ if (ctx_ref) -+ return; -+ -+ eloop_unregister_read_sock(ctx->sock.fd); -+ ubus_free(ctx); -+ ctx = NULL; -+} -+ -+void hostapd_ubus_add_iface(struct hostapd_iface *iface) -+{ -+ if (!hostapd_ubus_init()) -+ return; -+} -+ -+void hostapd_ubus_free_iface(struct hostapd_iface *iface) -+{ -+ if (!ctx) -+ return; -+} -+ -+static void -+hostapd_bss_del_ban(void *eloop_data, void *user_ctx) -+{ -+ struct ubus_banned_client *ban = eloop_data; -+ struct hostapd_data *hapd = user_ctx; -+ -+ avl_delete(&hapd->ubus.banned, &ban->avl); -+ free(ban); -+} -+ -+static void -+hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time) -+{ -+ struct ubus_banned_client *ban; -+ -+ if (time < 0) -+ time = 0; -+ -+ ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); -+ if (!ban) { -+ if (!time) -+ return; -+ -+ ban = os_zalloc(sizeof(*ban)); -+ memcpy(ban->addr, addr, sizeof(ban->addr)); -+ ban->avl.key = ban->addr; -+ avl_insert(&hapd->ubus.banned, &ban->avl); -+ } else { -+ eloop_cancel_timeout(hostapd_bss_del_ban, ban, hapd); -+ if (!time) { -+ hostapd_bss_del_ban(ban, hapd); -+ return; -+ } -+ } -+ -+ eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd); -+} -+ -+static int -+hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct sta_info *sta; -+ void *list, *c; -+ char mac_buf[20]; -+ static const struct { -+ const char *name; -+ uint32_t flag; -+ } sta_flags[] = { -+ { "auth", WLAN_STA_AUTH }, -+ { "assoc", WLAN_STA_ASSOC }, -+ { "authorized", WLAN_STA_AUTHORIZED }, -+ { "preauth", WLAN_STA_PREAUTH }, -+ { "wds", WLAN_STA_WDS }, -+ { "wmm", WLAN_STA_WMM }, -+ { "ht", WLAN_STA_HT }, -+ { "vht", WLAN_STA_VHT }, -+ { "wps", WLAN_STA_WPS }, -+ { "mfp", WLAN_STA_MFP }, -+ }; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_u32(&b, "freq", hapd->iface->freq); -+ list = blobmsg_open_table(&b, "clients"); -+ for (sta = hapd->sta_list; sta; sta = sta->next) { -+ int i; -+ -+ sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); -+ c = blobmsg_open_table(&b, mac_buf); -+ for (i = 0; i < ARRAY_SIZE(sta_flags); i++) -+ blobmsg_add_u8(&b, sta_flags[i].name, -+ !!(sta->flags & sta_flags[i].flag)); -+ blobmsg_add_u32(&b, "aid", sta->aid); -+ blobmsg_close_table(&b, c); -+ } -+ blobmsg_close_array(&b, list); -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+enum { -+ DEL_CLIENT_ADDR, -+ DEL_CLIENT_REASON, -+ DEL_CLIENT_DEAUTH, -+ DEL_CLIENT_BAN_TIME, -+ __DEL_CLIENT_MAX -+}; -+ -+static const struct blobmsg_policy del_policy[__DEL_CLIENT_MAX] = { -+ [DEL_CLIENT_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -+ [DEL_CLIENT_REASON] = { "reason", BLOBMSG_TYPE_INT32 }, -+ [DEL_CLIENT_DEAUTH] = { "deauth", BLOBMSG_TYPE_INT8 }, -+ [DEL_CLIENT_BAN_TIME] = { "ban_time", BLOBMSG_TYPE_INT32 }, -+}; -+ -+static int -+hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct blob_attr *tb[__DEL_CLIENT_MAX]; -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct sta_info *sta; -+ bool deauth = false; -+ int reason; -+ u8 addr[ETH_ALEN]; -+ -+ blobmsg_parse(del_policy, __DEL_CLIENT_MAX, tb, blob_data(msg), blob_len(msg)); -+ -+ if (!tb[DEL_CLIENT_ADDR]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (hwaddr_aton(blobmsg_data(tb[DEL_CLIENT_ADDR]), addr)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (tb[DEL_CLIENT_REASON]) -+ reason = blobmsg_get_u32(tb[DEL_CLIENT_REASON]); -+ -+ if (tb[DEL_CLIENT_DEAUTH]) -+ deauth = blobmsg_get_bool(tb[DEL_CLIENT_DEAUTH]); -+ -+ sta = ap_get_sta(hapd, addr); -+ if (sta) { -+ if (deauth) { -+ hostapd_drv_sta_deauth(hapd, addr, reason); -+ ap_sta_deauthenticate(hapd, sta, reason); -+ } else { -+ hostapd_drv_sta_disassoc(hapd, addr, reason); -+ ap_sta_disassociate(hapd, sta, reason); -+ } -+ } -+ -+ if (tb[DEL_CLIENT_BAN_TIME]) -+ hostapd_bss_ban_client(hapd, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME])); -+ -+ return 0; -+} -+ -+static void -+blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const u8 *addr) -+{ -+ char *s; -+ -+ s = blobmsg_alloc_string_buffer(buf, name, 20); -+ sprintf(s, MACSTR, MAC2STR(addr)); -+ blobmsg_add_string_buffer(buf); -+} -+ -+static int -+hostapd_bss_list_bans(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct ubus_banned_client *ban; -+ void *c; -+ -+ blob_buf_init(&b, 0); -+ c = blobmsg_open_array(&b, "clients"); -+ avl_for_each_element(&hapd->ubus.banned, ban, avl) -+ blobmsg_add_macaddr(&b, NULL, ban->addr); -+ blobmsg_close_array(&b, c); -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+static const struct ubus_method bss_methods[] = { -+ UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients), -+ UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy), -+ UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans), -+}; -+ -+static struct ubus_object_type bss_object_type = -+ UBUS_OBJECT_TYPE("hostapd_bss", bss_methods); -+ -+static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) -+{ -+ return memcmp(k1, k2, ETH_ALEN); -+} -+ -+void hostapd_ubus_add_bss(struct hostapd_data *hapd) -+{ -+ struct ubus_object *obj = &hapd->ubus.obj; -+ char *name; -+ int ret; -+ -+ if (!hostapd_ubus_init()) -+ return; -+ -+ if (asprintf(&name, "hostapd.%s", hapd->conf->iface) < 0) -+ return; -+ -+ avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); -+ obj->name = name; -+ obj->type = &bss_object_type; -+ obj->methods = bss_object_type.methods; -+ obj->n_methods = bss_object_type.n_methods; -+ ret = ubus_add_object(ctx, obj); -+ hostapd_ubus_ref_inc(); -+} -+ -+void hostapd_ubus_free_bss(struct hostapd_data *hapd) -+{ -+ struct ubus_object *obj = &hapd->ubus.obj; -+ char *name = (char *) obj->name; -+ -+ if (!ctx) -+ return; -+ -+ if (obj->id) { -+ ubus_remove_object(ctx, obj); -+ hostapd_ubus_ref_dec(); -+ } -+ -+ free(name); -+} -+ -+struct ubus_event_req { -+ struct ubus_notify_request nreq; -+ bool deny; -+}; -+ -+static void -+ubus_event_cb(struct ubus_notify_request *req, int idx, int ret) -+{ -+ struct ubus_event_req *ureq = container_of(req, struct ubus_event_req, nreq); -+ -+ if (ret) -+ ureq->deny = true; -+} -+ -+int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) -+{ -+ struct ubus_banned_client *ban; -+ const char *types[HOSTAPD_UBUS_TYPE_MAX] = { -+ [HOSTAPD_UBUS_PROBE_REQ] = "probe", -+ [HOSTAPD_UBUS_AUTH_REQ] = "auth", -+ [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", -+ }; -+ const char *type = "mgmt"; -+ struct ubus_event_req ureq = {}; -+ const u8 *addr; -+ -+ if (req->mgmt_frame) -+ addr = req->mgmt_frame->sa; -+ else -+ addr = req->addr; -+ -+ ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); -+ if (ban) -+ return -2; -+ -+ if (!hapd->ubus.obj.has_subscribers) -+ return 0; -+ -+ if (req->type < ARRAY_SIZE(types)) -+ type = types[req->type]; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_macaddr(&b, "address", addr); -+ if (req->mgmt_frame) -+ blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da); -+ if (req->frame_info) -+ blobmsg_add_u32(&b, "signal", req->frame_info->ssi_signal); -+ blobmsg_add_u32(&b, "freq", hapd->iface->freq); -+ -+ if (ubus_notify_async(ctx, &hapd->ubus.obj, type, b.head, &ureq.nreq)) -+ return 0; -+ -+ ureq.nreq.status_cb = ubus_event_cb; -+ ubus_complete_request(ctx, &ureq.nreq.req, 100); -+ -+ if (ureq.deny) -+ return -1; -+ -+ return 0; -+} ---- /dev/null -+++ b/src/ap/ubus.h -@@ -0,0 +1,78 @@ -+/* -+ * hostapd / ubus support -+ * Copyright (c) 2013, Felix Fietkau -+ * -+ * This software may be distributed under the terms of the BSD license. -+ * See README for more details. -+ */ -+#ifndef __HOSTAPD_UBUS_H -+#define __HOSTAPD_UBUS_H -+ -+enum hostapd_ubus_event_type { -+ HOSTAPD_UBUS_PROBE_REQ, -+ HOSTAPD_UBUS_AUTH_REQ, -+ HOSTAPD_UBUS_ASSOC_REQ, -+ HOSTAPD_UBUS_TYPE_MAX -+}; -+ -+struct hostapd_ubus_request { -+ enum hostapd_ubus_event_type type; -+ const struct ieee80211_mgmt *mgmt_frame; -+ const struct hostapd_frame_info *frame_info; -+ const u8 *addr; -+}; -+ -+struct hostapd_iface; -+struct hostapd_data; -+ -+#ifdef UBUS_SUPPORT -+ -+#include -+#include -+ -+struct hostapd_ubus_iface { -+ struct ubus_object obj; -+}; -+ -+struct hostapd_ubus_bss { -+ struct ubus_object obj; -+ struct avl_tree banned; -+}; -+ -+void hostapd_ubus_add_iface(struct hostapd_iface *iface); -+void hostapd_ubus_free_iface(struct hostapd_iface *iface); -+void hostapd_ubus_add_bss(struct hostapd_data *hapd); -+void hostapd_ubus_free_bss(struct hostapd_data *hapd); -+ -+int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req); -+ -+#else -+ -+struct hostapd_ubus_iface {}; -+ -+struct hostapd_ubus_bss {}; -+ -+static inline void hostapd_ubus_add_iface(struct hostapd_iface *iface) -+{ -+} -+ -+static inline void hostapd_ubus_free_iface(struct hostapd_iface *iface) -+{ -+} -+ -+static inline void hostapd_ubus_add_bss(struct hostapd_data *hapd) -+{ -+} -+ -+static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd) -+{ -+} -+ -+static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) -+{ -+ return 0; -+} -+ -+#endif -+ -+#endif ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -241,6 +241,7 @@ static int hostapd_broadcast_wep_set(str - - static void hostapd_free_hapd_data(struct hostapd_data *hapd) - { -+ hostapd_ubus_free_bss(hapd); - iapp_deinit(hapd->iapp); - hapd->iapp = NULL; - accounting_deinit(hapd); -@@ -806,6 +807,8 @@ static int hostapd_setup_bss(struct host - if (hapd->driver && hapd->driver->set_operstate) - hapd->driver->set_operstate(hapd->drv_priv, 1); - -+ hostapd_ubus_add_bss(hapd); -+ - return 0; - } - -@@ -956,6 +959,7 @@ int hostapd_setup_interface_complete(str - if (err) - goto error; - -+ hostapd_ubus_add_iface(iface); - wpa_printf(MSG_DEBUG, "Completing interface initialization"); - if (hapd->iconf->channel) { - iface->freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel); -@@ -1048,6 +1052,7 @@ int hostapd_setup_interface_complete(str - - error: - wpa_printf(MSG_ERROR, "Interface initialization failed"); -+ hostapd_ubus_free_iface(iface); - eloop_terminate(); - return -1; - } -@@ -1146,6 +1151,8 @@ void hostapd_interface_deinit_free(struc - void *drv_priv; - if (iface == NULL) - return; -+ -+ hostapd_ubus_free_iface(iface); - driver = iface->bss[0]->driver; - drv_priv = iface->bss[0]->drv_priv; - hostapd_interface_deinit(iface); ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -535,7 +535,8 @@ static void handle_auth_sae(struct hosta - - - static void handle_auth(struct hostapd_data *hapd, -- const struct ieee80211_mgmt *mgmt, size_t len) -+ const struct ieee80211_mgmt *mgmt, size_t len, -+ struct hostapd_frame_info *fi) - { - u16 auth_alg, auth_transaction, status_code; - u16 resp = WLAN_STATUS_SUCCESS; -@@ -550,6 +551,11 @@ static void handle_auth(struct hostapd_d - size_t resp_ies_len = 0; - char *identity = NULL; - char *radius_cui = NULL; -+ struct hostapd_ubus_request req = { -+ .type = HOSTAPD_UBUS_AUTH_REQ, -+ .mgmt_frame = mgmt, -+ .frame_info = fi, -+ }; - - if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { - printf("handle_auth - too short payload (len=%lu)\n", -@@ -633,6 +639,14 @@ static void handle_auth(struct hostapd_d - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } -+ -+ if (hostapd_ubus_handle_event(hapd, &req)) { -+ wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n", -+ MAC2STR(mgmt->sa)); -+ resp = WLAN_STATUS_UNSPECIFIED_FAILURE; -+ goto fail; -+ } -+ - if (res == HOSTAPD_ACL_PENDING) { - wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR - " waiting for an external authentication", -@@ -1220,13 +1234,18 @@ static void send_assoc_resp(struct hosta - - static void handle_assoc(struct hostapd_data *hapd, - const struct ieee80211_mgmt *mgmt, size_t len, -- int reassoc) -+ int reassoc, struct hostapd_frame_info *fi) - { - u16 capab_info, listen_interval; - u16 resp = WLAN_STATUS_SUCCESS; - const u8 *pos; - int left, i; - struct sta_info *sta; -+ struct hostapd_ubus_request req = { -+ .type = HOSTAPD_UBUS_ASSOC_REQ, -+ .mgmt_frame = mgmt, -+ .frame_info = fi, -+ }; - - if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : - sizeof(mgmt->u.assoc_req))) { -@@ -1325,6 +1344,13 @@ static void handle_assoc(struct hostapd_ - goto fail; - } - -+ if (hostapd_ubus_handle_event(hapd, &req)) { -+ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", -+ MAC2STR(mgmt->sa)); -+ resp = WLAN_STATUS_UNSPECIFIED_FAILURE; -+ goto fail; -+ } -+ - sta->capability = capab_info; - sta->listen_interval = listen_interval; - -@@ -1734,7 +1760,7 @@ void ieee802_11_mgmt(struct hostapd_data - - - if (stype == WLAN_FC_STYPE_PROBE_REQ) { -- handle_probe_req(hapd, mgmt, len, fi->ssi_signal); -+ handle_probe_req(hapd, mgmt, len, fi); - return; - } - -@@ -1749,15 +1775,15 @@ void ieee802_11_mgmt(struct hostapd_data - switch (stype) { - case WLAN_FC_STYPE_AUTH: - wpa_printf(MSG_DEBUG, "mgmt::auth"); -- handle_auth(hapd, mgmt, len); -+ handle_auth(hapd, mgmt, len, fi); - break; - case WLAN_FC_STYPE_ASSOC_REQ: - wpa_printf(MSG_DEBUG, "mgmt::assoc_req"); -- handle_assoc(hapd, mgmt, len, 0); -+ handle_assoc(hapd, mgmt, len, 0, fi); - break; - case WLAN_FC_STYPE_REASSOC_REQ: - wpa_printf(MSG_DEBUG, "mgmt::reassoc_req"); -- handle_assoc(hapd, mgmt, len, 1); -+ handle_assoc(hapd, mgmt, len, 1, fi); - break; - case WLAN_FC_STYPE_DISASSOC: - wpa_printf(MSG_DEBUG, "mgmt::disassoc"); ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -352,7 +352,7 @@ static enum ssid_match_result ssid_match - - void handle_probe_req(struct hostapd_data *hapd, - const struct ieee80211_mgmt *mgmt, size_t len, -- int ssi_signal) -+ struct hostapd_frame_info *fi) - { - u8 *resp; - struct ieee802_11_elems elems; -@@ -360,8 +360,14 @@ void handle_probe_req(struct hostapd_dat - size_t ie_len; - struct sta_info *sta = NULL; - size_t i, resp_len; -+ int ssi_signal = fi->ssi_signal; - int noack; - enum ssid_match_result res; -+ struct hostapd_ubus_request req = { -+ .type = HOSTAPD_UBUS_PROBE_REQ, -+ .mgmt_frame = mgmt, -+ .frame_info = fi, -+ }; - - ie = mgmt->u.probe_req.variable; - if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) -@@ -500,6 +506,12 @@ void handle_probe_req(struct hostapd_dat - } - #endif /* CONFIG_P2P */ - -+ if (hostapd_ubus_handle_event(hapd, &req)) { -+ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n", -+ MAC2STR(mgmt->sa)); -+ return; -+ } -+ - /* TODO: verify that supp_rates contains at least one matching rate - * with AP configuration */ - ---- a/src/ap/beacon.h -+++ b/src/ap/beacon.h -@@ -20,7 +20,7 @@ struct ieee80211_mgmt; - - void handle_probe_req(struct hostapd_data *hapd, - const struct ieee80211_mgmt *mgmt, size_t len, -- int ssi_signal); -+ struct hostapd_frame_info *fi); - void ieee802_11_set_beacon(struct hostapd_data *hapd); - void ieee802_11_set_beacons(struct hostapd_iface *iface); - void ieee802_11_update_beacons(struct hostapd_iface *iface);