From 54b37e6727e223f54fb774ebf07008d5e6c8ff7b Mon Sep 17 00:00:00 2001 From: elian Date: Mon, 20 May 2024 16:42:14 +0800 Subject: [PATCH 1/4] Align with recent cfg80211 header Starting from kernel version 6.7, several significant changes have been made to the cfg80211 subsystem. 1. The scan_width field is no longer present in the cfg80211_inform_bss structure. There really isn't any support for scanning at different channel widths than 20 MHz since there's no way to set it. 2. The parameters in the change_beacon function have been updated to cfg80211_ap_update. The change_beacon function now includes two additional parameters, fils_discovery and unsol_bcast_probe_resp, which arepart of the cfg80211_ap_update structure. --- vwifi.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/vwifi.c b/vwifi.c index 1ada95a..2aa131d 100644 --- a/vwifi.c +++ b/vwifi.c @@ -454,7 +454,9 @@ static void inform_bss(struct vwifi_vif *vif) struct cfg80211_inform_bss data = { /* the only channel */ .chan = &ap->wdev.wiphy->bands[NL80211_BAND_2GHZ]->channels[0], +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) .scan_width = NL80211_BSS_CHAN_WIDTH_20, +#endif .signal = DBM_TO_MBM(rand_int_smooth(-100, -30, jiffies)), }; int capability = WLAN_CAPABILITY_ESS; @@ -529,7 +531,7 @@ static enum hrtimer_restart vwifi_beacon(struct hrtimer *timer) .boottime_ns = ktime_get_boottime_ns(), .chan = vif->channel, }; - +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) switch (vif->bw) { case NL80211_CHAN_WIDTH_5: bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_5; @@ -541,7 +543,7 @@ static enum hrtimer_restart vwifi_beacon(struct hrtimer *timer) bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_20; break; } - +#endif int capability = WLAN_CAPABILITY_ESS; if (vif->privacy) @@ -1577,7 +1579,7 @@ static int vwifi_stop_ap(struct wiphy *wiphy, struct net_device *ndev) return 0; } - +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) static int vwifi_change_beacon(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_beacon_data *info) @@ -1611,7 +1613,41 @@ static int vwifi_change_beacon(struct wiphy *wiphy, return 0; } +#else +static int vwifi_change_beacon(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_ap_update *info) +{ + struct vwifi_vif *vif = ndev_get_vwifi_vif(ndev); + int ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; + int head_ie_len, tail_ie_len; + + /* cfg80211 and some user-space programs treat IEs as two-part: + * 1. head: 802.11 beacon frame header + beacon IEs before TIM IE + * 2. tail: beacon IEs after TIM IE + * We combine them and store them in vif->beacon_ie. + */ + head_ie_len = info->beacon.head_len - ie_offset; + tail_ie_len = info->beacon.tail_len; + if (likely(head_ie_len + tail_ie_len <= IE_MAX_LEN)) { + vif->beacon_ie_len = head_ie_len + tail_ie_len; + memset(vif->beacon_ie, 0, IE_MAX_LEN); + memcpy(vif->beacon_ie, &info->beacon.head[ie_offset], head_ie_len); + memcpy(vif->beacon_ie + head_ie_len, info->beacon.tail, tail_ie_len); + + pr_info( + "%s: head_ie_len (before TIM IE) = %d, tail_ie_len = " + "%d", + __func__, head_ie_len, tail_ie_len); + } else { + pr_info("%s: IE exceed %d bytes!\n", __func__, IE_MAX_LEN); + return 1; + } + + return 0; +} +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) static int vwifi_add_key(struct wiphy *wiphy, struct net_device *ndev, @@ -2550,7 +2586,9 @@ static void vwifi_virtio_mgmt_rx_scan_response( }; struct cfg80211_inform_bss data = { .chan = &rx_channel, +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) .scan_width = NL80211_BSS_CHAN_WIDTH_20, +#endif .signal = DBM_TO_MBM(rand_int_smooth(-100, -30, jiffies)), }; From 78bea245fe0dc9c576cb95ed5c3e55877ad0a856 Mon Sep 17 00:00:00 2001 From: elian Date: Tue, 21 May 2024 13:49:44 +0800 Subject: [PATCH 2/4] Surround the changed lines with #if directives Adopt rickywu0421's suggestion: Surrounding the changed lines with #if directives is better since there are only a few lines changed. --- vwifi.c | 51 +++++++++++++++------------------------------------ 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/vwifi.c b/vwifi.c index 2aa131d..4ce8013 100644 --- a/vwifi.c +++ b/vwifi.c @@ -1579,10 +1579,15 @@ static int vwifi_stop_ap(struct wiphy *wiphy, struct net_device *ndev) return 0; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) + static int vwifi_change_beacon(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_beacon_data *info) +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) + struct cfg80211_beacon_data *info +#else + struct cfg80211_ap_update *info +#endif +) { struct vwifi_vif *vif = ndev_get_vwifi_vif(ndev); int ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; @@ -1593,49 +1598,23 @@ static int vwifi_change_beacon(struct wiphy *wiphy, * 2. tail: beacon IEs after TIM IE * We combine them and store them in vif->beacon_ie. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) head_ie_len = info->head_len - ie_offset; tail_ie_len = info->tail_len; - - if (likely(head_ie_len + tail_ie_len <= IE_MAX_LEN)) { - vif->beacon_ie_len = head_ie_len + tail_ie_len; - memset(vif->beacon_ie, 0, IE_MAX_LEN); - memcpy(vif->beacon_ie, &info->head[ie_offset], head_ie_len); - memcpy(vif->beacon_ie + head_ie_len, info->tail, tail_ie_len); - - pr_info( - "%s: head_ie_len (before TIM IE) = %d, tail_ie_len = " - "%d", - __func__, head_ie_len, tail_ie_len); - } else { - pr_info("%s: IE exceed %d bytes!\n", __func__, IE_MAX_LEN); - return 1; - } - - return 0; -} #else -static int vwifi_change_beacon(struct wiphy *wiphy, - struct net_device *ndev, - struct cfg80211_ap_update *info) -{ - struct vwifi_vif *vif = ndev_get_vwifi_vif(ndev); - int ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; - int head_ie_len, tail_ie_len; - - /* cfg80211 and some user-space programs treat IEs as two-part: - * 1. head: 802.11 beacon frame header + beacon IEs before TIM IE - * 2. tail: beacon IEs after TIM IE - * We combine them and store them in vif->beacon_ie. - */ head_ie_len = info->beacon.head_len - ie_offset; tail_ie_len = info->beacon.tail_len; - +#endif if (likely(head_ie_len + tail_ie_len <= IE_MAX_LEN)) { vif->beacon_ie_len = head_ie_len + tail_ie_len; memset(vif->beacon_ie, 0, IE_MAX_LEN); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) + memcpy(vif->beacon_ie, &info->head[ie_offset], head_ie_len); + memcpy(vif->beacon_ie + head_ie_len, info->tail, tail_ie_len); +#else memcpy(vif->beacon_ie, &info->beacon.head[ie_offset], head_ie_len); memcpy(vif->beacon_ie + head_ie_len, info->beacon.tail, tail_ie_len); - +#endif pr_info( "%s: head_ie_len (before TIM IE) = %d, tail_ie_len = " "%d", @@ -1647,7 +1626,7 @@ static int vwifi_change_beacon(struct wiphy *wiphy, return 0; } -#endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) static int vwifi_add_key(struct wiphy *wiphy, struct net_device *ndev, From 6f7e034eac89271bebeee53762d38d94a3bae922 Mon Sep 17 00:00:00 2001 From: elian Date: Tue, 21 May 2024 14:57:37 +0800 Subject: [PATCH 3/4] Fit recent kernel versions earlier Adopt jserv's suggestion: Place the newer kernel versions at the top to maintain consistency with the coding style. --- vwifi.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/vwifi.c b/vwifi.c index 4ce8013..4fb4593 100644 --- a/vwifi.c +++ b/vwifi.c @@ -454,7 +454,8 @@ static void inform_bss(struct vwifi_vif *vif) struct cfg80211_inform_bss data = { /* the only channel */ .chan = &ap->wdev.wiphy->bands[NL80211_BAND_2GHZ]->channels[0], -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) +#else .scan_width = NL80211_BSS_CHAN_WIDTH_20, #endif .signal = DBM_TO_MBM(rand_int_smooth(-100, -30, jiffies)), @@ -531,7 +532,8 @@ static enum hrtimer_restart vwifi_beacon(struct hrtimer *timer) .boottime_ns = ktime_get_boottime_ns(), .chan = vif->channel, }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) +#else switch (vif->bw) { case NL80211_CHAN_WIDTH_5: bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_5; @@ -1582,10 +1584,10 @@ static int vwifi_stop_ap(struct wiphy *wiphy, struct net_device *ndev) static int vwifi_change_beacon(struct wiphy *wiphy, struct net_device *ndev, -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) - struct cfg80211_beacon_data *info -#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) struct cfg80211_ap_update *info +#else + struct cfg80211_beacon_data *info #endif ) { @@ -1598,22 +1600,22 @@ static int vwifi_change_beacon(struct wiphy *wiphy, * 2. tail: beacon IEs after TIM IE * We combine them and store them in vif->beacon_ie. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) - head_ie_len = info->head_len - ie_offset; - tail_ie_len = info->tail_len; -#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) head_ie_len = info->beacon.head_len - ie_offset; tail_ie_len = info->beacon.tail_len; +#else + head_ie_len = info->head_len - ie_offset; + tail_ie_len = info->tail_len; #endif if (likely(head_ie_len + tail_ie_len <= IE_MAX_LEN)) { vif->beacon_ie_len = head_ie_len + tail_ie_len; memset(vif->beacon_ie, 0, IE_MAX_LEN); -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) - memcpy(vif->beacon_ie, &info->head[ie_offset], head_ie_len); - memcpy(vif->beacon_ie + head_ie_len, info->tail, tail_ie_len); -#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) memcpy(vif->beacon_ie, &info->beacon.head[ie_offset], head_ie_len); memcpy(vif->beacon_ie + head_ie_len, info->beacon.tail, tail_ie_len); +#else + memcpy(vif->beacon_ie, &info->head[ie_offset], head_ie_len); + memcpy(vif->beacon_ie + head_ie_len, info->tail, tail_ie_len); #endif pr_info( "%s: head_ie_len (before TIM IE) = %d, tail_ie_len = " @@ -2565,7 +2567,8 @@ static void vwifi_virtio_mgmt_rx_scan_response( }; struct cfg80211_inform_bss data = { .chan = &rx_channel, -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) +#else .scan_width = NL80211_BSS_CHAN_WIDTH_20, #endif .signal = DBM_TO_MBM(rand_int_smooth(-100, -30, jiffies)), From c8f3640a614d55b5e31860693d753e1fa519905a Mon Sep 17 00:00:00 2001 From: elian Date: Tue, 21 May 2024 23:53:29 +0800 Subject: [PATCH 4/4] Revise the writing style of version check Adopt jserv's suggestion: When there are no newer versions in the program statement, the form "#if LINUX_VERSION_CODE < KERNEL_VERSION" can be used for writing. --- vwifi.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/vwifi.c b/vwifi.c index 4fb4593..4dba8e9 100644 --- a/vwifi.c +++ b/vwifi.c @@ -454,8 +454,7 @@ static void inform_bss(struct vwifi_vif *vif) struct cfg80211_inform_bss data = { /* the only channel */ .chan = &ap->wdev.wiphy->bands[NL80211_BAND_2GHZ]->channels[0], -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) -#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) .scan_width = NL80211_BSS_CHAN_WIDTH_20, #endif .signal = DBM_TO_MBM(rand_int_smooth(-100, -30, jiffies)), @@ -532,8 +531,7 @@ static enum hrtimer_restart vwifi_beacon(struct hrtimer *timer) .boottime_ns = ktime_get_boottime_ns(), .chan = vif->channel, }; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) -#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) switch (vif->bw) { case NL80211_CHAN_WIDTH_5: bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_5; @@ -2567,8 +2565,7 @@ static void vwifi_virtio_mgmt_rx_scan_response( }; struct cfg80211_inform_bss data = { .chan = &rx_channel, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0) -#else +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) .scan_width = NL80211_BSS_CHAN_WIDTH_20, #endif .signal = DBM_TO_MBM(rand_int_smooth(-100, -30, jiffies)),