tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: wpa_supplicant / hostap changes



On 26/01/2020 07:07, Robert Elz wrote:
I have an iwm interface I could test that with, I have no idea if
it is hostap capable or not, but given that you say iwi and iwn are
not, I would guess not also.

However, that paytch to wpa_supplicant sounds like it would be
wonderful for iwm users, as the iwm driver has some yet undiscovered
bug where every 1/(rand() % N + 1) (for some unknown, but not large, N)
times the interface should come up it "failed to load firmware" and fails.

While obviously not doing anything to fix whatever bug that is (something
about the iwm cpu states not being correct, it seems) not taking the
interface down and up without a really good reason would really help with
network stability  (if I disable wpa_supplicant, and config the WiFi
manually, which I can do where no WPA security is being used, then the
interface typically runs for weeks without issues, with wpa_supplicant
running it is usually just days, sometimes hours, or less - which might
be related to DHCP lease times, I haven't checked).

I doubt if this change will address your issue :/

So even though I am not likely to contribute much info to your request, I
am going to test the patch - unless it makes things worse, or fails to
work, expect to hear no more from me...

But thanks for this.

Here's a v2 of the patch which merges the two different route(4) processing blocks into one and gives hostapd exactly the same functionality of wpa_supplicant re interface arrival and if up/down responsiveness. I wonder if this was the reason why it manually brought the interface down/up in the first place!

Roy
? bin/hostapd/.gdbinit
? bin/hostapd/hostapd
? bin/hostapd_cli/.gdbinit
? bin/hostapd_cli/hostapd_cli
? bin/wpa_cli/.gdbinit
? bin/wpa_cli/wpa_cli
? bin/wpa_passphrase/.gdbinit
? bin/wpa_passphrase/wpa_passphrase
Index: dist/src/drivers/driver_bsd.c
===================================================================
RCS file: /cvsroot/src/external/bsd/wpa/dist/src/drivers/driver_bsd.c,v
retrieving revision 1.30
diff -u -p -r1.30 driver_bsd.c
--- dist/src/drivers/driver_bsd.c	10 Apr 2019 17:48:07 -0000	1.30
+++ dist/src/drivers/driver_bsd.c	26 Jan 2020 09:41:46 -0000
@@ -133,7 +133,6 @@ bsd_get_drvindex(void *priv, unsigned in
 	return NULL;
 }
 
-#ifndef HOSTAPD
 static struct bsd_driver_data *
 bsd_get_drvname(void *priv, const char *ifname)
 {
@@ -146,7 +145,6 @@ bsd_get_drvname(void *priv, const char *
 	}
 	return NULL;
 }
-#endif /* HOSTAPD */
 
 static int
 bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len)
@@ -340,7 +338,7 @@ bsd_send_mlme_param(void *priv, const u8
 }
 
 static int
-bsd_ctrl_iface(void *priv, int enable)
+bsd_get_iface_flags(void *priv)
 {
 	struct bsd_driver_data *drv = priv;
 	struct ifreq ifr;
@@ -354,24 +352,6 @@ bsd_ctrl_iface(void *priv, int enable)
 		return -1;
 	}
 	drv->flags = ifr.ifr_flags;
-
-	if (enable) {
-		if (ifr.ifr_flags & IFF_UP)
-			return 0;
-		ifr.ifr_flags |= IFF_UP;
-	} else {
-		if (!(ifr.ifr_flags & IFF_UP))
-			return 0;
-		ifr.ifr_flags &= ~IFF_UP;
-	}
-
-	if (ioctl(drv->global->sock, SIOCSIFFLAGS, &ifr) < 0) {
-		wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]: %s",
-			   strerror(errno));
-		return -1;
-	}
-
-	drv->flags = ifr.ifr_flags;
 	return 0;
 }
 
@@ -585,7 +565,7 @@ bsd_set_ieee8021x(void *priv, struct wpa
 			   __func__);
 		return -1;
 	}
-	return bsd_ctrl_iface(priv, 1);
+	return 0;
 }
 
 static void
@@ -681,6 +661,158 @@ bsd_set_opt_ie(void *priv, const u8 *ie,
 	return 0;
 }
 
+static void
+bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
+{
+	struct bsd_driver_global *global = sock_ctx;
+	struct bsd_driver_data *drv;
+	struct msghdr msg;
+	struct if_announcemsghdr *ifan;
+	struct if_msghdr *ifm;
+	struct rt_msghdr *rtm;
+	union wpa_event_data event;
+	struct ieee80211_michael_event *mic;
+	struct ieee80211_leave_event *leave;
+	struct ieee80211_join_event *join;
+	ssize_t n;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = global->event_iov;
+	msg.msg_iovlen = 1;
+	n = recvmsg_realloc(sock, &msg, 0);
+	if (n < 0) {
+		if (errno != EINTR && errno != EAGAIN)
+			wpa_printf(MSG_ERROR, "%s read() failed: %s",
+				   __func__, strerror(errno));
+		return;
+	}
+
+	rtm = (struct rt_msghdr *) global->event_iov[0].iov_base;
+	if (rtm->rtm_version != RTM_VERSION) {
+		wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
+			   rtm->rtm_version);
+		return;
+	}
+	os_memset(&event, 0, sizeof(event));
+	switch (rtm->rtm_type) {
+	case RTM_IFANNOUNCE:
+		ifan = (struct if_announcemsghdr *) rtm;
+		switch (ifan->ifan_what) {
+		case IFAN_DEPARTURE:
+			drv = bsd_get_drvindex(global, ifan->ifan_index);
+			if (drv)
+				drv->if_removed = 1;
+			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+			break;
+		case IFAN_ARRIVAL:
+			drv = bsd_get_drvname(global, ifan->ifan_name);
+			if (drv) {
+				drv->ifindex = ifan->ifan_index;
+				drv->if_removed = 0;
+			}
+			event.interface_status.ievent = EVENT_INTERFACE_ADDED;
+			break;
+		default:
+			wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: unknown action");
+			return;
+		}
+		wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
+			   ifan->ifan_name,
+			   ifan->ifan_what == IFAN_DEPARTURE ?
+				"removed" : "added");
+		os_strlcpy(event.interface_status.ifname, ifan->ifan_name,
+			   sizeof(event.interface_status.ifname));
+		if (drv) {
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
+					     &event);
+			/*
+			 * Set ifindex to zero after sending the event as the
+			 * event might query the driver to ensure a match.
+			 */
+			if (ifan->ifan_what == IFAN_DEPARTURE)
+				drv->ifindex = 0;
+		} else {
+			wpa_supplicant_event_global(global->ctx,
+						    EVENT_INTERFACE_STATUS,
+						    &event);
+		}
+		break;
+	case RTM_IEEE80211:
+		ifan = (struct if_announcemsghdr *) rtm;
+		drv = bsd_get_drvindex(global, ifan->ifan_index);
+		if (drv == NULL)
+			return;
+		switch (ifan->ifan_what) {
+		case RTM_IEEE80211_ASSOC:
+		case RTM_IEEE80211_REASSOC:
+			if (drv->is_ap)
+				break;
+			wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
+			break;
+		case RTM_IEEE80211_DISASSOC:
+			if (drv->is_ap)
+				break;
+			wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
+			break;
+		case RTM_IEEE80211_SCAN:
+			if (drv->is_ap)
+				break;
+			wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS,
+					     NULL);
+			break;
+		case RTM_IEEE80211_LEAVE:
+			leave = (struct ieee80211_leave_event *) &ifan[1];
+			drv_event_disassoc(drv->ctx, leave->iev_addr);
+			break;
+		case RTM_IEEE80211_JOIN:
+#ifdef RTM_IEEE80211_REJOIN
+		case RTM_IEEE80211_REJOIN:
+#endif
+			join = (struct ieee80211_join_event *) &ifan[1];
+			bsd_new_sta(drv, drv->ctx, join->iev_addr);
+			break;
+		case RTM_IEEE80211_REPLAY:
+			/* ignore */
+			break;
+		case RTM_IEEE80211_MICHAEL:
+			mic = (struct ieee80211_michael_event *) &ifan[1];
+			wpa_printf(MSG_DEBUG,
+				"Michael MIC failure wireless event: "
+				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
+				MAC2STR(mic->iev_src));
+
+			os_memset(&event, 0, sizeof(event));
+			event.michael_mic_failure.unicast =
+				!IEEE80211_IS_MULTICAST(mic->iev_dst);
+			wpa_supplicant_event(drv->ctx,
+					     EVENT_MICHAEL_MIC_FAILURE, &event);
+			break;
+		}
+		break;
+	case RTM_IFINFO:
+		ifm = (struct if_msghdr *) rtm;
+		drv = bsd_get_drvindex(global, ifm->ifm_index);
+		if (drv == NULL)
+			return;
+		if ((ifm->ifm_flags & IFF_UP) == 0 &&
+		    (drv->flags & IFF_UP) != 0) {
+			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
+				   drv->ifname);
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED,
+					     NULL);
+		} else if ((ifm->ifm_flags & IFF_UP) != 0 &&
+		    (drv->flags & IFF_UP) == 0) {
+			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",
+				   drv->ifname);
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
+					     NULL);
+		}
+		drv->flags = ifm->ifm_flags;
+		break;
+	}
+}
+
+
 #ifdef HOSTAPD
 
 /*
@@ -799,80 +931,6 @@ bsd_sta_disassoc(void *priv, const u8 *o
 }
 
 static void
-bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
-{
-	struct bsd_driver_global *global = sock_ctx;
-	struct bsd_driver_data *drv;
-	struct msghdr msg;
-	struct if_announcemsghdr *ifan;
-	struct rt_msghdr *rtm;
-	struct ieee80211_michael_event *mic;
-	struct ieee80211_join_event *join;
-	struct ieee80211_leave_event *leave;
-	ssize_t n;
-	union wpa_event_data data;
-
-	memset(&msg, 0, sizeof(msg));
-	msg.msg_iov = global->event_iov;
-	msg.msg_iovlen = 1;
-	n = recvmsg_realloc(sock, &msg, 0);
-	if (n < 0) {
-		if (errno != EINTR && errno != EAGAIN)
-			wpa_printf(MSG_ERROR, "%s read() failed: %s",
-				   __func__, strerror(errno));
-		return;
-	}
-
-	rtm = (struct rt_msghdr *) global->event_iov[0].iov_base;
-	if (rtm->rtm_version != RTM_VERSION) {
-		wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
-			   rtm->rtm_version);
-		return;
-	}
-	switch (rtm->rtm_type) {
-	case RTM_IEEE80211:
-		ifan = (struct if_announcemsghdr *) rtm;
-		drv = bsd_get_drvindex(global, ifan->ifan_index);
-		if (drv == NULL)
-			return;
-		switch (ifan->ifan_what) {
-		case RTM_IEEE80211_ASSOC:
-		case RTM_IEEE80211_REASSOC:
-		case RTM_IEEE80211_DISASSOC:
-		case RTM_IEEE80211_SCAN:
-			break;
-		case RTM_IEEE80211_LEAVE:
-			leave = (struct ieee80211_leave_event *) &ifan[1];
-			drv_event_disassoc(drv->hapd, leave->iev_addr);
-			break;
-		case RTM_IEEE80211_JOIN:
-#ifdef RTM_IEEE80211_REJOIN
-		case RTM_IEEE80211_REJOIN:
-#endif
-			join = (struct ieee80211_join_event *) &ifan[1];
-			bsd_new_sta(drv, drv->hapd, join->iev_addr);
-			break;
-		case RTM_IEEE80211_REPLAY:
-			/* ignore */
-			break;
-		case RTM_IEEE80211_MICHAEL:
-			mic = (struct ieee80211_michael_event *) &ifan[1];
-			wpa_printf(MSG_DEBUG,
-				"Michael MIC failure wireless event: "
-				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
-				MAC2STR(mic->iev_src));
-			os_memset(&data, 0, sizeof(data));
-			data.michael_mic_failure.unicast = 1;
-			data.michael_mic_failure.src = mic->iev_src;
-			wpa_supplicant_event(drv->hapd,
-					     EVENT_MICHAEL_MIC_FAILURE, &data);
-			break;
-		}
-		break;
-	}
-}
-
-static void
 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
 {
 	struct bsd_driver_data *drv = ctx;
@@ -908,8 +966,7 @@ bsd_init(struct hostapd_data *hapd, stru
 	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
 		goto bad;
 
-	/* mark down during setup */
-	if (bsd_ctrl_iface(drv, 0) < 0)
+	if (bsd_get_iface_flags(drv) < 0)
 		goto bad;
 
 	if (bsd_set_mediaopt(drv, IFM_OMASK, IFM_IEEE80211_HOSTAP) < 0) {
@@ -934,8 +991,6 @@ bsd_deinit(void *priv)
 {
 	struct bsd_driver_data *drv = priv;
 
-	if (drv->ifindex != 0)
-		bsd_ctrl_iface(drv, 0);
 	if (drv->sock_xmit != NULL)
 		l2_packet_deinit(drv->sock_xmit);
 	os_free(drv);
@@ -943,13 +998,6 @@ bsd_deinit(void *priv)
 
 
 static int
-bsd_commit(void *priv)
-{
-	return bsd_ctrl_iface(priv, 1);
-}
-
-
-static int
 bsd_set_sta_authorized(void *priv, const u8 *addr,
 		       unsigned int total_flags, unsigned int flags_or,
 		       unsigned int flags_and)
@@ -1201,9 +1249,13 @@ wpa_driver_bsd_scan(void *priv, struct w
 		return -1;
 	}
 
-	/* NB: interface must be marked UP to do a scan */
-	if (bsd_ctrl_iface(drv, 1) < 0)
+	/* NB: interface must be marked UP to do a scan
+	 * BUT it's not our job to bring the interface up */
+	if (!(drv->flags & IFF_UP)) {
+		wpa_printf(MSG_DEBUG, "%s: interface is not up, aborting scan",
+			   __func__);
 		return -1;
+	}
 
 #ifdef IEEE80211_IOC_SCAN_MAX_SSID
 	os_memset(&sr, 0, sizeof(sr));
@@ -1241,157 +1293,6 @@ wpa_driver_bsd_scan(void *priv, struct w
 }
 
 static void
-wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
-{
-	struct bsd_driver_global *global = sock_ctx;
-	struct bsd_driver_data *drv;
-	struct msghdr msg;
-	struct if_announcemsghdr *ifan;
-	struct if_msghdr *ifm;
-	struct rt_msghdr *rtm;
-	union wpa_event_data event;
-	struct ieee80211_michael_event *mic;
-	struct ieee80211_leave_event *leave;
-	struct ieee80211_join_event *join;
-	ssize_t n;
-
-	memset(&msg, 0, sizeof(msg));
-	msg.msg_iov = global->event_iov;
-	msg.msg_iovlen = 1;
-	n = recvmsg_realloc(sock, &msg, 0);
-	if (n < 0) {
-		if (errno != EINTR && errno != EAGAIN)
-			wpa_printf(MSG_ERROR, "%s read() failed: %s",
-				   __func__, strerror(errno));
-		return;
-	}
-
-	rtm = (struct rt_msghdr *) global->event_iov[0].iov_base;
-	if (rtm->rtm_version != RTM_VERSION) {
-		wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
-			   rtm->rtm_version);
-		return;
-	}
-	os_memset(&event, 0, sizeof(event));
-	switch (rtm->rtm_type) {
-	case RTM_IFANNOUNCE:
-		ifan = (struct if_announcemsghdr *) rtm;
-		switch (ifan->ifan_what) {
-		case IFAN_DEPARTURE:
-			drv = bsd_get_drvindex(global, ifan->ifan_index);
-			if (drv)
-				drv->if_removed = 1;
-			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
-			break;
-		case IFAN_ARRIVAL:
-			drv = bsd_get_drvname(global, ifan->ifan_name);
-			if (drv) {
-				drv->ifindex = ifan->ifan_index;
-				drv->if_removed = 0;
-			}
-			event.interface_status.ievent = EVENT_INTERFACE_ADDED;
-			break;
-		default:
-			wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: unknown action");
-			return;
-		}
-		wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
-			   ifan->ifan_name,
-			   ifan->ifan_what == IFAN_DEPARTURE ?
-				"removed" : "added");
-		os_strlcpy(event.interface_status.ifname, ifan->ifan_name,
-			   sizeof(event.interface_status.ifname));
-		if (drv) {
-			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
-					     &event);
-			/*
-			 * Set ifindex to zero after sending the event as the
-			 * event might query the driver to ensure a match.
-			 */
-			if (ifan->ifan_what == IFAN_DEPARTURE)
-				drv->ifindex = 0;
-		} else {
-			wpa_supplicant_event_global(global->ctx,
-						    EVENT_INTERFACE_STATUS,
-						    &event);
-		}
-		break;
-	case RTM_IEEE80211:
-		ifan = (struct if_announcemsghdr *) rtm;
-		drv = bsd_get_drvindex(global, ifan->ifan_index);
-		if (drv == NULL)
-			return;
-		switch (ifan->ifan_what) {
-		case RTM_IEEE80211_ASSOC:
-		case RTM_IEEE80211_REASSOC:
-			if (drv->is_ap)
-				break;
-			wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
-			break;
-		case RTM_IEEE80211_DISASSOC:
-			if (drv->is_ap)
-				break;
-			wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
-			break;
-		case RTM_IEEE80211_SCAN:
-			if (drv->is_ap)
-				break;
-			wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS,
-					     NULL);
-			break;
-		case RTM_IEEE80211_LEAVE:
-			leave = (struct ieee80211_leave_event *) &ifan[1];
-			drv_event_disassoc(drv->ctx, leave->iev_addr);
-			break;
-		case RTM_IEEE80211_JOIN:
-#ifdef RTM_IEEE80211_REJOIN
-		case RTM_IEEE80211_REJOIN:
-#endif
-			join = (struct ieee80211_join_event *) &ifan[1];
-			bsd_new_sta(drv, drv->ctx, join->iev_addr);
-			break;
-		case RTM_IEEE80211_REPLAY:
-			/* ignore */
-			break;
-		case RTM_IEEE80211_MICHAEL:
-			mic = (struct ieee80211_michael_event *) &ifan[1];
-			wpa_printf(MSG_DEBUG,
-				"Michael MIC failure wireless event: "
-				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
-				MAC2STR(mic->iev_src));
-
-			os_memset(&event, 0, sizeof(event));
-			event.michael_mic_failure.unicast =
-				!IEEE80211_IS_MULTICAST(mic->iev_dst);
-			wpa_supplicant_event(drv->ctx,
-					     EVENT_MICHAEL_MIC_FAILURE, &event);
-			break;
-		}
-		break;
-	case RTM_IFINFO:
-		ifm = (struct if_msghdr *) rtm;
-		drv = bsd_get_drvindex(global, ifm->ifm_index);
-		if (drv == NULL)
-			return;
-		if ((ifm->ifm_flags & IFF_UP) == 0 &&
-		    (drv->flags & IFF_UP) != 0) {
-			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
-				   drv->ifname);
-			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED,
-					     NULL);
-		} else if ((ifm->ifm_flags & IFF_UP) != 0 &&
-		    (drv->flags & IFF_UP) == 0) {
-			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",
-				   drv->ifname);
-			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
-					     NULL);
-		}
-		drv->flags = ifm->ifm_flags;
-		break;
-	}
-}
-
-static void
 wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
 			      struct ieee80211req_scan_result *sr)
 {
@@ -1643,8 +1544,7 @@ wpa_driver_bsd_init(void *ctx, const cha
 	if (wpa_driver_bsd_capa(drv))
 		goto fail;
 
-	/* Down interface during setup. */
-	if (bsd_ctrl_iface(drv, 0) < 0)
+	if (bsd_get_iface_flags(drv) < 0)
 		goto fail;
 
 	drv->opmode = get80211opmode(drv);
@@ -1665,11 +1565,11 @@ wpa_driver_bsd_deinit(void *priv)
 	if (drv->ifindex != 0 && !drv->if_removed) {
 		wpa_driver_bsd_set_wpa(drv, 0);
 
-		/* NB: mark interface down */
-		bsd_ctrl_iface(drv, 0);
-
-		wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa,
-						drv->prev_privacy);
+		if (wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa,
+						    drv->prev_privacy) < 0)
+			wpa_printf(MSG_DEBUG,
+				   "%s: failed to restore privacy state",
+				   __func__);
 
 		if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)
 		    < 0)
@@ -1701,9 +1601,7 @@ bsd_global_init(void *ctx)
 #ifdef RO_MSGFILTER
 	unsigned char msgfilter[] = {
 		RTM_IEEE80211,
-#ifndef HOSTAPD
 		RTM_IFINFO, RTM_IFANNOUNCE,
-#endif
 	};
 #endif
 
@@ -1735,15 +1633,9 @@ bsd_global_init(void *ctx)
 			   strerror(errno));
 #endif
 
-#ifdef HOSTAPD
 	eloop_register_read_sock(global->route, bsd_wireless_event_receive,
 				 NULL, global);
 
-#else /* HOSTAPD */
-	eloop_register_read_sock(global->route, wpa_driver_bsd_event_receive,
-				 NULL, global);
-#endif /* HOSTAPD */
-
 	return global;
 
 fail:
@@ -1781,7 +1673,6 @@ const struct wpa_driver_ops wpa_driver_b
 	.sta_disassoc		= bsd_sta_disassoc,
 	.sta_deauth		= bsd_sta_deauth,
 	.sta_set_flags		= bsd_set_sta_authorized,
-	.commit			= bsd_commit,
 #else /* HOSTAPD */
 	.init2			= wpa_driver_bsd_init,
 	.deinit			= wpa_driver_bsd_deinit,


Home | Main Index | Thread Index | Old Index