Skip to content

Commit b32140f

Browse files
committed
Support blocklist in vwifi
Use vwifi-tool to display the status of vwifi and provide ability to use blocklist to block packets from specified interface. Support blocklist in vwifi kernel module, used as interfaces pair such as "owl2 blocks owl1", allow maximum blocklist size to be 1024 bytes now and maintained as global content within struct owl_content. When we detect the packet's source interface and destination interface is in the blocklist, we discard the packet. Using userspace program with netlink to communicate with kernel and allow the ability to dynamically alter the blocklist maintaining in vwifi kernel module. According to #48, we set blocklist in order to filter packet which is unwanted and discard it when AP is forwarding the package. So far the discarded package are simply being ignored by the program, we may need future improvement to delete them thoroughly. Resolves: #48
1 parent e5eb949 commit b32140f

File tree

4 files changed

+312
-3
lines changed

4 files changed

+312
-3
lines changed

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@ ccflags-y := -std=gnu99 -Wno-declaration-after-statement
55
KDIR ?= /lib/modules/$(shell uname -r)/build
66
GIT_HOOKS := .git/hooks/applied
77

8-
all:
8+
all: kmod vwifi-tool
9+
10+
kmod:
911
$(MAKE) -C $(KDIR) M=$(shell pwd) modules
1012

13+
vwifi-tool: vwifi-tool.c
14+
$(CC) $(ccflags-y) -o $@ $<
15+
1116
clean:
1217
$(MAKE) -C $(KDIR) M=$(shell pwd) clean
18+
$(RM) vwifi-tool
1319

1420
check: all
15-
@scripts/verify.sh
21+
@scripts/verify.sh

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,66 @@ PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
344344
4 packets transmitted, 4 received, 0% packet loss, time 3058ms
345345
rtt min/avg/max/mdev = 0.054/0.141/0.342/0.117 ms
346346
```
347+
### vwifi-tool
348+
A set of tools which supports more utilization for vwifi.
349+
Currently supporting feature:
350+
* display the status of vwifi driver
351+
* Use netlink socket to communicate with vwifi driver to configure block list
347352

353+
#### Status checking
354+
Simply utilize `vwifi-tool` without any options
355+
```
356+
$ ./vwifi-tool
357+
vwifi status : not loaded
358+
```
359+
After vwifi driver is loaded into kernel, you should expect the following output
360+
```
361+
$ ./vwifi-tool
362+
vwifi status : live
363+
```
364+
#### Blocklist test
365+
vwifi also supports blocklist ability to allow some interfaces to block packets from certain interfaces.
366+
We can use `vwifi-tool` to set or unset blocklist for vwifi, multiple options are explained as below
367+
* `-d` : specify the destination interface for a blocklist pair
368+
* `-s` : specify the source interface for a blocklist pair
369+
* `-c` : `1` means to unset the blocklist in vwifi, default as `0`
370+
371+
Set the blocklist pair using vwifi-tool like the following
372+
```
373+
$ ./vwifi-tool -d owl2 -s owl1
374+
```
375+
You should see the following output, including your blocklist which will be sent to vwifi
376+
```
377+
vwifi status : live
378+
blocklist:
379+
owl2 blocks owl1
380+
Configuring blocklist for vwifi...
381+
Message from vwifi: vwifi has received your blocklist
382+
```
383+
Then you can try to do the ping test again
384+
```
385+
$ sudo ip netns exec ns1 ping -c 4 10.0.0.3
386+
```
387+
You should see the following output:
388+
```
389+
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
390+
391+
--- 10.0.0.3 ping statistics ---
392+
4 packets transmitted, 0 received, 100% packet loss, time 3053ms
393+
```
394+
You can adjust the content of your blacklist and load it into vwifi anytime.
395+
396+
If you want to unset the blocklist in vwifi, simply add the option `-c` with vwifi-tool
397+
```
398+
$ ./vwifi-tool -c
399+
```
400+
You'll see the following output
401+
```
402+
vwifi status : live
403+
Unset blocklist for vwifi...
404+
Configuring blocklist for vwifi...
405+
Message from vwifi: vwifi has received your blocklist
406+
```
348407
## Testing environment (virtio)
349408
Below is our testing environment with virtio feature:
350409

vwifi-tool.c

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#include <getopt.h>
2+
#include <linux/netlink.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <sys/socket.h>
7+
#include <unistd.h>
8+
9+
#define MAX_PAYLOAD 1024
10+
#define LINE_LENGTH 20
11+
#define MAX_BLOCKLIST_PAIR 5
12+
13+
int main(int argc, char *argv[])
14+
{
15+
/* Check the status of vwifi kernel module */
16+
char *kmod_status_file = "/sys/module/vwifi/initstate";
17+
FILE *fp = fopen(kmod_status_file, "r");
18+
if (!fp) {
19+
printf("vwifi status : not loaded\n");
20+
exit(1);
21+
}
22+
char read_buf[LINE_LENGTH];
23+
fgets(read_buf, LINE_LENGTH, fp);
24+
read_buf[strcspn(read_buf, "\n")] = 0;
25+
if (strcmp("live", read_buf) == 0)
26+
printf("vwifi status : live\n");
27+
else {
28+
printf("vwifi status : %s\n", read_buf);
29+
exit(1);
30+
}
31+
32+
/* Get opt arguments from command line to configure blocklist */
33+
char *dest[MAX_BLOCKLIST_PAIR], *src[MAX_BLOCKLIST_PAIR],
34+
blocklist_pair[MAX_BLOCKLIST_PAIR][LINE_LENGTH];
35+
int d_ind = 0, s_ind = 0, clear = 0;
36+
int c;
37+
38+
while ((c = getopt(argc, argv, "d:s:c")) != -1) {
39+
switch (c) {
40+
case 'd':
41+
dest[d_ind++] = optarg;
42+
break;
43+
case 's':
44+
src[s_ind++] = optarg;
45+
break;
46+
case 'c':
47+
clear = 1;
48+
break;
49+
default:
50+
printf("Invalid arguments\n");
51+
break;
52+
}
53+
}
54+
55+
/* When no options are specified, simply display the status of vwifi */
56+
if (!d_ind && !s_ind && !c)
57+
return 0;
58+
59+
if (d_ind != s_ind) {
60+
printf("Destination number doesn't match with Source number\n");
61+
exit(1);
62+
} else if (clear) {
63+
/* When clear bit is set, we'll send a blank blocklist to vwifi so we
64+
* can unset all blocklist pair */
65+
printf("Unset blocklist for vwifi...\n");
66+
d_ind = 0;
67+
} else {
68+
for (int i = 0; i < d_ind; i++) {
69+
memset(blocklist_pair[i], '\0', sizeof(blocklist_pair[i]));
70+
snprintf(blocklist_pair[i], sizeof(blocklist_pair[i]), "%s %s %s",
71+
dest[i], "blocks", src[i]);
72+
}
73+
printf("blocklist:\n");
74+
for (int i = 0; i < d_ind; i++) {
75+
printf("%s\n", blocklist_pair[i]);
76+
}
77+
}
78+
79+
/* copy blocklist pair into message buffer */
80+
char buffer[NLMSG_SPACE(MAX_PAYLOAD)];
81+
memset(buffer, '\0', sizeof(buffer));
82+
83+
for (int i = 0; i < d_ind; i++) {
84+
if (strlen(blocklist_pair[i]) + strlen(buffer) + 1 <
85+
NLMSG_SPACE(MAX_PAYLOAD)) {
86+
strcat(buffer, blocklist_pair[i]);
87+
strcat(buffer, "\n");
88+
} else {
89+
printf(
90+
"Error: Blocklist size exceeds the maximum size of buffer\n");
91+
exit(1);
92+
}
93+
}
94+
95+
/* Use netlink socket to communicate with kernel module */
96+
int sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
97+
if (sock_fd < 0) {
98+
printf("Error: Can't open socket\n");
99+
exit(1);
100+
}
101+
102+
struct sockaddr_nl src_addr = {
103+
.nl_family = AF_NETLINK,
104+
.nl_pid = getpid(),
105+
};
106+
107+
bind(sock_fd, (struct sockaddr *) &src_addr, sizeof(src_addr));
108+
109+
struct sockaddr_nl dest_addr = {
110+
.nl_family = AF_NETLINK,
111+
.nl_pid = 0,
112+
.nl_groups = 0,
113+
};
114+
115+
struct nlmsghdr *nlh =
116+
(struct nlmsghdr *) calloc(1, NLMSG_SPACE(MAX_PAYLOAD));
117+
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
118+
nlh->nlmsg_pid = getpid();
119+
nlh->nlmsg_flags = 0;
120+
121+
strncpy(NLMSG_DATA(nlh), buffer, NLMSG_SPACE(MAX_PAYLOAD));
122+
123+
struct iovec iov = {
124+
.iov_base = (void *) nlh,
125+
.iov_len = nlh->nlmsg_len,
126+
};
127+
128+
struct msghdr msg = {
129+
.msg_name = (void *) &dest_addr,
130+
.msg_namelen = sizeof(dest_addr),
131+
.msg_iov = &iov,
132+
.msg_iovlen = 1,
133+
};
134+
135+
printf("Configuring blocklist for vwifi...\n");
136+
sendmsg(sock_fd, &msg, 0);
137+
138+
recvmsg(sock_fd, &msg, 0);
139+
printf("Message from vwifi: %s\n", (char *) NLMSG_DATA(nlh));
140+
141+
close(sock_fd);
142+
143+
return 0;
144+
}

0 commit comments

Comments
 (0)