aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-08-06 17:59:12 +0000
committerFelix Fietkau <nbd@openwrt.org>2013-08-06 17:59:12 +0000
commit91f0b411f4aa8b5e0bcb7388141bf85586b82976 (patch)
treebf434184f412c1f77b518258d20952dfdd64cb26
parent39ab281faeca8bbfa0776c989cdcf761f4804e15 (diff)
downloadupstream-91f0b411f4aa8b5e0bcb7388141bf85586b82976.tar.gz
upstream-91f0b411f4aa8b5e0bcb7388141bf85586b82976.tar.bz2
upstream-91f0b411f4aa8b5e0bcb7388141bf85586b82976.zip
hostapd: Fix WDS/WEP usage
WEP in WDS is currently broken in hostapd. Add a patch to fix the issue. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> SVN-Revision: 37733
-rw-r--r--package/network/services/hostapd/patches/710-wds-wep-fix.patch156
1 files changed, 156 insertions, 0 deletions
diff --git a/package/network/services/hostapd/patches/710-wds-wep-fix.patch b/package/network/services/hostapd/patches/710-wds-wep-fix.patch
new file mode 100644
index 0000000000..1411d1fc65
--- /dev/null
+++ b/package/network/services/hostapd/patches/710-wds-wep-fix.patch
@@ -0,0 +1,156 @@
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -296,19 +296,19 @@ int hostapd_vlan_if_remove(struct hostap
+ }
+
+
+-int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, int aid,
+- int val)
++int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
++ const u8 *addr, int aid, int val)
+ {
+ const char *bridge = NULL;
+
+ if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
+- return 0;
++ return -1;
+ if (hapd->conf->wds_bridge[0])
+ bridge = hapd->conf->wds_bridge;
+ else if (hapd->conf->bridge[0])
+ bridge = hapd->conf->bridge;
+ return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
+- bridge);
++ bridge, ifname_wds);
+ }
+
+
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -31,8 +31,8 @@ int hostapd_set_drv_ieee8021x(struct hos
+ int enabled);
+ int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname);
+ int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname);
+-int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, int aid,
+- int val);
++int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
++ const u8 *addr, int aid, int val);
+ int hostapd_sta_add(struct hostapd_data *hapd,
+ const u8 *addr, u16 aid, u16 capability,
+ const u8 *supp_rates, size_t supp_rates_len,
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -1846,6 +1846,29 @@ static void handle_auth_cb(struct hostap
+ }
+ }
+
++static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
++ struct sta_info *sta,
++ char *ifname_wds)
++{
++ int i, idx;
++ struct hostapd_ssid *ssid = sta->ssid;
++
++ if (hapd->conf->ieee802_1x || hapd->conf->wpa)
++ return;
++
++ for (i = 0; i < 4; i++) {
++ if (ssid->wep.key[i] &&
++ hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
++ i == ssid->wep.idx, NULL, 0,
++ ssid->wep.key[i],
++ ssid->wep.len[i])) {
++ wpa_printf(MSG_WARNING,
++ "Could not set WEP keys for WDS interface; %s",
++ ifname_wds);
++ break;
++ }
++ }
++}
+
+ static void handle_assoc_cb(struct hostapd_data *hapd,
+ const struct ieee80211_mgmt *mgmt,
+@@ -1949,8 +1972,15 @@ static void handle_assoc_cb(struct hosta
+ goto fail;
+ }
+
+- if (sta->flags & WLAN_STA_WDS)
+- hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1);
++ if (sta->flags & WLAN_STA_WDS) {
++ int ret;
++ char ifname_wds[IFNAMSIZ + 1];
++
++ ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr,
++ sta->aid, 1);
++ if (!ret)
++ hostapd_set_wds_encryption(hapd, sta, ifname_wds);
++ }
+
+ if (sta->eapol_sm == NULL) {
+ /*
+@@ -2191,11 +2221,18 @@ void ieee802_11_rx_from_unknown(struct h
+ return;
+
+ if (wds && !(sta->flags & WLAN_STA_WDS)) {
++ int ret;
++ char ifname_wds[IFNAMSIZ + 1];
++
+ wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
+ "STA " MACSTR " (aid %u)",
+ MAC2STR(sta->addr), sta->aid);
+ sta->flags |= WLAN_STA_WDS;
+- hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1);
++ ret = hostapd_set_wds_sta(hapd, ifname_wds,
++ sta->addr, sta->aid, 1);
++ if (!ret)
++ hostapd_set_wds_encryption(hapd, sta,
++ ifname_wds);
+ }
+ return;
+ }
+--- a/src/ap/sta_info.c
++++ b/src/ap/sta_info.c
+@@ -129,7 +129,7 @@ void ap_free_sta(struct hostapd_data *ha
+ ap_sta_set_authorized(hapd, sta, 0);
+
+ if (sta->flags & WLAN_STA_WDS)
+- hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 0);
++ hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
+
+ if (!(sta->flags & WLAN_STA_PREAUTH))
+ hostapd_drv_sta_remove(hapd, sta->addr);
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -2057,10 +2057,12 @@ struct wpa_driver_ops {
+ * @val: 1 = bind to 4-address WDS; 0 = unbind
+ * @bridge_ifname: Bridge interface to use for the WDS station or %NULL
+ * to indicate that bridge is not to be used
++ * @ifname_wds: Buffer to return the interface name for the new WDS
++ * station.
+ * Returns: 0 on success, -1 on failure
+ */
+ int (*set_wds_sta)(void *priv, const u8 *addr, int aid, int val,
+- const char *bridge_ifname);
++ const char *bridge_ifname, char *ifname_wds);
+
+ /**
+ * send_action - Transmit an Action frame
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -8744,13 +8744,16 @@ static int have_ifidx(struct wpa_driver_
+
+
+ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
+- const char *bridge_ifname)
++ const char *bridge_ifname, char *ifname_wds)
+ {
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ char name[IFNAMSIZ + 1];
+
+ os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
++ if (ifname_wds)
++ os_strlcpy(ifname_wds, name, IFNAMSIZ + 1);
++
+ wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
+ " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
+ if (val) {