diff options
author | Mike Maloney <maloney@google.com> | 2017-04-18 11:14:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-04-20 15:39:19 -0400 |
commit | c1f8d0f98c3bc12393821c1bf00d8eaa0bd58bd8 (patch) | |
tree | 71f19fe662ccc3a778346ffd4c3b43c291ca0ac0 /tools | |
parent | 3018e947d7fd536d57e2b550c33e456d921fff8c (diff) |
selftests/net: Fixes psock_fanout CBPF test case
'psock_fanout' has been failing since commit 4d7b9dc1f36a9 ("tools:
psock_lib: harden socket filter used by psock tests"). That commit
changed the CBPF filter to examine the full ethernet frame, and was
tested on 'psock_tpacket' which uses SOCK_RAW. But 'psock_fanout' was
also using this same CBPF in two places, for filtering and fanout, on a
SOCK_DGRAM socket.
Change 'psock_fanout' to use SOCK_RAW so that the CBPF program used with
SO_ATTACH_FILTER can examine the entire frame. Create a new CBPF
program for use with PACKET_FANOUT_DATA which ignores the header, as it
cannot see the ethernet header.
Tested: Ran tools/testing/selftests/net/psock_{fanout,tpacket} 10 times,
and they all passed.
Fixes: 4d7b9dc1f36a9 ("tools: psock_lib: harden socket filter used by psock tests")
Signed-off-by: 'Mike Maloney <maloneykernel@gmail.com>'
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/net/psock_fanout.c | 22 | ||||
-rw-r--r-- | tools/testing/selftests/net/psock_lib.h | 13 |
2 files changed, 23 insertions, 12 deletions
diff --git a/tools/testing/selftests/net/psock_fanout.c b/tools/testing/selftests/net/psock_fanout.c index 412459369686..e62bb354820c 100644 --- a/tools/testing/selftests/net/psock_fanout.c +++ b/tools/testing/selftests/net/psock_fanout.c | |||
@@ -75,7 +75,7 @@ static int sock_fanout_open(uint16_t typeflags, int num_packets) | |||
75 | { | 75 | { |
76 | int fd, val; | 76 | int fd, val; |
77 | 77 | ||
78 | fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); | 78 | fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); |
79 | if (fd < 0) { | 79 | if (fd < 0) { |
80 | perror("socket packet"); | 80 | perror("socket packet"); |
81 | exit(1); | 81 | exit(1); |
@@ -95,6 +95,24 @@ static int sock_fanout_open(uint16_t typeflags, int num_packets) | |||
95 | return fd; | 95 | return fd; |
96 | } | 96 | } |
97 | 97 | ||
98 | static void sock_fanout_set_cbpf(int fd) | ||
99 | { | ||
100 | struct sock_filter bpf_filter[] = { | ||
101 | BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 80), /* ldb [80] */ | ||
102 | BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ | ||
103 | }; | ||
104 | struct sock_fprog bpf_prog; | ||
105 | |||
106 | bpf_prog.filter = bpf_filter; | ||
107 | bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_filter); | ||
108 | |||
109 | if (setsockopt(fd, SOL_PACKET, PACKET_FANOUT_DATA, &bpf_prog, | ||
110 | sizeof(bpf_prog))) { | ||
111 | perror("fanout data cbpf"); | ||
112 | exit(1); | ||
113 | } | ||
114 | } | ||
115 | |||
98 | static void sock_fanout_set_ebpf(int fd) | 116 | static void sock_fanout_set_ebpf(int fd) |
99 | { | 117 | { |
100 | const int len_off = __builtin_offsetof(struct __sk_buff, len); | 118 | const int len_off = __builtin_offsetof(struct __sk_buff, len); |
@@ -270,7 +288,7 @@ static int test_datapath(uint16_t typeflags, int port_off, | |||
270 | exit(1); | 288 | exit(1); |
271 | } | 289 | } |
272 | if (type == PACKET_FANOUT_CBPF) | 290 | if (type == PACKET_FANOUT_CBPF) |
273 | sock_setfilter(fds[0], SOL_PACKET, PACKET_FANOUT_DATA); | 291 | sock_fanout_set_cbpf(fds[0]); |
274 | else if (type == PACKET_FANOUT_EBPF) | 292 | else if (type == PACKET_FANOUT_EBPF) |
275 | sock_fanout_set_ebpf(fds[0]); | 293 | sock_fanout_set_ebpf(fds[0]); |
276 | 294 | ||
diff --git a/tools/testing/selftests/net/psock_lib.h b/tools/testing/selftests/net/psock_lib.h index a77da88bf946..7d990d6c861b 100644 --- a/tools/testing/selftests/net/psock_lib.h +++ b/tools/testing/selftests/net/psock_lib.h | |||
@@ -38,7 +38,7 @@ | |||
38 | # define __maybe_unused __attribute__ ((__unused__)) | 38 | # define __maybe_unused __attribute__ ((__unused__)) |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | static __maybe_unused void sock_setfilter(int fd, int lvl, int optnum) | 41 | static __maybe_unused void pair_udp_setfilter(int fd) |
42 | { | 42 | { |
43 | /* the filter below checks for all of the following conditions that | 43 | /* the filter below checks for all of the following conditions that |
44 | * are based on the contents of create_payload() | 44 | * are based on the contents of create_payload() |
@@ -76,23 +76,16 @@ static __maybe_unused void sock_setfilter(int fd, int lvl, int optnum) | |||
76 | }; | 76 | }; |
77 | struct sock_fprog bpf_prog; | 77 | struct sock_fprog bpf_prog; |
78 | 78 | ||
79 | if (lvl == SOL_PACKET && optnum == PACKET_FANOUT_DATA) | ||
80 | bpf_filter[5].code = 0x16; /* RET A */ | ||
81 | |||
82 | bpf_prog.filter = bpf_filter; | 79 | bpf_prog.filter = bpf_filter; |
83 | bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_filter); | 80 | bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_filter); |
84 | if (setsockopt(fd, lvl, optnum, &bpf_prog, | 81 | |
82 | if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf_prog, | ||
85 | sizeof(bpf_prog))) { | 83 | sizeof(bpf_prog))) { |
86 | perror("setsockopt SO_ATTACH_FILTER"); | 84 | perror("setsockopt SO_ATTACH_FILTER"); |
87 | exit(1); | 85 | exit(1); |
88 | } | 86 | } |
89 | } | 87 | } |
90 | 88 | ||
91 | static __maybe_unused void pair_udp_setfilter(int fd) | ||
92 | { | ||
93 | sock_setfilter(fd, SOL_SOCKET, SO_ATTACH_FILTER); | ||
94 | } | ||
95 | |||
96 | static __maybe_unused void pair_udp_open(int fds[], uint16_t port) | 89 | static __maybe_unused void pair_udp_open(int fds[], uint16_t port) |
97 | { | 90 | { |
98 | struct sockaddr_in saddr, daddr; | 91 | struct sockaddr_in saddr, daddr; |