tools/testing/selftests/net/psock_tpacket.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/net/psock_tpacket.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/psock_tpacket.c
Extension
.c
Size
18844 bytes
Lines
851
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ring {
	struct iovec *rd;
	uint8_t *mm_space;
	size_t mm_len, rd_len;
	struct sockaddr_ll ll;
	void (*walk)(int sock, struct ring *ring);
	int type, rd_num, flen, version;
	union {
		struct tpacket_req  req;
		struct tpacket_req3 req3;
	};
};

struct block_desc {
	uint32_t version;
	uint32_t offset_to_priv;
	struct tpacket_hdr_v1 h1;
};

union frame_map {
	struct {
		struct tpacket_hdr tp_h __aligned_tpacket;
		struct sockaddr_ll s_ll __align_tpacket(sizeof(struct tpacket_hdr));
	} *v1;
	struct {
		struct tpacket2_hdr tp_h __aligned_tpacket;
		struct sockaddr_ll s_ll __align_tpacket(sizeof(struct tpacket2_hdr));
	} *v2;
	void *raw;
};

static unsigned int total_packets, total_bytes;

static int pfsocket(int ver)
{
	int ret, sock = socket(PF_PACKET, SOCK_RAW, 0);
	if (sock == -1) {
		perror("socket");
		exit(1);
	}

	ret = setsockopt(sock, SOL_PACKET, PACKET_VERSION, &ver, sizeof(ver));
	if (ret == -1) {
		perror("setsockopt");
		exit(1);
	}

	return sock;
}

static void status_bar_update(void)
{
	if (total_packets % 10 == 0) {
		fprintf(stderr, ".");
		fflush(stderr);
	}
}

static void test_payload(void *pay, size_t len)
{
	struct ethhdr *eth = pay;

	if (len < sizeof(struct ethhdr)) {
		fprintf(stderr, "test_payload: packet too "
			"small: %zu bytes!\n", len);
		exit(1);
	}

	if (eth->h_proto != htons(ETH_P_IP)) {
		fprintf(stderr, "test_payload: wrong ethernet "
			"type: 0x%x!\n", ntohs(eth->h_proto));
		exit(1);
	}
}

static void create_payload(void *pay, size_t *len)
{
	int i;
	struct ethhdr *eth = pay;
	struct iphdr *ip = pay + sizeof(*eth);

	/* Lets create some broken crap, that still passes
	 * our BPF filter.
	 */

	*len = DATA_LEN + 42;

	memset(pay, 0xff, ETH_ALEN * 2);
	eth->h_proto = htons(ETH_P_IP);

Annotation

Implementation Notes