[PATCH] WDS: Fix WEP usage

Sujith Manoharan sujith
Tue Jul 9 02:48:18 PDT 2013


From: Sujith Manoharan <c_manoha at qca.qualcomm.com>

The static WEP keys have to be configured for the new VLAN
interface that is created for a 4addr WDS peer, not doing so
breaks WEP functionality in nl80211/4addr based WDS links.

Signed-hostap: Sujith Manoharan <c_manoha at qca.qualcomm.com>
---
 src/ap/ap_drv_ops.c          |  8 ++++----
 src/ap/ap_drv_ops.h          |  4 ++--
 src/ap/ieee802_11.c          | 43 ++++++++++++++++++++++++++++++++++++++++---
 src/ap/sta_info.c            |  2 +-
 src/drivers/driver.h         |  4 +++-
 src/drivers/driver_nl80211.c |  5 ++++-
 6 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 8205d13..3072562 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -296,19 +296,19 @@ 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)
 {
 	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);
 }
 
 
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 70fab55..cfc30ce 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -31,8 +31,8 @@ int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
 			      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,
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 5503af1..2807bff 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1817,6 +1817,29 @@ static void handle_auth_cb(struct hostapd_data *hapd,
 	}
 }
 
+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,
@@ -1920,8 +1943,15 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
 		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) {
 		/*
@@ -2162,11 +2192,18 @@ void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
 			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;
 	}
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 833f1b2..21235f2 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -129,7 +129,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 	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);
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 3b7e400..cb36391 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2049,10 +2049,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
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 0115533..aec1150 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -8653,13 +8653,16 @@ static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
 
 
 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) {
-- 
1.8.3.2




More information about the Hostap mailing list