• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2019 Cyril Hrubis <chrubis@suse.cz>
4  */
5 
6 /*
7  * Very simple uevent netlink socket test.
8  *
9  * We fork a child that listens for a kernel events while parents creates and
10  * removes a tun network device which should produce two several add and remove
11  * events.
12  */
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <sys/wait.h>
17 #include <sys/socket.h>
18 #include <linux/if.h>
19 #include <linux/if_tun.h>
20 
21 #include "tst_test.h"
22 
23 #include "uevent.h"
24 
25 #define TUN_PATH "/dev/net/tun"
26 
generate_tun_uevents(void)27 static void generate_tun_uevents(void)
28 {
29 	int fd = SAFE_OPEN(TUN_PATH, O_RDWR);
30 
31 	struct ifreq ifr = {
32 		.ifr_flags = IFF_TUN,
33 		.ifr_name = "ltp-tun0",
34 	};
35 
36 	SAFE_IOCTL(fd, TUNSETIFF, (void*)&ifr);
37 
38 	SAFE_IOCTL(fd, TUNSETPERSIST, 0);
39 
40 	SAFE_CLOSE(fd);
41 }
42 
verify_uevent(void)43 static void verify_uevent(void)
44 {
45 	int pid, fd;
46 
47 	struct uevent_desc add = {
48 		.msg = "add@/devices/virtual/net/ltp-tun0",
49 		.value_cnt = 4,
50 		.values = (const char*[]) {
51 			"ACTION=add",
52 			"DEVPATH=/devices/virtual/net/ltp-tun0",
53 			"SUBSYSTEM=net",
54 			"INTERFACE=ltp-tun0",
55 		}
56 	};
57 
58 	struct uevent_desc add_rx = {
59 		.msg = "add@/devices/virtual/net/ltp-tun0/queues/rx-0",
60 		.value_cnt = 3,
61 		.values = (const char*[]) {
62 			"ACTION=add",
63 			"DEVPATH=/devices/virtual/net/ltp-tun0/queues/rx-0",
64 			"SUBSYSTEM=queues",
65 		}
66 	};
67 
68 	struct uevent_desc add_tx = {
69 		.msg = "add@/devices/virtual/net/ltp-tun0/queues/tx-0",
70 		.value_cnt = 3,
71 		.values = (const char*[]) {
72 			"ACTION=add",
73 			"DEVPATH=/devices/virtual/net/ltp-tun0/queues/tx-0",
74 			"SUBSYSTEM=queues",
75 		}
76 	};
77 
78 	struct uevent_desc rem_rx = {
79 		.msg = "remove@/devices/virtual/net/ltp-tun0/queues/rx-0",
80 		.value_cnt = 3,
81 		.values = (const char*[]) {
82 			"ACTION=remove",
83 			"DEVPATH=/devices/virtual/net/ltp-tun0/queues/rx-0",
84 			"SUBSYSTEM=queues",
85 		}
86 	};
87 
88 	struct uevent_desc rem_tx = {
89 		.msg = "remove@/devices/virtual/net/ltp-tun0/queues/tx-0",
90 		.value_cnt = 3,
91 		.values = (const char*[]) {
92 			"ACTION=remove",
93 			"DEVPATH=/devices/virtual/net/ltp-tun0/queues/tx-0",
94 			"SUBSYSTEM=queues",
95 		}
96 	};
97 
98 	struct uevent_desc rem = {
99 		.msg = "remove@/devices/virtual/net/ltp-tun0",
100 		.value_cnt = 4,
101 		.values = (const char*[]) {
102 			"ACTION=remove",
103 			"DEVPATH=/devices/virtual/net/ltp-tun0",
104 			"SUBSYSTEM=net",
105 			"INTERFACE=ltp-tun0",
106 		}
107 	};
108 
109 	const struct uevent_desc *const uevents[] = {
110 		&add,
111 		&add_rx,
112 		&add_tx,
113 		&rem_rx,
114 		&rem_tx,
115 		&rem,
116 		NULL
117 	};
118 
119 	pid = SAFE_FORK();
120 	if (!pid) {
121 		fd = open_uevent_netlink();
122 		TST_CHECKPOINT_WAKE(0);
123 		wait_for_uevents(fd, uevents);
124 		exit(0);
125 	}
126 
127 	TST_CHECKPOINT_WAIT(0);
128 
129 	generate_tun_uevents();
130 
131 	wait_for_pid(pid);
132 }
133 
134 static struct tst_test test = {
135 	.test_all = verify_uevent,
136 	.forks_child = 1,
137 	.needs_checkpoints = 1,
138 	.needs_drivers = (const char *const []) {
139 		"tun",
140 		NULL
141 	},
142 	.needs_root = 1
143 };
144