developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 1 | From fc8ea40f6130ac18d9c66797de2cf1d5af55d496 Mon Sep 17 00:00:00 2001 |
| 2 | From: Markus Theil <markus.theil@tu-ilmenau.de> |
| 3 | Date: Tue, 30 Jun 2020 14:19:07 +0200 |
| 4 | Subject: [PATCH 19/19] mesh: use deterministic channel on channel switch |
| 5 | |
| 6 | This patch uses a deterministic channel on DFS channel switch |
| 7 | in mesh networks. Otherwise, when switching to a usable but not |
| 8 | available channel, no CSA can be sent and a random channel is choosen |
| 9 | without notification of other nodes. It is then quite likely, that |
| 10 | the mesh network gets disconnected. |
| 11 | |
| 12 | Fix this by using a deterministic number, based on the sha256 hash |
| 13 | of the mesh ID, in order to use at least a different number in each |
| 14 | mesh network. |
| 15 | |
| 16 | Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de> |
| 17 | --- |
| 18 | src/ap/dfs.c | 20 +++++++++++++++++++- |
| 19 | src/drivers/driver_nl80211.c | 4 ++++ |
| 20 | 2 files changed, 23 insertions(+), 1 deletion(-) |
| 21 | |
| 22 | --- a/src/ap/dfs.c |
| 23 | +++ b/src/ap/dfs.c |
| 24 | @@ -17,6 +17,7 @@ |
| 25 | #include "ap_drv_ops.h" |
| 26 | #include "drivers/driver.h" |
| 27 | #include "dfs.h" |
| 28 | +#include "crypto/crypto.h" |
| 29 | |
| 30 | |
| 31 | enum dfs_channel_type { |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 32 | @@ -526,9 +527,14 @@ dfs_get_valid_channel(struct hostapd_ifa |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 33 | int num_available_chandefs; |
| 34 | int chan_idx, chan_idx2; |
| 35 | int sec_chan_idx_80p80 = -1; |
| 36 | + bool is_mesh = false; |
| 37 | int i; |
| 38 | u32 _rand; |
| 39 | |
| 40 | +#ifdef CONFIG_MESH |
| 41 | + is_mesh = iface->mconf; |
| 42 | +#endif |
| 43 | + |
| 44 | wpa_printf(MSG_DEBUG, "DFS: Selecting random channel"); |
| 45 | *secondary_channel = 0; |
| 46 | *oper_centr_freq_seg0_idx = 0; |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 47 | @@ -548,8 +554,20 @@ dfs_get_valid_channel(struct hostapd_ifa |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 48 | if (num_available_chandefs == 0) |
| 49 | return NULL; |
| 50 | |
| 51 | - if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) |
| 52 | + /* try to use deterministic channel in mesh, so that both sides |
| 53 | + * have a chance to switch to the same channel */ |
| 54 | + if (is_mesh) { |
| 55 | +#ifdef CONFIG_MESH |
| 56 | + u64 hash[4]; |
| 57 | + const u8 *meshid[1] = { &iface->mconf->meshid[0] }; |
| 58 | + const size_t meshid_len = iface->mconf->meshid_len; |
| 59 | + |
| 60 | + sha256_vector(1, meshid, &meshid_len, (u8 *)&hash[0]); |
| 61 | + _rand = hash[0] + hash[1] + hash[2] + hash[3]; |
| 62 | +#endif |
| 63 | + } else if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) |
| 64 | return NULL; |
| 65 | + |
| 66 | chan_idx = _rand % num_available_chandefs; |
| 67 | dfs_find_channel(iface, &chan, chan_idx, type); |
| 68 | if (!chan) { |
| 69 | --- a/src/drivers/driver_nl80211.c |
| 70 | +++ b/src/drivers/driver_nl80211.c |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 71 | @@ -11017,6 +11017,10 @@ static int nl80211_switch_channel(void * |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 72 | if (ret) |
| 73 | goto error; |
| 74 | |
| 75 | + if (drv->nlmode == NL80211_IFTYPE_MESH_POINT) { |
| 76 | + nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS); |
| 77 | + } |
| 78 | + |
| 79 | /* beacon_csa params */ |
| 80 | beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES); |
| 81 | if (!beacon_csa) |