tools/testing/selftests/net/netfilter/nf_queue.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/netfilter/nf_queue.c
Extension
.c
Size
9519 bytes
Lines
440
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 options {
	bool count_packets;
	bool gso_enabled;
	bool failopen;
	bool out_of_order;
	bool bogus_verdict;
	int verbose;
	unsigned int queue_num;
	unsigned int timeout;
	uint32_t verdict;
	uint32_t delay_ms;
};

static unsigned int queue_stats[5];
static struct options opts;

static void help(const char *p)
{
	printf("Usage: %s [-c|-v [-vv] ] [-o] [-O] [-b] [-t timeout] [-q queue_num] [-Qdst_queue ] [ -d ms_delay ] [-G]\n", p);
}

static int parse_attr_cb(const struct nlattr *attr, void *data)
{
	const struct nlattr **tb = data;
	int type = mnl_attr_get_type(attr);

	/* skip unsupported attribute in user-space */
	if (mnl_attr_type_valid(attr, NFQA_MAX) < 0)
		return MNL_CB_OK;

	switch (type) {
	case NFQA_MARK:
	case NFQA_IFINDEX_INDEV:
	case NFQA_IFINDEX_OUTDEV:
	case NFQA_IFINDEX_PHYSINDEV:
	case NFQA_IFINDEX_PHYSOUTDEV:
		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case NFQA_TIMESTAMP:
		if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
		    sizeof(struct nfqnl_msg_packet_timestamp)) < 0) {
			perror("mnl_attr_validate2");
			return MNL_CB_ERROR;
		}
		break;
	case NFQA_HWADDR:
		if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
		    sizeof(struct nfqnl_msg_packet_hw)) < 0) {
			perror("mnl_attr_validate2");
			return MNL_CB_ERROR;
		}
		break;
	case NFQA_PAYLOAD:
		break;
	}
	tb[type] = attr;
	return MNL_CB_OK;
}

static int queue_cb(const struct nlmsghdr *nlh, void *data)
{
	struct nlattr *tb[NFQA_MAX+1] = { 0 };
	struct nfqnl_msg_packet_hdr *ph = NULL;
	uint32_t id = 0;

	(void)data;

	mnl_attr_parse(nlh, sizeof(struct nfgenmsg), parse_attr_cb, tb);
	if (tb[NFQA_PACKET_HDR]) {
		ph = mnl_attr_get_payload(tb[NFQA_PACKET_HDR]);
		id = ntohl(ph->packet_id);

		if (opts.verbose > 0)
			printf("packet hook=%u, hwproto 0x%x",
				ntohs(ph->hw_protocol), ph->hook);

		if (ph->hook >= 5) {
			fprintf(stderr, "Unknown hook %d\n", ph->hook);
			return MNL_CB_ERROR;
		}

		if (opts.verbose > 0) {
			uint32_t skbinfo = 0;

			if (tb[NFQA_SKB_INFO])
				skbinfo = ntohl(mnl_attr_get_u32(tb[NFQA_SKB_INFO]));
			if (skbinfo & NFQA_SKB_CSUMNOTREADY)

Annotation

Implementation Notes