Skip to content

Commit e853ae7

Browse files
fomichevAlexei Starovoitov
authored andcommitted
selftests/bpf: support BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP
Exit as soon as we found that packet is encapped when BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP is passed. Add appropriate selftest cases. v2: * Subtract sizeof(struct iphdr) from .iph_inner.tot_len (Willem de Bruijn) Acked-by: Petar Penkov <[email protected]> Acked-by: Willem de Bruijn <[email protected]> Acked-by: Song Liu <[email protected]> Cc: Song Liu <[email protected]> Cc: Willem de Bruijn <[email protected]> Cc: Petar Penkov <[email protected]> Signed-off-by: Stanislav Fomichev <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 71c99e3 commit e853ae7

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

tools/testing/selftests/bpf/prog_tests/flow_dissector.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ struct ipv4_pkt {
4141
struct tcphdr tcp;
4242
} __packed;
4343

44+
struct ipip_pkt {
45+
struct ethhdr eth;
46+
struct iphdr iph;
47+
struct iphdr iph_inner;
48+
struct tcphdr tcp;
49+
} __packed;
50+
4451
struct svlan_ipv4_pkt {
4552
struct ethhdr eth;
4653
__u16 vlan_tci;
@@ -82,6 +89,7 @@ struct test {
8289
union {
8390
struct ipv4_pkt ipv4;
8491
struct svlan_ipv4_pkt svlan_ipv4;
92+
struct ipip_pkt ipip;
8593
struct ipv6_pkt ipv6;
8694
struct ipv6_frag_pkt ipv6_frag;
8795
struct dvlan_ipv6_pkt dvlan_ipv6;
@@ -303,6 +311,62 @@ struct test tests[] = {
303311
},
304312
.flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL,
305313
},
314+
{
315+
.name = "ipip-encap",
316+
.pkt.ipip = {
317+
.eth.h_proto = __bpf_constant_htons(ETH_P_IP),
318+
.iph.ihl = 5,
319+
.iph.protocol = IPPROTO_IPIP,
320+
.iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
321+
.iph_inner.ihl = 5,
322+
.iph_inner.protocol = IPPROTO_TCP,
323+
.iph_inner.tot_len =
324+
__bpf_constant_htons(MAGIC_BYTES) -
325+
sizeof(struct iphdr),
326+
.tcp.doff = 5,
327+
.tcp.source = 80,
328+
.tcp.dest = 8080,
329+
},
330+
.keys = {
331+
.nhoff = 0,
332+
.nhoff = ETH_HLEN,
333+
.thoff = ETH_HLEN + sizeof(struct iphdr) +
334+
sizeof(struct iphdr),
335+
.addr_proto = ETH_P_IP,
336+
.ip_proto = IPPROTO_TCP,
337+
.n_proto = __bpf_constant_htons(ETH_P_IP),
338+
.is_encap = true,
339+
.sport = 80,
340+
.dport = 8080,
341+
},
342+
},
343+
{
344+
.name = "ipip-no-encap",
345+
.pkt.ipip = {
346+
.eth.h_proto = __bpf_constant_htons(ETH_P_IP),
347+
.iph.ihl = 5,
348+
.iph.protocol = IPPROTO_IPIP,
349+
.iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
350+
.iph_inner.ihl = 5,
351+
.iph_inner.protocol = IPPROTO_TCP,
352+
.iph_inner.tot_len =
353+
__bpf_constant_htons(MAGIC_BYTES) -
354+
sizeof(struct iphdr),
355+
.tcp.doff = 5,
356+
.tcp.source = 80,
357+
.tcp.dest = 8080,
358+
},
359+
.keys = {
360+
.flags = BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP,
361+
.nhoff = ETH_HLEN,
362+
.thoff = ETH_HLEN + sizeof(struct iphdr),
363+
.addr_proto = ETH_P_IP,
364+
.ip_proto = IPPROTO_IPIP,
365+
.n_proto = __bpf_constant_htons(ETH_P_IP),
366+
.is_encap = true,
367+
},
368+
.flags = BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP,
369+
},
306370
};
307371

308372
static int create_tap(const char *ifname)

tools/testing/selftests/bpf/progs/bpf_flow.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,15 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto)
167167
return export_flow_keys(keys, BPF_OK);
168168
case IPPROTO_IPIP:
169169
keys->is_encap = true;
170+
if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP)
171+
return export_flow_keys(keys, BPF_OK);
172+
170173
return parse_eth_proto(skb, bpf_htons(ETH_P_IP));
171174
case IPPROTO_IPV6:
172175
keys->is_encap = true;
176+
if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP)
177+
return export_flow_keys(keys, BPF_OK);
178+
173179
return parse_eth_proto(skb, bpf_htons(ETH_P_IPV6));
174180
case IPPROTO_GRE:
175181
gre = bpf_flow_dissect_get_header(skb, sizeof(*gre), &_gre);
@@ -189,6 +195,8 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto)
189195
keys->thoff += 4; /* Step over sequence number */
190196

191197
keys->is_encap = true;
198+
if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP)
199+
return export_flow_keys(keys, BPF_OK);
192200

193201
if (gre->proto == bpf_htons(ETH_P_TEB)) {
194202
eth = bpf_flow_dissect_get_header(skb, sizeof(*eth),

0 commit comments

Comments
 (0)