diff mbox

[25/44] Prepare 802.11i pre-authentication for full dynamic vlan.

Message ID 1456314830-12935-26-git-send-email-michael-dev@fami-braun.de
State Changes Requested
Headers show

Commit Message

michael-dev Feb. 24, 2016, 11:53 a.m. UTC
From: Michael Braun <michael-dev@fami-braun.de>

To receive pre-authentication packets on a non-wifi-client-data bridge,
the bssid needs to appear as local mac.

This is implemented by creating an interface of type "dummy" with the mac
address configured as bssid and adding this to the bridge.

Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
---
 hostapd/config_file.c |  2 ++
 hostapd/hostapd.conf  | 10 ++++++++++
 src/ap/ap_config.h    |  1 +
 src/ap/preauth_auth.c | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 46 insertions(+)
diff mbox

Patch

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 2631e8d..d2a6406 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -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) {
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 728712e..e26add5 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -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.
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 4d1aee5..8521e01 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -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
diff --git a/src/ap/preauth_auth.c b/src/ap/preauth_auth.c
index 3e0c800..2284b5d 100644
--- a/src/ap/preauth_auth.c
+++ b/src/ap/preauth_auth.c
@@ -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);