@@ -2516,6 +2516,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "rsn_preauth_interfaces") == 0) {
os_free(bss->rsn_preauth_interfaces);
bss->rsn_preauth_interfaces = os_strdup(pos);
+ } else if (os_strcmp(buf, "rsn_preauth_autoconf_bridge") == 0) {
+ bss->rsn_preauth_autoconf_bridge = atoi(pos);
#endif /* CONFIG_RSN_PREAUTH */
#ifdef CONFIG_PEERKEY
} else if (os_strcmp(buf, "peerkey") == 0) {
@@ -1178,7 +1178,17 @@ own_ip_addr=127.0.0.1
# associated stations (e.g., wlan0) should not be added, since
# pre-authentication is only used with APs other than the currently associated
# one.
+# Packets addressed to the local bssid need to appear as "local" to
+# rsn_preauth_interfaces in order to be received. This can be achieved by
+# for example adding dummy interfaces with the bssid to the relevant bridge
+# given in rsn_preauth_interfaces.
#rsn_preauth_interfaces=eth0
+#
+# These dummy interfaces can also be added automatically by setting the
+# following option. It will be applied to all interfaces given in
+# rsn_preauth_interfaces, they need to be bridges.
+# (default: 0 = disabled)
+#rsn_preauth_autoconf_bridge=1
# peerkey: Whether PeerKey negotiation for direct links (IEEE 802.11e) is
# allowed. This is only used with RSN/WPA2.
@@ -318,6 +318,7 @@ struct hostapd_bss_config {
int rsn_pairwise;
int rsn_preauth;
char *rsn_preauth_interfaces;
+ int rsn_preauth_autoconf_bridge;
int peerkey;
#ifdef CONFIG_IEEE80211R
@@ -22,6 +22,9 @@
#include "sta_info.h"
#include "wpa_auth.h"
#include "preauth_auth.h"
+#include "bridge.h"
+#include "dummy.h"
+#include "ifconfig.h"
#ifndef ETH_P_PREAUTH
#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
@@ -97,9 +100,27 @@ static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname)
{
struct rsn_preauth_interface *piface;
+#ifdef CONFIG_LIBNL3_ROUTE
+ char dummy_iface[IFNAMSIZ+1];
+#endif /* CONFIG_LIBNL3_ROUTE */
wpa_printf(MSG_DEBUG, "RSN pre-auth interface '%s'", ifname);
+ if (hapd->conf->rsn_preauth_autoconf_bridge) {
+#ifdef CONFIG_LIBNL3_ROUTE
+ snprintf(dummy_iface, sizeof(dummy_iface), "pre%s",
+ hapd->conf->iface);
+ if (dummy_add(dummy_iface, hapd->own_addr) < 0 ||
+ ifconfig_up(dummy_iface) < 0 ||
+ br_addif(ifname, dummy_iface) < 0)
+ wpa_printf(MSG_ERROR, "Failed to add bssid to "
+ "rsn_preauth_interface %s", ifname);
+#else
+ wpa_printf(MSG_ERROR, "Missing libnl3 - bssid not added to "
+ "rsn_preauth_interface %s", ifname);
+#endif /* CONFIG_LIBNL3_ROUTE */
+ }
+
piface = os_zalloc(sizeof(*piface));
if (piface == NULL)
return -1;
@@ -133,12 +154,24 @@ fail1:
void rsn_preauth_iface_deinit(struct hostapd_data *hapd)
{
struct rsn_preauth_interface *piface, *prev;
+#ifdef CONFIG_LIBNL3_ROUTE
+ char dummy_iface[IFNAMSIZ+1];
+#endif /* CONFIG_LIBNL3_ROUTE */
piface = hapd->preauth_iface;
hapd->preauth_iface = NULL;
while (piface) {
prev = piface;
piface = piface->next;
+ if (hapd->conf->rsn_preauth_autoconf_bridge) {
+#ifdef CONFIG_LIBNL3_ROUTE
+ snprintf(dummy_iface, sizeof(dummy_iface), "pre%s",
+ hapd->conf->iface);
+ ifconfig_down(dummy_iface);
+ br_delif(prev->ifname, dummy_iface);
+ dummy_del(dummy_iface);
+#endif /* CONFIG_LIBNL3_ROUTE */
+ }
l2_packet_deinit(prev->l2);
os_free(prev->ifname);
os_free(prev);