Commit b4940402 authored by Alexis Lothoré (eBPF Foundation)'s avatar Alexis Lothoré (eBPF Foundation) Committed by Alexei Starovoitov
Browse files

selftests/bpf: add gre packets testing to flow_dissector



The bpf_flow program is able to handle GRE headers in IP packets. Add a
few test data input simulating those GRE packets, with 2 different
cases:
- parse GRE and the encapsulated packet
- parse GRE only

Acked-by: default avatarStanislav Fomichev <sdf@fomichev.me>
Signed-off-by: default avatarAlexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
Link: https://lore.kernel.org/r/20241120-flow_dissector-v3-6-45b46494f937@bootlin.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent a2cc66bb
Loading
Loading
Loading
Loading
+76 −0
Original line number Diff line number Diff line
@@ -63,6 +63,19 @@ struct dvlan_ipv6_pkt {
	struct tcphdr tcp;
} __packed;

struct gre_base_hdr {
	__be16 flags;
	__be16 protocol;
} gre_base_hdr;

struct gre_minimal_pkt {
	struct ethhdr eth;
	struct iphdr iph;
	struct gre_base_hdr gre_hdr;
	struct iphdr iph_inner;
	struct tcphdr tcp;
} __packed;

struct test {
	const char *name;
	union {
@@ -72,6 +85,7 @@ struct test {
		struct ipv6_pkt ipv6;
		struct ipv6_frag_pkt ipv6_frag;
		struct dvlan_ipv6_pkt dvlan_ipv6;
		struct gre_minimal_pkt gre_minimal;
	} pkt;
	struct bpf_flow_keys keys;
	__u32 flags;
@@ -417,6 +431,68 @@ struct test tests[] = {
		},
		.retval = BPF_FLOW_DISSECTOR_CONTINUE,
	},
	{
		.name = "ip-gre",
		.pkt.gre_minimal = {
			.eth.h_proto = __bpf_constant_htons(ETH_P_IP),
			.iph.ihl = 5,
			.iph.protocol = IPPROTO_GRE,
			.iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
			.gre_hdr = {
				.flags = 0,
				.protocol = __bpf_constant_htons(ETH_P_IP),
			},
			.iph_inner.ihl = 5,
			.iph_inner.protocol = IPPROTO_TCP,
			.iph_inner.tot_len =
				__bpf_constant_htons(MAGIC_BYTES -
				sizeof(struct iphdr)),
			.tcp.doff = 5,
			.tcp.source = 80,
			.tcp.dest = 8080,
		},
		.keys = {
			.nhoff = ETH_HLEN,
			.thoff = ETH_HLEN + sizeof(struct iphdr) * 2 +
				 sizeof(struct gre_base_hdr),
			.addr_proto = ETH_P_IP,
			.ip_proto = IPPROTO_TCP,
			.n_proto = __bpf_constant_htons(ETH_P_IP),
			.is_encap = true,
			.sport = 80,
			.dport = 8080,
		},
		.retval = BPF_OK,
	},
	{
		.name = "ip-gre-no-encap",
		.pkt.ipip = {
			.eth.h_proto = __bpf_constant_htons(ETH_P_IP),
			.iph.ihl = 5,
			.iph.protocol = IPPROTO_GRE,
			.iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
			.iph_inner.ihl = 5,
			.iph_inner.protocol = IPPROTO_TCP,
			.iph_inner.tot_len =
				__bpf_constant_htons(MAGIC_BYTES -
				sizeof(struct iphdr)),
			.tcp.doff = 5,
			.tcp.source = 80,
			.tcp.dest = 8080,
		},
		.keys = {
			.flags = BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP,
			.nhoff = ETH_HLEN,
			.thoff = ETH_HLEN + sizeof(struct iphdr)
				 + sizeof(struct gre_base_hdr),
			.addr_proto = ETH_P_IP,
			.ip_proto = IPPROTO_GRE,
			.n_proto = __bpf_constant_htons(ETH_P_IP),
			.is_encap = true,
		},
		.flags = BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP,
		.retval = BPF_OK,
	},
};

static int create_tap(const char *ifname)