From patchwork Mon Apr 10 02:55:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masashi Honma X-Patchwork-Id: 748824 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3w1ZcF0b6fz9s76 for ; Mon, 10 Apr 2017 12:57:49 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="XXblMJ9O"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="anKdNx1S"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=0ounlrdVBoyie9Hdc9Ndf/L4ODs3089hVlj5P2UAbrQ=; b=XXb lMJ9OF1FJa8q/iX7kaqZYrCnmfazMPH/bM2TyNxo3CUck/6TIQygyf2NaFxSAnyAJ5wbOxOMjLJ7E zg1trSxeCllCa9UrCC/BGLIaLaZRgam+P/dC9h2sDRMAO6AhODeP+C312oLWKiyRJR9ete2gxSPP4 638RQF00d7j1qE0JUjZ7P3NYOHAit74BrVyzcvMjPdw9fPWui1CNGvoP/h/G/DYWX4hokemBjZ2tE +U8SKzWXdeF1hPCYgPp4GMepTgc447bdW1Pz5sXp8oNU2iTIUYsCjdvNcW20H4byXz3hk+iZsgk3A C5KHzAlZj+hRm5GOjCBXwmERpTPA36A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cxPVu-0001Y1-CK; Mon, 10 Apr 2017 02:57:10 +0000 Received: from mail-pg0-x244.google.com ([2607:f8b0:400e:c05::244]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cxPV8-0001Re-BS for hostap@lists.infradead.org; Mon, 10 Apr 2017 02:56:25 +0000 Received: by mail-pg0-x244.google.com with SMTP id 81so23930943pgh.3 for ; Sun, 09 Apr 2017 19:56:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=hLSOEDbSN4EKSxJiTV0ONJlNphM4m94vAPKilM9LJz4=; b=anKdNx1SD2MYyCOjMhecY0VyS4tRkpAQZGpbCQ4OgtSXLhefin2IFwipyU3Di8jTmK cW3l4m5jnoetRMaDX/iV6kQzw/ukpnYxTZltKOqCH6P14E9rGBkKoSyMtts2Ybhxh3Rh pIk1DpnetqTz8hIr1QfHf5aXRvTLN5N5/eDsuysVnK9MjoV1MVMLEPcOMbk2scLUU1RL ZMAYUm+dcdxPihKSspslloXQqrvDmAoa/aa4CJPynV/feIwXOefNuahpD7OhO/1l+iPf GFQ4vjzkOSik5iKQxYqZYlRaIaxi0X05hymdgolkCp7rnBX+ASnOuhwNYuxToZciD4G7 opNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=hLSOEDbSN4EKSxJiTV0ONJlNphM4m94vAPKilM9LJz4=; b=pmkmbYiXZ7hVHukvb08anWXhpYGwZcagIK5/ftEjKouGK1v5toOjZO22nJ2J4saYlJ ikTh1ylXFHGkgOxQ2RCWqz0FnGGC3OB5X4j4n/+PycavRnkjg1WrSuF9VL1ddnA9Uy7D E8HuSo64C3pkTc1IQTcySG31t6h/omtK23p44PfYicgDZBi57TDTFjxmfLAbySYhCTqZ YPjrX68Klyx2Nw03kmxHpfbAOFYFTnWtnntZ5kF1ZPdkBWOveYCn6uyZKLsKs5lIRgdc am96nSZWX1jFhKuWtjnOUXKda+OQZ/KRUf5GdbBSf8s6RjsOm/7Aa7esJuQbXrLcV0BA 581Q== X-Gm-Message-State: AFeK/H1YR/6LQKVIF+Hm8xk+Hd5BC4PJqPbTbkqPpRe0yOHNi2uWb2cBGfpwozyfHLTgjQ== X-Received: by 10.99.128.200 with SMTP id j191mr53493374pgd.125.1491792960262; Sun, 09 Apr 2017 19:56:00 -0700 (PDT) Received: from localhost.localdomain (p6e1206.kngwnt01.ap.so-net.ne.jp. [218.110.18.6]) by smtp.gmail.com with ESMTPSA id b70sm21072406pfc.100.2017.04.09.19.55.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 09 Apr 2017 19:55:59 -0700 (PDT) From: Masashi Honma To: hostap@lists.infradead.org Subject: [PATCH 1/2] mesh: Enable DFS for mesh network Date: Mon, 10 Apr 2017 11:55:46 +0900 Message-Id: <1491792947-29720-1-git-send-email-masashi.honma@gmail.com> X-Mailer: git-send-email 2.7.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170409_195622_476886_B5BB5810 X-CRM114-Status: GOOD ( 17.31 ) X-Spam-Score: -2.0 (--) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-2.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2607:f8b0:400e:c05:0:0:0:244 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (masashi.honma[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Masashi Honma MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Signed-off-by: Masashi Honma --- src/ap/ap_config.h | 1 + src/ap/dfs.c | 27 ++++-- src/ap/hostapd.c | 7 ++ tests/hwsim/test_wpas_mesh.py | 12 +-- wpa_supplicant/ap.c | 42 ++++++--- wpa_supplicant/mesh.c | 184 ++++++++++++++++++++++------------------ wpa_supplicant/mesh.h | 2 +- wpa_supplicant/wpa_supplicant.c | 8 +- 8 files changed, 170 insertions(+), 113 deletions(-) diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 989b071..0513dd9 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -49,6 +49,7 @@ struct mesh_conf { int dot11MeshRetryTimeout; /* msec */ int dot11MeshConfirmTimeout; /* msec */ int dot11MeshHoldingTimeout; /* msec */ + int (*join_mesh)(void *priv); }; #define MAX_STA_COUNT 2007 diff --git a/src/ap/dfs.c b/src/ap/dfs.c index 2957201..30cb99f 100644 --- a/src/ap/dfs.c +++ b/src/ap/dfs.c @@ -637,6 +637,17 @@ static unsigned int dfs_get_cac_time(struct hostapd_iface *iface, } +static void *get_message_ctx(struct hostapd_iface *iface) +{ +#ifdef CONFIG_MESH + if (iface->mconf) + return iface->owner; +#endif /* CONFIG_MESH */ + + return iface->bss[0]->msg_ctx; +} + + /* * Main DFS handler * 1 - continue channel/ap setup @@ -719,7 +730,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface) /* Finally start CAC */ hostapd_set_state(iface, HAPD_IFACE_DFS); wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz", iface->freq); - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START + wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START "freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds", iface->freq, iface->conf->channel, iface->conf->secondary_channel, @@ -768,7 +779,7 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq, int ht_enabled, int chan_offset, int chan_width, int cf1, int cf2) { - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED + wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_COMPLETED "success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2); @@ -810,7 +821,7 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq, int ht_enabled, int chan_offset, int chan_width, int cf1, int cf2) { - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED + wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", freq, ht_enabled, chan_offset, chan_width, cf1, cf2); @@ -848,7 +859,7 @@ static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface) wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel->chan); - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL + wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL "freq=%d chan=%d sec_chan=%d", channel->freq, channel->chan, secondary_channel); @@ -928,7 +939,7 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface) wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel->chan); - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL + wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL "freq=%d chan=%d sec_chan=%d", channel->freq, channel->chan, secondary_channel); @@ -990,7 +1001,7 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq, { int res; - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_RADAR_DETECTED + wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_RADAR_DETECTED "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", freq, ht_enabled, chan_offset, chan_width, cf1, cf2); @@ -1021,7 +1032,7 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq, int ht_enabled, int chan_offset, int chan_width, int cf1, int cf2) { - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NOP_FINISHED + wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NOP_FINISHED "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", freq, ht_enabled, chan_offset, chan_width, cf1, cf2); @@ -1071,7 +1082,7 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq, int ht_enabled, int chan_offset, int chan_width, int cf1, int cf2) { - wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START + wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START "freq=%d chan=%d chan_offset=%d width=%d seg0=%d " "seg1=%d cac_time=%ds", freq, (freq - 5000) / 5, chan_offset, chan_width, cf1, cf2, 60); diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 01215aa..27f5d7f 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1821,6 +1821,13 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface, return res_dfs_offload; } +#ifdef CONFIG_MESH + if (iface->mconf && iface->mconf->join_mesh(iface->owner) < 0) { + wpa_msg(iface->owner, MSG_ERROR, "Could not join mesh"); + goto fail; + } +#endif /* CONFIG_MESH */ + #ifdef NEED_AP_MLME dfs_offload: #endif /* NEED_AP_MLME */ diff --git a/tests/hwsim/test_wpas_mesh.py b/tests/hwsim/test_wpas_mesh.py index f632ffd..469fe01 100644 --- a/tests/hwsim/test_wpas_mesh.py +++ b/tests/hwsim/test_wpas_mesh.py @@ -1573,7 +1573,7 @@ def test_mesh_oom(dev, apdev): raise logger.info("Ignore no-oom for i=%d" % i) - with alloc_fail(dev[0], 4, "=wpa_supplicant_mesh_init"): + with alloc_fail(dev[0], 3, "=wpa_supplicant_mesh_init"): id = add_mesh_secure_net(dev[0]) dev[0].mesh_group_add(id) ev = dev[0].wait_event(["Failed to init mesh"]) @@ -1636,7 +1636,7 @@ def test_mesh_drv_fail(dev, apdev): dev[0].dump_monitor() with fail_test(dev[0], 1, "wpa_driver_nl80211_init_mesh"): add_open_mesh_network(dev[0]) - ev = dev[0].wait_event(["Could not join mesh"]) + ev = dev[0].wait_event(["Failed to init mesh"]) if ev is None: raise Exception("Join failure not reported") @@ -1772,15 +1772,15 @@ def test_mesh_invalid_frequency(dev, apdev): check_mesh_support(dev[0]) add_open_mesh_network(dev[0], freq=None) ev = dev[0].wait_event(["MESH-GROUP-STARTED", - "Could not join mesh"]) - if ev is None or "Could not join mesh" not in ev: + "Failed to init mesh"]) + if ev is None or "Failed to init mesh" not in ev: raise Exception("Mesh join failure not reported") dev[0].request("REMOVE_NETWORK all") add_open_mesh_network(dev[0], freq="2413") ev = dev[0].wait_event(["MESH-GROUP-STARTED", - "Could not join mesh"]) - if ev is None or "Could not join mesh" not in ev: + "Failed to init mesh"]) + if ev is None or "Failed to init mesh" not in ev: raise Exception("Mesh join failure not reported") def test_mesh_default_beacon_int(dev, apdev): diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 3fc8e94..720cd98 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -1497,13 +1497,35 @@ int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd) #ifdef NEED_AP_MLME +static int event_handling_required(struct wpa_supplicant *wpa_s) +{ +#ifdef CONFIG_MESH + if (wpa_s->ifmsh) + return 1; +#endif /* CONFIG_MESH */ + + return wpa_s->ap_iface && wpa_s->ap_iface->bss[0]; +} + + +static struct hostapd_iface *get_hapd_iface(struct wpa_supplicant *wpa_s) +{ +#ifdef CONFIG_MESH + if (wpa_s->ifmsh) + return wpa_s->ifmsh; +#endif /* CONFIG_MESH */ + + return wpa_s->ap_iface; +} + + void wpas_event_dfs_radar_detected(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + if (!event_handling_required(wpa_s)) return; wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq); - hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq, + hostapd_dfs_radar_detected(get_hapd_iface(wpa_s), radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); @@ -1513,10 +1535,10 @@ void wpas_event_dfs_radar_detected(struct wpa_supplicant *wpa_s, void wpas_event_dfs_cac_started(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + if (!event_handling_required(wpa_s)) return; wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq); - hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq, + hostapd_dfs_start_cac(get_hapd_iface(wpa_s), radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); } @@ -1525,10 +1547,10 @@ void wpas_event_dfs_cac_started(struct wpa_supplicant *wpa_s, void wpas_event_dfs_cac_finished(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + if (!event_handling_required(wpa_s)) return; wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq); - hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq, + hostapd_dfs_complete_cac(get_hapd_iface(wpa_s), 1, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); } @@ -1537,10 +1559,10 @@ void wpas_event_dfs_cac_finished(struct wpa_supplicant *wpa_s, void wpas_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + if (!event_handling_required(wpa_s)) return; wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq); - hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq, + hostapd_dfs_complete_cac(get_hapd_iface(wpa_s), 0, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); } @@ -1549,10 +1571,10 @@ void wpas_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s, void wpas_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) + if (!event_handling_required(wpa_s)) return; wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq); - hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq, + hostapd_dfs_nop_finished(get_hapd_iface(wpa_s), radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, radar->cf1, radar->cf2); } diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c index 01b657e..02323ae 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -26,6 +26,7 @@ #include "mesh_rsn.h" #include "mesh.h" +static int wpa_supplicant_join_mesh(void *priv); static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s) { @@ -124,6 +125,7 @@ static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s, conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout; conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout; conf->dot11MeshHoldingTimeout = ssid->dot11MeshHoldingTimeout; + conf->join_mesh = wpa_supplicant_join_mesh; return conf; } @@ -147,20 +149,55 @@ static void wpas_mesh_copy_groups(struct hostapd_data *bss, } -static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, - struct wpa_ssid *ssid, - struct hostapd_freq_params *freq) +static void wpa_supplicant_mesh_freq_init(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid, + struct hostapd_freq_params *freq) +{ + os_memset(freq, 0, sizeof(*freq)); + ibss_mesh_setup_freq(wpa_s, ssid, freq); + if (freq->ht_enabled && freq->sec_channel_offset) + ssid->ht40 = freq->sec_channel_offset; + if (freq->vht_enabled) { + ssid->vht = 1; + switch (freq->bandwidth) { + case 80: + if (freq->center_freq2) { + ssid->max_oper_chwidth = VHT_CHANWIDTH_80P80MHZ; + ssid->vht_center_freq2 = freq->center_freq2; + } else { + ssid->max_oper_chwidth = VHT_CHANWIDTH_80MHZ; + } + break; + case 160: + ssid->max_oper_chwidth = VHT_CHANWIDTH_160MHZ; + break; + default: + ssid->max_oper_chwidth = VHT_CHANWIDTH_USE_HT; + break; + } + } +} + + +int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) { struct hostapd_iface *ifmsh; struct hostapd_data *bss; struct hostapd_config *conf; struct mesh_conf *mconf; + struct hostapd_freq_params freq; int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 }; - static int default_groups[] = { 19, 20, 21, 25, 26, -1 }; - size_t len; int rate_len; int frequency; + if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) + return -EINVAL; + + wpa_supplicant_mesh_deinit(wpa_s); + + wpa_supplicant_mesh_freq_init(wpa_s, ssid, &freq); + if (!wpa_s->conf->user_mpm) { /* not much for us to do here */ wpa_msg(wpa_s, MSG_WARNING, @@ -172,6 +209,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, if (!ifmsh) return -ENOMEM; + ifmsh->owner = wpa_s; ifmsh->drv_flags = wpa_s->drv_flags; ifmsh->num_bss = 1; ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss, @@ -189,10 +227,10 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, bss->iface = ifmsh; bss->mesh_sta_free_cb = mesh_mpm_free_sta; frequency = ssid->frequency; - if (frequency != freq->freq && - frequency == freq->freq + freq->sec_channel_offset * 20) { + if (frequency != freq.freq && + frequency == freq.freq + freq.sec_channel_offset * 20) { wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched"); - frequency = freq->freq; + frequency = freq.freq; } wpa_s->assoc_freq = frequency; wpa_s->current_ssid = ssid; @@ -226,6 +264,15 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, frequency); goto out_free; } + + if (ieee80211_is_dfs(ssid->frequency) && wpa_s->conf->country[0]) { + conf->ieee80211h = 1; + conf->ieee80211d = 1; + conf->country[0] = wpa_s->conf->country[0]; + conf->country[1] = wpa_s->conf->country[1]; + conf->country[2] = ' '; + } + if (ssid->ht40) conf->secondary_channel = ssid->ht40; if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) { @@ -279,45 +326,15 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, conf->basic_rates[rate_len] = -1; } - if (hostapd_setup_interface(ifmsh)) { - wpa_printf(MSG_ERROR, - "Failed to initialize hostapd interface for mesh"); - return -1; - } - if (wpa_drv_init_mesh(wpa_s)) { wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver"); return -1; } - if (mconf->security != MESH_CONF_SEC_NONE) { - if (ssid->passphrase == NULL) { - wpa_printf(MSG_ERROR, - "mesh: Passphrase for SAE not configured"); - goto out_free; - } - - bss->conf->wpa = ssid->proto; - bss->conf->wpa_key_mgmt = ssid->key_mgmt; - - if (wpa_s->conf->sae_groups && - wpa_s->conf->sae_groups[0] > 0) { - wpas_mesh_copy_groups(bss, wpa_s); - } else { - bss->conf->sae_groups = - os_memdup(default_groups, - sizeof(default_groups)); - if (!bss->conf->sae_groups) - goto out_free; - } - - len = os_strlen(ssid->passphrase); - bss->conf->ssid.wpa_passphrase = - dup_binstr(ssid->passphrase, len); - - wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf); - if (!wpa_s->mesh_rsn) - goto out_free; + if (hostapd_setup_interface(ifmsh)) { + wpa_printf(MSG_ERROR, + "Failed to initialize hostapd interface for mesh"); + return -1; } wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf); @@ -359,19 +376,13 @@ void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s, } -int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, - struct wpa_ssid *ssid) +static int wpa_supplicant_join_mesh(void *priv) { + struct wpa_supplicant *wpa_s = priv; struct wpa_driver_mesh_join_params params; + struct wpa_ssid *ssid = wpa_s->last_ssid; int ret = 0; - if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) { - ret = -ENOENT; - goto out; - } - - wpa_supplicant_mesh_deinit(wpa_s); - wpa_s->pairwise_cipher = WPA_CIPHER_NONE; wpa_s->group_cipher = WPA_CIPHER_NONE; wpa_s->mgmt_group_cipher = 0; @@ -379,31 +390,9 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, os_memset(¶ms, 0, sizeof(params)); params.meshid = ssid->ssid; params.meshid_len = ssid->ssid_len; - ibss_mesh_setup_freq(wpa_s, ssid, ¶ms.freq); + wpa_supplicant_mesh_freq_init(wpa_s, ssid, ¶ms.freq); wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled; wpa_s->mesh_vht_enabled = !!params.freq.vht_enabled; - if (params.freq.ht_enabled && params.freq.sec_channel_offset) - ssid->ht40 = params.freq.sec_channel_offset; - if (wpa_s->mesh_vht_enabled) { - ssid->vht = 1; - switch (params.freq.bandwidth) { - case 80: - if (params.freq.center_freq2) { - ssid->max_oper_chwidth = VHT_CHANWIDTH_80P80MHZ; - ssid->vht_center_freq2 = - params.freq.center_freq2; - } else { - ssid->max_oper_chwidth = VHT_CHANWIDTH_80MHZ; - } - break; - case 160: - ssid->max_oper_chwidth = VHT_CHANWIDTH_160MHZ; - break; - default: - ssid->max_oper_chwidth = VHT_CHANWIDTH_USE_HT; - break; - } - } if (ssid->beacon_int > 0) params.beacon_int = ssid->beacon_int; else if (wpa_s->conf->beacon_int > 0) @@ -429,14 +418,41 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, } params.conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity; - if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms.freq)) { - wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh"); - wpa_drv_leave_mesh(wpa_s); - ret = -1; - goto out; - } - if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) { + struct hostapd_iface *ifmsh = wpa_s->ifmsh; + struct hostapd_data *bss = ifmsh->bss[0]; + struct mesh_conf *mconf = ifmsh->mconf; + static int default_groups[] = { 19, 20, 21, 25, 26, -1 }; + size_t len; + + if (ssid->passphrase == NULL) { + wpa_printf(MSG_ERROR, + "mesh: Passphrase for SAE not configured"); + return -1; + } + + bss->conf->wpa = ssid->proto; + bss->conf->wpa_key_mgmt = ssid->key_mgmt; + + if (wpa_s->conf->sae_groups && + wpa_s->conf->sae_groups[0] > 0) { + wpas_mesh_copy_groups(bss, wpa_s); + } else { + bss->conf->sae_groups = + os_memdup(default_groups, + sizeof(default_groups)); + if (!bss->conf->sae_groups) + return -1; + } + + len = os_strlen(ssid->passphrase); + bss->conf->ssid.wpa_passphrase = + dup_binstr(ssid->passphrase, len); + + wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf); + if (!wpa_s->mesh_rsn) + return -1; + wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher; wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher; wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher; @@ -459,10 +475,12 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, /* hostapd sets the interface down until we associate */ wpa_drv_set_operstate(wpa_s, 1); - if (!ret) + if (!ret) { wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); + wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d", + wpa_ssid_txt(ssid->ssid, ssid->ssid_len), ssid->id); + } -out: return ret; } diff --git a/wpa_supplicant/mesh.h b/wpa_supplicant/mesh.h index 7317083..4ff23f2 100644 --- a/wpa_supplicant/mesh.h +++ b/wpa_supplicant/mesh.h @@ -9,7 +9,7 @@ #ifndef MESH_H #define MESH_H -int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, +int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s); void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s, diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 498820a..6c6d1c3 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1806,14 +1806,12 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, } if (bss) ssid->frequency = bss->freq; - if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) { - wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh"); + if (wpa_supplicant_mesh_init(wpa_s, ssid)) { + wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh"); + wpa_drv_leave_mesh(wpa_s); return; } wpa_s->current_bss = bss; - wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d", - wpa_ssid_txt(ssid->ssid, ssid->ssid_len), - ssid->id); #else /* CONFIG_MESH */ wpa_msg(wpa_s, MSG_ERROR, "mesh mode support not included in the build");