Commit c1f8d0f9 authored by Mike Maloney's avatar Mike Maloney Committed by David S. Miller
Browse files

selftests/net: Fixes psock_fanout CBPF test case



'psock_fanout' has been failing since commit 4d7b9dc1 ("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: 4d7b9dc1 ("tools: psock_lib: harden socket filter used by psock tests")
Signed-off-by: default avatar'Mike Maloney <maloneykernel@gmail.com&gt;'>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3018e947
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -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]);

+3 −10
Original line number Diff line number Diff line
@@ -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;