aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ap/sta_info.c2
-rw-r--r--src/common/ieee802_11_defs.h2
-rw-r--r--src/drivers/driver.h2
-rw-r--r--src/drivers/driver_nl80211.c98
-rw-r--r--src/p2p/p2p.c11
-rw-r--r--src/p2p/p2p.h15
-rw-r--r--src/p2p/p2p_go_neg.c30
-rw-r--r--src/p2p/p2p_i.h1
-rw-r--r--src/p2p/p2p_invitation.c2
-rw-r--r--src/rsn_supp/tdls.c2
-rw-r--r--src/rsn_supp/wpa_ft.c5
-rw-r--r--src/tls/libtommath.c12
12 files changed, 164 insertions, 18 deletions
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 8ada1218..cbafb47f 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -576,7 +576,7 @@ void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
{
wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
hapd->conf->iface, MAC2STR(sta->addr));
- sta->flags &= ~WLAN_STA_ASSOC;
+ sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
ap_sta_set_authorized(hapd, sta, 0);
sta->timeout_next = STA_DEAUTH;
wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 652476ff..f782c865 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1005,6 +1005,8 @@ enum wifi_display_subelem {
/* AKM suite selectors */
#define WLAN_AKM_SUITE_8021X 0x000FAC01
#define WLAN_AKM_SUITE_PSK 0x000FAC02
+#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
+#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
#define WLAN_AKM_SUITE_CCKM 0x00409600
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index f12f4bc2..63f90bc0 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -864,6 +864,8 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS_SAE 0x02000000
/* Driver makes use of OBSS scan mechanism in wpa_supplicant */
#define WPA_DRIVER_FLAGS_OBSS_SCAN 0x04000000
+/* Driver supports IBSS (Ad-hoc) mode */
+#define WPA_DRIVER_FLAGS_IBSS 0x08000000
unsigned int flags;
int max_scan_ssids;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 3a35a6b5..efd5cab8 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1642,6 +1642,34 @@ static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
}
+static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
+ struct nlattr *tb[])
+{
+ union wpa_event_data data;
+
+ os_memset(&data, 0, sizeof(data));
+
+ if (tb[NL80211_ATTR_IE]) {
+ data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
+ data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
+ }
+
+ if (tb[NL80211_ATTR_IE_RIC]) {
+ data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
+ data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
+ }
+
+ if (tb[NL80211_ATTR_MAC])
+ os_memcpy(data.ft_ies.target_ap,
+ nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
+
+ wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
+ MAC2STR(data.ft_ies.target_ap));
+
+ wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
+}
+
+
static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
struct nlattr *tb[])
{
@@ -2232,29 +2260,30 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
switch (cmd) {
case NL80211_CMD_TRIGGER_SCAN:
- wpa_printf(MSG_DEBUG, "nl80211: Scan trigger");
+ wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
break;
case NL80211_CMD_START_SCHED_SCAN:
- wpa_printf(MSG_DEBUG, "nl80211: Sched scan started");
+ wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
break;
case NL80211_CMD_SCHED_SCAN_STOPPED:
- wpa_printf(MSG_DEBUG, "nl80211: Sched scan stopped");
+ wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
break;
case NL80211_CMD_NEW_SCAN_RESULTS:
- wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
+ wpa_dbg(drv->ctx, MSG_DEBUG,
+ "nl80211: New scan results available");
drv->scan_complete_events = 1;
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
drv->ctx);
send_scan_event(drv, 0, tb);
break;
case NL80211_CMD_SCHED_SCAN_RESULTS:
- wpa_printf(MSG_DEBUG,
- "nl80211: New sched scan results available");
+ wpa_dbg(drv->ctx, MSG_DEBUG,
+ "nl80211: New sched scan results available");
send_scan_event(drv, 0, tb);
break;
case NL80211_CMD_SCAN_ABORTED:
- wpa_printf(MSG_DEBUG, "nl80211: Scan aborted");
+ wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
/*
* Need to indicate that scan results are available in order
* not to make wpa_supplicant stop its scanning.
@@ -2339,9 +2368,12 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
case NL80211_CMD_CONN_FAILED:
nl80211_connect_failed_event(drv, tb);
break;
+ case NL80211_CMD_FT_EVENT:
+ mlme_event_ft_event(drv, tb);
+ break;
default:
- wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
- "(cmd=%d)", cmd);
+ wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
+ "(cmd=%d)", cmd);
break;
}
}
@@ -2569,6 +2601,9 @@ static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
case NL80211_IFTYPE_AP:
info->capa->flags |= WPA_DRIVER_FLAGS_AP;
break;
+ case NL80211_IFTYPE_ADHOC:
+ info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
+ break;
case NL80211_IFTYPE_P2P_GO:
info->p2p_go_supported = 1;
break;
@@ -3831,6 +3866,7 @@ static int wpa_driver_nl80211_scan(struct i802_bss *bss,
int ret = -1, timeout;
struct nl_msg *msg, *rates = NULL;
+ wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
drv->scan_for_auth = 0;
msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params);
@@ -3932,6 +3968,8 @@ static int wpa_driver_nl80211_sched_scan(void *priv,
struct nl_msg *match_set_rssi = NULL;
size_t i;
+ wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: sched_scan request");
+
#ifdef ANDROID
if (!drv->capa.sched_scan_supported)
return android_pno_start(bss, params);
@@ -7173,6 +7211,8 @@ skip_auth_type:
if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
params->key_mgmt_suite == KEY_MGMT_PSK ||
+ params->key_mgmt_suite == KEY_MGMT_FT_802_1X ||
+ params->key_mgmt_suite == KEY_MGMT_FT_PSK ||
params->key_mgmt_suite == KEY_MGMT_CCKM) {
int mgmt = WLAN_AKM_SUITE_PSK;
@@ -7183,6 +7223,12 @@ skip_auth_type:
case KEY_MGMT_802_1X:
mgmt = WLAN_AKM_SUITE_8021X;
break;
+ case KEY_MGMT_FT_802_1X:
+ mgmt = WLAN_AKM_SUITE_FT_8021X;
+ break;
+ case KEY_MGMT_FT_PSK:
+ mgmt = WLAN_AKM_SUITE_FT_PSK;
+ break;
case KEY_MGMT_PSK:
default:
mgmt = WLAN_AKM_SUITE_PSK;
@@ -9676,6 +9722,39 @@ static int driver_nl80211_probe_req_report(void *priv, int report)
}
+static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md,
+ const u8 *ies, size_t ies_len)
+{
+ int ret;
+ struct nl_msg *msg;
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ u16 mdid = WPA_GET_LE16(md);
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -ENOMEM;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs");
+ nl80211_cmd(drv, msg, 0, NL80211_CMD_UPDATE_FT_IES);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_IE, ies_len, ies);
+ NLA_PUT_U16(msg, NL80211_ATTR_MDID, mdid);
+
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ if (ret) {
+ wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed "
+ "err=%d (%s)", ret, strerror(-ret));
+ }
+
+ return ret;
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return -ENOBUFS;
+}
+
+
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
.desc = "Linux nl80211/cfg80211",
@@ -9751,6 +9830,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.send_tdls_mgmt = nl80211_send_tdls_mgmt,
.tdls_oper = nl80211_tdls_oper,
#endif /* CONFIG_TDLS */
+ .update_ft_ies = wpa_driver_nl80211_update_ft_ies,
#ifdef ANDROID_P2P
.set_noa = wpa_driver_set_p2p_noa,
.get_noa = wpa_driver_get_p2p_noa,
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 704e5310..2b5e5bd1 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -3490,7 +3490,8 @@ static void p2p_timeout_invite_listen(struct p2p_data *p2p)
"P2P: Invitation Request retry limit reached");
if (p2p->cfg->invitation_result)
p2p->cfg->invitation_result(
- p2p->cfg->cb_ctx, -1, NULL, NULL);
+ p2p->cfg->cb_ctx, -1, NULL, NULL,
+ p2p->invite_peer->info.p2p_device_addr);
}
p2p_set_state(p2p, P2P_IDLE);
}
@@ -4319,6 +4320,14 @@ void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5,
}
+void p2p_set_own_freq_preference(struct p2p_data *p2p, int freq)
+{
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Own frequency preference: "
+ "%d MHz", freq);
+ p2p->own_freq_preference = freq;
+}
+
+
const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p)
{
if (p2p == NULL || p2p->go_neg_peer == NULL)
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 4f9b75d0..28a0a1d1 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -743,6 +743,7 @@ struct p2p_config {
* @status: Negotiation result (Status Code)
* @bssid: P2P Group BSSID or %NULL if not received
* @channels: Available operating channels for the group
+ * @addr: Peer address
*
* This callback is used to indicate result of an Invitation procedure
* started with a call to p2p_invite(). The indicated status code is
@@ -751,7 +752,8 @@ struct p2p_config {
* local failure in transmitting the Invitation Request.
*/
void (*invitation_result)(void *ctx, int status, const u8 *bssid,
- const struct p2p_channels *channels);
+ const struct p2p_channels *channels,
+ const u8 *addr);
/**
* go_connected - Check whether we are connected to a GO
@@ -1658,6 +1660,17 @@ void p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan);
void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5,
int freq_overall);
+/**
+ * p2p_set_own_freq_preference - Set own preference for channel
+ * @p2p: P2P module context from p2p_init()
+ * @freq: Frequency (MHz) of the preferred channel or 0 if no preference
+ *
+ * This function can be used to set a preference on the operating channel based
+ * on frequencies used on the other virtual interfaces that share the same
+ * radio. If non-zero, this is used to try to avoid multi-channel concurrency.
+ */
+void p2p_set_own_freq_preference(struct p2p_data *p2p, int freq);
+
const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p);
/**
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 61153d4f..c143ef4a 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -350,14 +350,36 @@ void p2p_reselect_channel(struct p2p_data *p2p,
u8 op_reg_class, op_channel;
unsigned int i;
- wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Selected operating "
- "channel (reg_class %u channel %u) not acceptable to the "
- "peer", p2p->op_reg_class, p2p->op_channel);
+ if (p2p->own_freq_preference > 0 &&
+ p2p_freq_to_channel(p2p->cfg->country, p2p->own_freq_preference,
+ &op_reg_class, &op_channel) == 0 &&
+ p2p_channels_includes(intersection, op_reg_class, op_channel)) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick own channel "
+ "preference (reg_class %u channel %u) from "
+ "intersection", op_reg_class, op_channel);
+ p2p->op_reg_class = op_reg_class;
+ p2p->op_channel = op_channel;
+ return;
+ }
+
+ if (p2p->best_freq_overall > 0 &&
+ p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_overall,
+ &op_reg_class, &op_channel) == 0 &&
+ p2p_channels_includes(intersection, op_reg_class, op_channel)) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick best overall "
+ "channel (reg_class %u channel %u) from intersection",
+ op_reg_class, op_channel);
+ p2p->op_reg_class = op_reg_class;
+ p2p->op_channel = op_channel;
+ return;
+ }
/* First, try to pick the best channel from another band */
freq = p2p_channel_to_freq(p2p->cfg->country, p2p->op_reg_class,
p2p->op_channel);
if (freq >= 2400 && freq < 2500 && p2p->best_freq_5 > 0 &&
+ !p2p_channels_includes(intersection, p2p->op_reg_class,
+ p2p->op_channel) &&
p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_5,
&op_reg_class, &op_channel) == 0 &&
p2p_channels_includes(intersection, op_reg_class, op_channel)) {
@@ -370,6 +392,8 @@ void p2p_reselect_channel(struct p2p_data *p2p,
}
if (freq >= 4900 && freq < 6000 && p2p->best_freq_24 > 0 &&
+ !p2p_channels_includes(intersection, p2p->op_reg_class,
+ p2p->op_channel) &&
p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_24,
&op_reg_class, &op_channel) == 0 &&
p2p_channels_includes(intersection, op_reg_class, op_channel)) {
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 5286b020..d5ce52f8 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -430,6 +430,7 @@ struct p2p_data {
int best_freq_24;
int best_freq_5;
int best_freq_overall;
+ int own_freq_preference;
/**
* wps_vendor_ext - WPS Vendor Extensions to add
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index 43d9475d..2ed9730e 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -466,7 +466,7 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa,
if (p2p->cfg->invitation_result)
p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status,
- msg.group_bssid, channels);
+ msg.group_bssid, channels, sa);
p2p_parse_free(&msg);
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 09abdbbc..bcd924c9 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -1636,7 +1636,7 @@ skip_rsn:
MACSTR " (terminate previously "
"initiated negotiation",
MAC2STR(src_addr));
- wpa_tdls_peer_free(sm, peer);
+ wpa_tdls_disable_link(sm, peer->addr);
}
}
}
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index 2df060ca..4b08a624 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -788,9 +788,12 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
if (parse.ric) {
wpa_hexdump(MSG_MSGDUMP, "FT: RIC Response",
parse.ric, parse.ric_len);
- /* TODO: parse response and inform driver about results */
+ /* TODO: parse response and inform driver about results when
+ * using wpa_supplicant SME */
}
+ wpa_printf(MSG_DEBUG, "FT: Completed successfully");
+
return 0;
}
diff --git a/src/tls/libtommath.c b/src/tls/libtommath.c
index 741b442c..3fb8fbed 100644
--- a/src/tls/libtommath.c
+++ b/src/tls/libtommath.c
@@ -42,6 +42,9 @@
/* Include faster sqr at the cost of about 0.5 kB in code */
#define BN_FAST_S_MP_SQR_C
+/* About 0.25 kB of code, but ~1.7kB of stack space! */
+#define BN_FAST_S_MP_MUL_DIGS_C
+
#else /* LTM_FAST */
#define BN_MP_DIV_SMALL
@@ -139,7 +142,9 @@ static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
static int s_mp_sqr(mp_int * a, mp_int * b);
static int s_mp_mul_high_digs(mp_int * a, mp_int * b, mp_int * c, int digs);
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
static int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
+#endif
#ifdef BN_MP_INIT_MULTI_C
static int mp_init_multi(mp_int *mp, ...);
@@ -671,6 +676,9 @@ static int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
#ifdef BN_MP_EXPTMOD_FAST_C
}
#endif
+ if (dr == 0) {
+ /* avoid compiler warnings about possibly unused variable */
+ }
}
@@ -2339,12 +2347,14 @@ static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
mp_word r;
mp_digit tmpx, *tmpt, *tmpy;
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
/* can we use the fast multiplier? */
if (((digs) < MP_WARRAY) &&
MIN (a->used, b->used) <
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
return fast_s_mp_mul_digs (a, b, c, digs);
}
+#endif
if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
return res;
@@ -2397,6 +2407,7 @@ static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
}
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
/* Fast (comba) multiplier
*
* This is the fast column-array [comba] multiplier. It is
@@ -2482,6 +2493,7 @@ static int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
mp_clamp (c);
return MP_OKAY;
}
+#endif /* BN_FAST_S_MP_MUL_DIGS_C */
/* init an mp_init for a given size */