aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/net
diff options
context:
space:
mode:
authorWillem de Bruijn <willemb@google.com>2015-08-14 22:31:36 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-17 17:22:48 -0400
commit95e22792fa5460e579a69171777ff79d8725be29 (patch)
tree374142e4d685e7a97d8a4160ccab2247dfa14536 /tools/testing/selftests/net
parentf2e520956a1ab636698f8160194c9b8ac0989aab (diff)
selftests/net: test classic bpf fanout mode
Test PACKET_FANOUT_CBPF by inserting a cBPF program that selects a socket by payload. Requires modifying the test program to send packets with multiple payloads. Also fix a bug in testing the return value of mmap() Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/testing/selftests/net')
-rw-r--r--tools/testing/selftests/net/psock_fanout.c16
-rw-r--r--tools/testing/selftests/net/psock_lib.h29
2 files changed, 33 insertions, 12 deletions
diff --git a/tools/testing/selftests/net/psock_fanout.c b/tools/testing/selftests/net/psock_fanout.c
index 08c2a36ef7a9..baf46a20e1b3 100644
--- a/tools/testing/selftests/net/psock_fanout.c
+++ b/tools/testing/selftests/net/psock_fanout.c
@@ -19,6 +19,7 @@
19 * - PACKET_FANOUT_LB 19 * - PACKET_FANOUT_LB
20 * - PACKET_FANOUT_CPU 20 * - PACKET_FANOUT_CPU
21 * - PACKET_FANOUT_ROLLOVER 21 * - PACKET_FANOUT_ROLLOVER
22 * - PACKET_FANOUT_CBPF
22 * 23 *
23 * Todo: 24 * Todo:
24 * - functionality: PACKET_FANOUT_FLAG_DEFRAG 25 * - functionality: PACKET_FANOUT_FLAG_DEFRAG
@@ -115,8 +116,8 @@ static char *sock_fanout_open_ring(int fd)
115 116
116 ring = mmap(0, req.tp_block_size * req.tp_block_nr, 117 ring = mmap(0, req.tp_block_size * req.tp_block_nr,
117 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 118 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
118 if (!ring) { 119 if (ring == MAP_FAILED) {
119 fprintf(stderr, "packetsock ring mmap\n"); 120 perror("packetsock ring mmap");
120 exit(1); 121 exit(1);
121 } 122 }
122 123
@@ -209,6 +210,7 @@ static int test_datapath(uint16_t typeflags, int port_off,
209{ 210{
210 const int expect0[] = { 0, 0 }; 211 const int expect0[] = { 0, 0 };
211 char *rings[2]; 212 char *rings[2];
213 uint8_t type = typeflags & 0xFF;
212 int fds[2], fds_udp[2][2], ret; 214 int fds[2], fds_udp[2][2], ret;
213 215
214 fprintf(stderr, "test: datapath 0x%hx\n", typeflags); 216 fprintf(stderr, "test: datapath 0x%hx\n", typeflags);
@@ -219,6 +221,9 @@ static int test_datapath(uint16_t typeflags, int port_off,
219 fprintf(stderr, "ERROR: failed open\n"); 221 fprintf(stderr, "ERROR: failed open\n");
220 exit(1); 222 exit(1);
221 } 223 }
224 if (type == PACKET_FANOUT_CBPF)
225 sock_setfilter(fds[0], SOL_PACKET, PACKET_FANOUT_DATA);
226
222 rings[0] = sock_fanout_open_ring(fds[0]); 227 rings[0] = sock_fanout_open_ring(fds[0]);
223 rings[1] = sock_fanout_open_ring(fds[1]); 228 rings[1] = sock_fanout_open_ring(fds[1]);
224 pair_udp_open(fds_udp[0], PORT_BASE); 229 pair_udp_open(fds_udp[0], PORT_BASE);
@@ -227,11 +232,11 @@ static int test_datapath(uint16_t typeflags, int port_off,
227 232
228 /* Send data, but not enough to overflow a queue */ 233 /* Send data, but not enough to overflow a queue */
229 pair_udp_send(fds_udp[0], 15); 234 pair_udp_send(fds_udp[0], 15);
230 pair_udp_send(fds_udp[1], 5); 235 pair_udp_send_char(fds_udp[1], 5, DATA_CHAR_1);
231 ret = sock_fanout_read(fds, rings, expect1); 236 ret = sock_fanout_read(fds, rings, expect1);
232 237
233 /* Send more data, overflow the queue */ 238 /* Send more data, overflow the queue */
234 pair_udp_send(fds_udp[0], 15); 239 pair_udp_send_char(fds_udp[0], 15, DATA_CHAR_1);
235 /* TODO: ensure consistent order between expect1 and expect2 */ 240 /* TODO: ensure consistent order between expect1 and expect2 */
236 ret |= sock_fanout_read(fds, rings, expect2); 241 ret |= sock_fanout_read(fds, rings, expect2);
237 242
@@ -275,6 +280,7 @@ int main(int argc, char **argv)
275 const int expect_rb[2][2] = { { 15, 5 }, { 20, 15 } }; 280 const int expect_rb[2][2] = { { 15, 5 }, { 20, 15 } };
276 const int expect_cpu0[2][2] = { { 20, 0 }, { 20, 0 } }; 281 const int expect_cpu0[2][2] = { { 20, 0 }, { 20, 0 } };
277 const int expect_cpu1[2][2] = { { 0, 20 }, { 0, 20 } }; 282 const int expect_cpu1[2][2] = { { 0, 20 }, { 0, 20 } };
283 const int expect_bpf[2][2] = { { 15, 5 }, { 15, 20 } };
278 int port_off = 2, tries = 5, ret; 284 int port_off = 2, tries = 5, ret;
279 285
280 test_control_single(); 286 test_control_single();
@@ -295,6 +301,8 @@ int main(int argc, char **argv)
295 port_off, expect_lb[0], expect_lb[1]); 301 port_off, expect_lb[0], expect_lb[1]);
296 ret |= test_datapath(PACKET_FANOUT_ROLLOVER, 302 ret |= test_datapath(PACKET_FANOUT_ROLLOVER,
297 port_off, expect_rb[0], expect_rb[1]); 303 port_off, expect_rb[0], expect_rb[1]);
304 ret |= test_datapath(PACKET_FANOUT_CBPF,
305 port_off, expect_bpf[0], expect_bpf[1]);
298 306
299 set_cpuaffinity(0); 307 set_cpuaffinity(0);
300 ret |= test_datapath(PACKET_FANOUT_CPU, port_off, 308 ret |= test_datapath(PACKET_FANOUT_CPU, port_off,
diff --git a/tools/testing/selftests/net/psock_lib.h b/tools/testing/selftests/net/psock_lib.h
index 37da54ac85a9..24bc7ec1be7d 100644
--- a/tools/testing/selftests/net/psock_lib.h
+++ b/tools/testing/selftests/net/psock_lib.h
@@ -30,6 +30,7 @@
30 30
31#define DATA_LEN 100 31#define DATA_LEN 100
32#define DATA_CHAR 'a' 32#define DATA_CHAR 'a'
33#define DATA_CHAR_1 'b'
33 34
34#define PORT_BASE 8000 35#define PORT_BASE 8000
35 36
@@ -37,29 +38,36 @@
37# define __maybe_unused __attribute__ ((__unused__)) 38# define __maybe_unused __attribute__ ((__unused__))
38#endif 39#endif
39 40
40static __maybe_unused void pair_udp_setfilter(int fd) 41static __maybe_unused void sock_setfilter(int fd, int lvl, int optnum)
41{ 42{
42 struct sock_filter bpf_filter[] = { 43 struct sock_filter bpf_filter[] = {
43 { 0x80, 0, 0, 0x00000000 }, /* LD pktlen */ 44 { 0x80, 0, 0, 0x00000000 }, /* LD pktlen */
44 { 0x35, 0, 5, DATA_LEN }, /* JGE DATA_LEN [f goto nomatch]*/ 45 { 0x35, 0, 4, DATA_LEN }, /* JGE DATA_LEN [f goto nomatch]*/
45 { 0x30, 0, 0, 0x00000050 }, /* LD ip[80] */ 46 { 0x30, 0, 0, 0x00000050 }, /* LD ip[80] */
46 { 0x15, 0, 3, DATA_CHAR }, /* JEQ DATA_CHAR [f goto nomatch]*/ 47 { 0x15, 1, 0, DATA_CHAR }, /* JEQ DATA_CHAR [t goto match]*/
47 { 0x30, 0, 0, 0x00000051 }, /* LD ip[81] */ 48 { 0x15, 0, 1, DATA_CHAR_1}, /* JEQ DATA_CHAR_1 [t goto match]*/
48 { 0x15, 0, 1, DATA_CHAR }, /* JEQ DATA_CHAR [f goto nomatch]*/
49 { 0x06, 0, 0, 0x00000060 }, /* RET match */ 49 { 0x06, 0, 0, 0x00000060 }, /* RET match */
50 { 0x06, 0, 0, 0x00000000 }, /* RET no match */ 50 { 0x06, 0, 0, 0x00000000 }, /* RET no match */
51 }; 51 };
52 struct sock_fprog bpf_prog; 52 struct sock_fprog bpf_prog;
53 53
54 if (lvl == SOL_PACKET && optnum == PACKET_FANOUT_DATA)
55 bpf_filter[5].code = 0x16; /* RET A */
56
54 bpf_prog.filter = bpf_filter; 57 bpf_prog.filter = bpf_filter;
55 bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_filter); 58 bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_filter);
56 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf_prog, 59 if (setsockopt(fd, lvl, optnum, &bpf_prog,
57 sizeof(bpf_prog))) { 60 sizeof(bpf_prog))) {
58 perror("setsockopt SO_ATTACH_FILTER"); 61 perror("setsockopt SO_ATTACH_FILTER");
59 exit(1); 62 exit(1);
60 } 63 }
61} 64}
62 65
66static __maybe_unused void pair_udp_setfilter(int fd)
67{
68 sock_setfilter(fd, SOL_SOCKET, SO_ATTACH_FILTER);
69}
70
63static __maybe_unused void pair_udp_open(int fds[], uint16_t port) 71static __maybe_unused void pair_udp_open(int fds[], uint16_t port)
64{ 72{
65 struct sockaddr_in saddr, daddr; 73 struct sockaddr_in saddr, daddr;
@@ -96,11 +104,11 @@ static __maybe_unused void pair_udp_open(int fds[], uint16_t port)
96 } 104 }
97} 105}
98 106
99static __maybe_unused void pair_udp_send(int fds[], int num) 107static __maybe_unused void pair_udp_send_char(int fds[], int num, char payload)
100{ 108{
101 char buf[DATA_LEN], rbuf[DATA_LEN]; 109 char buf[DATA_LEN], rbuf[DATA_LEN];
102 110
103 memset(buf, DATA_CHAR, sizeof(buf)); 111 memset(buf, payload, sizeof(buf));
104 while (num--) { 112 while (num--) {
105 /* Should really handle EINTR and EAGAIN */ 113 /* Should really handle EINTR and EAGAIN */
106 if (write(fds[0], buf, sizeof(buf)) != sizeof(buf)) { 114 if (write(fds[0], buf, sizeof(buf)) != sizeof(buf)) {
@@ -118,6 +126,11 @@ static __maybe_unused void pair_udp_send(int fds[], int num)
118 } 126 }
119} 127}
120 128
129static __maybe_unused void pair_udp_send(int fds[], int num)
130{
131 return pair_udp_send_char(fds, num, DATA_CHAR);
132}
133
121static __maybe_unused void pair_udp_close(int fds[]) 134static __maybe_unused void pair_udp_close(int fds[])
122{ 135{
123 close(fds[0]); 136 close(fds[0]);