selftests/net: Fixes psock_fanout CBPF test case
'psock_fanout' has been failing since commit4d7b9dc1f3
("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:4d7b9dc1f3
("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>
This commit is contained in:
Родитель
3018e947d7
Коммит
c1f8d0f98c
|
@ -75,7 +75,7 @@ static int sock_fanout_open(uint16_t typeflags, int num_packets)
|
|||
{
|
||||
int fd, val;
|
||||
|
||||
fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
|
||||
fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
|
||||
if (fd < 0) {
|
||||
perror("socket packet");
|
||||
exit(1);
|
||||
|
@ -95,6 +95,24 @@ static int sock_fanout_open(uint16_t typeflags, int num_packets)
|
|||
return fd;
|
||||
}
|
||||
|
||||
static void sock_fanout_set_cbpf(int fd)
|
||||
{
|
||||
struct sock_filter bpf_filter[] = {
|
||||
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 80), /* ldb [80] */
|
||||
BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */
|
||||
};
|
||||
struct sock_fprog bpf_prog;
|
||||
|
||||
bpf_prog.filter = bpf_filter;
|
||||
bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_filter);
|
||||
|
||||
if (setsockopt(fd, SOL_PACKET, PACKET_FANOUT_DATA, &bpf_prog,
|
||||
sizeof(bpf_prog))) {
|
||||
perror("fanout data cbpf");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void sock_fanout_set_ebpf(int fd)
|
||||
{
|
||||
const int len_off = __builtin_offsetof(struct __sk_buff, len);
|
||||
|
@ -270,7 +288,7 @@ static int test_datapath(uint16_t typeflags, int port_off,
|
|||
exit(1);
|
||||
}
|
||||
if (type == PACKET_FANOUT_CBPF)
|
||||
sock_setfilter(fds[0], SOL_PACKET, PACKET_FANOUT_DATA);
|
||||
sock_fanout_set_cbpf(fds[0]);
|
||||
else if (type == PACKET_FANOUT_EBPF)
|
||||
sock_fanout_set_ebpf(fds[0]);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
# define __maybe_unused __attribute__ ((__unused__))
|
||||
#endif
|
||||
|
||||
static __maybe_unused void sock_setfilter(int fd, int lvl, int optnum)
|
||||
static __maybe_unused void pair_udp_setfilter(int fd)
|
||||
{
|
||||
/* the filter below checks for all of the following conditions that
|
||||
* are based on the contents of create_payload()
|
||||
|
@ -76,23 +76,16 @@ static __maybe_unused void sock_setfilter(int fd, int lvl, int optnum)
|
|||
};
|
||||
struct sock_fprog bpf_prog;
|
||||
|
||||
if (lvl == SOL_PACKET && optnum == PACKET_FANOUT_DATA)
|
||||
bpf_filter[5].code = 0x16; /* RET A */
|
||||
|
||||
bpf_prog.filter = bpf_filter;
|
||||
bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_filter);
|
||||
if (setsockopt(fd, lvl, optnum, &bpf_prog,
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf_prog,
|
||||
sizeof(bpf_prog))) {
|
||||
perror("setsockopt SO_ATTACH_FILTER");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static __maybe_unused void pair_udp_setfilter(int fd)
|
||||
{
|
||||
sock_setfilter(fd, SOL_SOCKET, SO_ATTACH_FILTER);
|
||||
}
|
||||
|
||||
static __maybe_unused void pair_udp_open(int fds[], uint16_t port)
|
||||
{
|
||||
struct sockaddr_in saddr, daddr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче