Skip to content

Commit baf4714

Browse files
authored
Customize naming scheme for wiphy (#57)
The default phy%d naming for wiphy in linux kernel depends on the value of a static variable wiphy_counter. Since they never attempts to decrease the value of wiphy_counter even a wiphy is unregistered or freed, this behavior ensures the naming and indexing for wiphy will be absolutely unique. However, the kernel might have other projects also utilize wiphy structure, which will cause some confusion of wiphy's index and naming when using `struct wiphy`. We implement a custom-made name vw_phy%d for wiphy in our project, in order to separate the naming and indexing for 'struct wiphy'. Close #54
1 parent ff5f9e4 commit baf4714

File tree

4 files changed

+79
-13
lines changed

4 files changed

+79
-13
lines changed

README.md

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ $ sudo iw list
125125

126126
Reference output:
127127
```
128-
Wiphy phy2
128+
Wiphy vw_phy2
129129
(... omit)
130-
Wiphy phy1
130+
Wiphy vw_phy1
131131
(... omit)
132-
Wiphy phy0
132+
Wiphy vw_phy0
133133
wiphy index: 0
134134
max # scan SSIDs: 69
135135
max scan IEs length: 0 bytes
@@ -205,12 +205,34 @@ $ sudo ip netns add ns1
205205
$ sudo ip netns add ns2
206206
````
207207

208+
Find the `wiphy` name for the three interfaces.
209+
The index number for the `wiphy` name postfix might be different each time.
210+
Please use the following command for the ease of memorizing different index number everytime.
211+
```shell
212+
$ vw0_phy=$(sudo iw dev vw0 info | grep wiphy | awk '{print $2}')
213+
$ vw0_phy=$(sudo iw list | grep "wiphy index: $vw0_phy" -B 1 | grep Wiphy | awk '{print $2}')
214+
$ vw1_phy=$(sudo iw dev vw1 info | grep wiphy | awk '{print $2}')
215+
$ vw1_phy=$(sudo iw list | grep "wiphy index: $vw1_phy" -B 1 | grep Wiphy | awk '{print $2}')
216+
$ vw2_phy=$(sudo iw dev vw2 info | grep wiphy | awk '{print $2}')
217+
$ vw2_phy=$(sudo iw list | grep "wiphy index: $vw2_phy" -B 1 | grep Wiphy | awk '{print $2}')
218+
```
219+
220+
Check whether the name of each `wiphy` is the same as the name listing under the command `sudo iw list`
221+
```shell
222+
$ echo $vw0_phy
223+
vw_phy0
224+
$ echo $vw1_phy
225+
vw_phy1
226+
$ echo $vw2_phy
227+
vw_phy2
228+
```
229+
208230
Assign the three interfaces to separate network namespaces.
209231
Please note that the `wiphy` is placed within the network namespace, and the interface associated with that wiphy will be contained within it.
210232
```shell
211-
$ sudo iw phy phy0 set netns name ns0
212-
$ sudo iw phy phy1 set netns name ns1
213-
$ sudo iw phy phy2 set netns name ns2
233+
$ sudo iw phy $vw_phy0 set netns name ns0
234+
$ sudo iw phy $vw_phy1 set netns name ns1
235+
$ sudo iw phy $vw_phy2 set netns name ns2
214236
```
215237

216238
### Assigning IP Addresses to Each Interface

scripts/common.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,10 @@ function stop_hostapd() {
6565
sudo kill -9 $(pidof hostapd) > /dev/null
6666
return 0
6767
}
68+
69+
function get_wiphy_name() {
70+
local interface_name=$1
71+
local wiphy_name=$(sudo iw dev $interface_name info | grep wiphy | awk '{print $2}')
72+
wiphy_name=$(sudo iw list | grep "wiphy index: $wiphy_name" -B 1 | grep Wiphy | awk '{print $2}')
73+
echo $wiphy_name
74+
}

scripts/verify.sh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,9 @@ if [ $final_ret -eq 0 ]; then
2626

2727
# get phy number of each interface
2828
sudo iw dev > device.log
29-
vw0_phy=$(cat device.log | grep -B 1 vw0 | grep phy)
30-
vw0_phy=${vw0_phy/\#/}
31-
vw1_phy=$(cat device.log | grep -B 1 vw1 | grep phy)
32-
vw1_phy=${vw1_phy/\#/}
33-
vw2_phy=$(cat device.log | grep -B 1 vw2 | grep phy)
34-
vw2_phy=${vw2_phy/\#/}
29+
vw0_phy=$(get_wiphy_name vw0)
30+
vw1_phy=$(get_wiphy_name vw1)
31+
vw2_phy=$(get_wiphy_name vw2)
3532

3633
# create network namespaces for each phy (interface)
3734
sudo ip netns add ns0

vwifi.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ MODULE_DESCRIPTION("virtual cfg80211 driver");
2424
#define NAME_PREFIX "vw"
2525
#define NDEV_NAME NAME_PREFIX "%d"
2626

27+
#define VWIFI_WIPHY_NAME_LEN 12
28+
#define VWIFI_WIPHY_PREFIX "vw_phy"
29+
2730
#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
2831
#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
2932

@@ -71,6 +74,11 @@ static DEFINE_SPINLOCK(vif_list_lock);
7174
/* SME stands for "station management entity" */
7275
enum sme_state { SME_DISCONNECTED, SME_CONNECTING, SME_CONNECTED };
7376

77+
/* Each virtual interface contains a wiphy, vwifi_wiphy_counter is responsible
78+
* for recording the number of wiphy in vwifi.
79+
*/
80+
static atomic_t vwifi_wiphy_counter = ATOMIC_INIT(0);
81+
7482
/* Virtual interface pointed to by netdev_priv(). Fields in the structure are
7583
* interface-dependent. Every interface has its own vwifi_vif, regardless of the
7684
* interface mode (STA, AP, Ad-hoc...).
@@ -1898,13 +1906,45 @@ static struct wiphy *vwifi_cfg80211_add(void)
18981906
struct wiphy *wiphy = NULL;
18991907
enum nl80211_band band;
19001908

1909+
/* In order to customize vwifi's wiphy name, we use vwifi_wiphy_counter to
1910+
* keep track of the number of wiphy in vwifi, and use vwifi_wiphy_idx to
1911+
* retreive the value of vwifi_wiphy_counter.
1912+
*/
1913+
int vwifi_wiphy_idx = atomic_inc_return(&vwifi_wiphy_counter);
1914+
1915+
/* atomic_inc_return makes it start at 1, make it start at 0 */
1916+
vwifi_wiphy_idx--;
1917+
if (unlikely(vwifi_wiphy_idx < 0)) {
1918+
atomic_dec(&vwifi_wiphy_counter);
1919+
return NULL;
1920+
}
1921+
19011922
/* allocate wiphy context. It is possible just to use wiphy_new().
19021923
* wiphy should represent physical FullMAC wireless device. We need
19031924
* to implement add_virtual_intf() from cfg80211_ops for adding
19041925
* interface(s) on top of a wiphy.
19051926
* NULL means use the default phy%d naming.
1927+
* vwifi_wiphy_name is the custom-made vw_phy%d naming we use for
1928+
* wiphy in vwifi.
19061929
*/
1907-
wiphy = wiphy_new_nm(&vwifi_cfg_ops, 0, NULL);
1930+
1931+
/* Reference:
1932+
* https://elixir.bootlin.com/linux/v6.7/source/net/wireless/core.c#L447
1933+
* The default phy%d naming for wiphy in linux kernel depends on the value
1934+
* of a static variable wiphy_counter. The value of wiphy_counter will never
1935+
* decrease even if we unregister the wiphy. This behavior ensures that the
1936+
* naming and indexing for `struct wiphy` will be absolutely unique.
1937+
* However, the kernel might have other modules or projects also utilizing
1938+
* `struct wiphy`, which will cause some confusion of wiphy's index and
1939+
* naming when using the default naming scheme. We implement a custom-made
1940+
* name "vw_phy%d" for wiphy in vwifi device driver, in order to seperate
1941+
* the naming and indexing for `struct wiphy` in vwifi.
1942+
*/
1943+
char vwifi_wiphy_name[VWIFI_WIPHY_NAME_LEN] = {0};
1944+
snprintf(vwifi_wiphy_name, VWIFI_WIPHY_NAME_LEN, "%s%d", VWIFI_WIPHY_PREFIX,
1945+
vwifi_wiphy_idx);
1946+
1947+
wiphy = wiphy_new_nm(&vwifi_cfg_ops, 0, vwifi_wiphy_name);
19081948
if (!wiphy) {
19091949
pr_info("couldn't allocate wiphy device\n");
19101950
return NULL;

0 commit comments

Comments
 (0)