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;
|
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) {
|
if (fd < 0) {
|
||||||
perror("socket packet");
|
perror("socket packet");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -95,6 +95,24 @@ static int sock_fanout_open(uint16_t typeflags, int num_packets)
|
||||||
return fd;
|
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)
|
static void sock_fanout_set_ebpf(int fd)
|
||||||
{
|
{
|
||||||
const int len_off = __builtin_offsetof(struct __sk_buff, len);
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (type == PACKET_FANOUT_CBPF)
|
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)
|
else if (type == PACKET_FANOUT_EBPF)
|
||||||
sock_fanout_set_ebpf(fds[0]);
|
sock_fanout_set_ebpf(fds[0]);
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
# define __maybe_unused __attribute__ ((__unused__))
|
# define __maybe_unused __attribute__ ((__unused__))
|
||||||
#endif
|
#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
|
/* the filter below checks for all of the following conditions that
|
||||||
* are based on the contents of create_payload()
|
* 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;
|
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.filter = bpf_filter;
|
||||||
bpf_prog.len = sizeof(bpf_filter) / sizeof(struct sock_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))) {
|
sizeof(bpf_prog))) {
|
||||||
perror("setsockopt SO_ATTACH_FILTER");
|
perror("setsockopt SO_ATTACH_FILTER");
|
||||||
exit(1);
|
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)
|
static __maybe_unused void pair_udp_open(int fds[], uint16_t port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in saddr, daddr;
|
struct sockaddr_in saddr, daddr;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче