aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2013-07-20 14:41:22 (GMT)
committerJouni Malinen <j@w1.fi>2013-07-20 14:41:22 (GMT)
commit69dd2967db680a2dafc6f86feedb4730dc93a015 (patch)
treec7c59103083f6c43e4c24740fb2d2ebac1fd853e
parentc8ebeda4060121f09461705d87d2f9c1399668d5 (diff)
downloadhostap-69dd2967db680a2dafc6f86feedb4730dc93a015.zip
hostap-69dd2967db680a2dafc6f86feedb4730dc93a015.tar.gz
hostap-69dd2967db680a2dafc6f86feedb4730dc93a015.tar.bz2
WDS: Fix WEP usage with nl80211 wds_sta=1
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@qca.qualcomm.com>
-rw-r--r--src/ap/ap_drv_ops.c8
-rw-r--r--src/ap/ap_drv_ops.h4
-rw-r--r--src/ap/ieee802_11.c44
-rw-r--r--src/ap/sta_info.c2
-rw-r--r--src/drivers/driver.h4
-rw-r--r--src/drivers/driver_nl80211.c5
6 files changed, 55 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..35282af 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1818,6 +1818,30 @@ 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;
+ 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,
size_t len, int reassoc, int ok)
@@ -1920,8 +1944,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 +2193,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 4b7bf80..980f913 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2050,10 +2050,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 or %NULL to indicate name is not returned.
* 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 4c0c24d..4b15ff6 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -8672,13 +8672,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) {