Cumulative patch from commit c06c9099f0d0827feae5622097bd8ac946eca5ea
c06c909 Use stronger PRNG for MS-MPPE-Send/Recv-Key salt
9e1f1bd eloop: Clean up coding style for eloop debug prints
f9982b3 Implement kqueue(2) support via CONFIG_ELOOP_KQUEUE
2e69bdd eloop: Add eloop_sock_requeue()
70f4f05 wpa_ctrl: Retry select() on EINTR
df9e2c2 D-Bus: Don't do <deny send_interface="..." /> in dbus service file
9684c75 mesh: Fix peer link counting when a mesh peer reconnects
83fe38b P2P: Fall back to no VHT when starting AP/P2P GO
360a9d5 P2P: Reduce off channel wait time for some P2P Action frames
1fc63fe RADIUS: Share a single function for generating session IDs
2cbc6ff RADIUS: Redesign Request Authenticator generation
b71a64a Send an Acct-Multi-Session-Id attribute in Access-Request packets
4260e1a Add Acct-Session-Id to Accounting-On/Off
d72a005 RADIUS: Use more likely unique accounting Acct-{,Multi-}Session-Id
d689317 EAPOL auth: Move radius_cui/identity freeing to eapol_auth_free()
0ae86f9 wpa_supplicant: Fix couple of C++ compiler errors with header files
9b6177a Add Event-Timestamp to all Accounting-Request packets
d179089 GAS: Calculate response buffer length of ANQP elements
dda091c OpenSSL: Fix server side PKCS#12 processing with extra certificates
443c8e1 OpenSSL: Fix possible null pointer dereference on an OCSP error path
a3cc64f Remove -w support from wpa_supplicant README
e265838 EAP-FAST: Fix an error path in PAC binary format parsing
f91e11f D-Bus: Fix p2p interface capability message
479f46c Do not send Acct-Authentic in Accounting-On/Off
696544e RADIUS: Do not include Acct-Terminate-Cause in Accounting-On/Off
236053e Make fallback from HT40 to HT20 work
cb22e3b BSD: Zero ifindex on interface removal
a8ef133 Android: Support multiple CA certs when connecting to EAP network
80ce804 WNM: Workaround for broken AP operating class behavior
af06093 BSD: Disable interface on down
dc0ad60 BSD: Use correct ifindex from route messages
5f17b2c BSD: __FUNCTION__ -> __func__
2088ecb OSU: Add debug printing of more LogotypeExtn fields
0b905c8 Add the selector suite into wpa_parse_wpa_ie_rsn() "invalid group cipher"
03a72ea VHT: Add an interoperability workaround for 80+80 and 160 MHz channels
Change-Id: Ief9174bdec380e81025e1467c47bf1656eb39cd9
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index 780c19b..99f3504 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -62,6 +62,7 @@
struct l2_packet_data *sock_xmit;/* raw packet xmit socket */
char ifname[IFNAMSIZ+1]; /* interface name */
+ int flags;
unsigned int ifindex; /* interface index */
void *ctx;
struct wpa_driver_capa capa; /* driver capability */
@@ -93,6 +94,9 @@
struct bsd_driver_data *drv = priv;
struct ieee80211req ireq;
+ if (drv->ifindex == 0)
+ return -1;
+
os_memset(&ireq, 0, sizeof(ireq));
os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name));
ireq.i_type = op;
@@ -287,6 +291,7 @@
strerror(errno));
return -1;
}
+ drv->flags = ifr.ifr_flags;
if (enable) {
if (ifr.ifr_flags & IFF_UP)
@@ -304,6 +309,7 @@
return -1;
}
+ drv->flags = ifr.ifr_flags;
return 0;
}
@@ -773,12 +779,12 @@
rtm->rtm_version);
return;
}
- drv = bsd_get_drvindex(global, rtm->rtm_index);
- if (drv == NULL)
- 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:
@@ -878,7 +884,8 @@
{
struct bsd_driver_data *drv = priv;
- bsd_ctrl_iface(drv, 0);
+ if (drv->ifindex != 0)
+ bsd_ctrl_iface(drv, 0);
if (drv->sock_xmit != NULL)
l2_packet_deinit(drv->sock_xmit);
os_free(drv);
@@ -966,7 +973,7 @@
int ret = 0;
wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d",
- __FUNCTION__, wpa, privacy);
+ __func__, wpa, privacy);
if (!wpa && wpa_driver_bsd_set_wpa_ie(priv, NULL, 0) < 0)
ret = -1;
@@ -981,7 +988,7 @@
static int
wpa_driver_bsd_set_wpa(void *priv, int enabled)
{
- wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
+ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled);
}
@@ -1189,6 +1196,7 @@
struct bsd_driver_global *global = sock_ctx;
struct bsd_driver_data *drv;
struct if_announcemsghdr *ifan;
+ struct if_msghdr *ifm;
struct rt_msghdr *rtm;
union wpa_event_data event;
struct ieee80211_michael_event *mic;
@@ -1210,19 +1218,20 @@
rtm->rtm_version);
return;
}
- drv = bsd_get_drvindex(global, rtm->rtm_index);
- if (drv == NULL)
- return;
- ctx = drv->ctx;
os_memset(&event, 0, sizeof(event));
switch (rtm->rtm_type) {
case RTM_IFANNOUNCE:
ifan = (struct if_announcemsghdr *) rtm;
+ drv = bsd_get_drvindex(global, ifan->ifan_index);
+ if (drv == NULL)
+ return;
os_strlcpy(event.interface_status.ifname, drv->ifname,
sizeof(event.interface_status.ifname));
switch (ifan->ifan_what) {
case IFAN_DEPARTURE:
event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+ drv->ifindex = 0;
+ break;
default:
return;
}
@@ -1230,37 +1239,41 @@
event.interface_status.ifname,
ifan->ifan_what == IFAN_DEPARTURE ?
"removed" : "added");
- wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
+ wpa_supplicant_event(drv->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(ctx, EVENT_ASSOC, NULL);
+ wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
break;
case RTM_IEEE80211_DISASSOC:
if (drv->is_ap)
break;
- wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
+ wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
break;
case RTM_IEEE80211_SCAN:
if (drv->is_ap)
break;
- wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
+ wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS,
+ NULL);
break;
case RTM_IEEE80211_LEAVE:
leave = (struct ieee80211_leave_event *) &ifan[1];
- drv_event_disassoc(ctx, leave->iev_addr);
+ 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, ctx, join->iev_addr);
+ bsd_new_sta(drv, drv->ctx, join->iev_addr);
break;
case RTM_IEEE80211_REPLAY:
/* ignore */
@@ -1275,20 +1288,30 @@
os_memset(&event, 0, sizeof(event));
event.michael_mic_failure.unicast =
!IEEE80211_IS_MULTICAST(mic->iev_dst);
- wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,
- &event);
+ wpa_supplicant_event(drv->ctx,
+ EVENT_MICHAEL_MIC_FAILURE, &event);
break;
}
break;
case RTM_IFINFO:
- if ((rtm->rtm_flags & RTF_UP) == 0) {
- os_strlcpy(event.interface_status.ifname, drv->ifname,
- sizeof(event.interface_status.ifname));
- event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+ 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",
- event.interface_status.ifname);
- wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
+ 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;
}
}
@@ -1559,16 +1582,21 @@
{
struct bsd_driver_data *drv = priv;
- wpa_driver_bsd_set_wpa(drv, 0);
+ if (drv->ifindex != 0) {
+ wpa_driver_bsd_set_wpa(drv, 0);
- /* NB: mark interface down */
- bsd_ctrl_iface(drv, 0);
+ /* NB: mark interface down */
+ bsd_ctrl_iface(drv, 0);
- wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
+ wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa,
+ drv->prev_privacy);
- if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
- wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
- __func__);
+ if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)
+ < 0)
+ wpa_printf(MSG_DEBUG,
+ "%s: failed to restore roaming state",
+ __func__);
+ }
if (drv->sock_xmit != NULL)
l2_packet_deinit(drv->sock_xmit);