Message ID | 20190724170018.96659-8-sdf@google.com |
---|---|
State | Changes Requested |
Delegated to: | BPF Maintainers |
Headers | show |
Series | bpf/flow_dissector: support input flags | expand |
On Wed, Jul 24, 2019 at 10:11 AM Stanislav Fomichev <sdf@google.com> wrote: > > Exit as soon as we found that packet is encapped when > FLOW_DISSECTOR_F_STOP_AT_ENCAP is passed. > Add appropriate selftest cases. > > Cc: Willem de Bruijn <willemb@google.com> > Cc: Petar Penkov <ppenkov@google.com> > Signed-off-by: Stanislav Fomichev <sdf@google.com> Acked-by: Song Liu <songliubraving@fb.com> > --- > .../selftests/bpf/prog_tests/flow_dissector.c | 60 +++++++++++++++++++ > tools/testing/selftests/bpf/progs/bpf_flow.c | 8 +++ > 2 files changed, 68 insertions(+) > > diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c > index 1ea921c4cdc0..e382264fbc40 100644 > --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c > +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c > @@ -41,6 +41,13 @@ struct ipv4_pkt { > struct tcphdr tcp; > } __packed; > > +struct ipip_pkt { > + struct ethhdr eth; > + struct iphdr iph; > + struct iphdr iph_inner; > + struct tcphdr tcp; > +} __packed; > + > struct svlan_ipv4_pkt { > struct ethhdr eth; > __u16 vlan_tci; > @@ -82,6 +89,7 @@ struct test { > union { > struct ipv4_pkt ipv4; > struct svlan_ipv4_pkt svlan_ipv4; > + struct ipip_pkt ipip; > struct ipv6_pkt ipv6; > struct ipv6_frag_pkt ipv6_frag; > struct dvlan_ipv6_pkt dvlan_ipv6; > @@ -303,6 +311,58 @@ struct test tests[] = { > }, > .flags = FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, > }, > + { > + .name = "ipip-encap", > + .pkt.ipip = { > + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), > + .iph.ihl = 5, > + .iph.protocol = IPPROTO_IPIP, > + .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), > + .tcp.doff = 5, > + .tcp.source = 80, > + .tcp.dest = 8080, > + }, > + .keys = { > + .nhoff = 0, > + .nhoff = ETH_HLEN, > + .thoff = ETH_HLEN + sizeof(struct iphdr) + > + sizeof(struct iphdr), > + .addr_proto = ETH_P_IP, > + .ip_proto = IPPROTO_TCP, > + .n_proto = __bpf_constant_htons(ETH_P_IP), > + .is_encap = true, > + .sport = 80, > + .dport = 8080, > + }, > + }, > + { > + .name = "ipip-no-encap", > + .pkt.ipip = { > + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), > + .iph.ihl = 5, > + .iph.protocol = IPPROTO_IPIP, > + .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), > + .tcp.doff = 5, > + .tcp.source = 80, > + .tcp.dest = 8080, > + }, > + .keys = { > + .flags = FLOW_DISSECTOR_F_STOP_AT_ENCAP, > + .nhoff = ETH_HLEN, > + .thoff = ETH_HLEN + sizeof(struct iphdr), > + .addr_proto = ETH_P_IP, > + .ip_proto = IPPROTO_IPIP, > + .n_proto = __bpf_constant_htons(ETH_P_IP), > + .is_encap = true, > + }, > + .flags = FLOW_DISSECTOR_F_STOP_AT_ENCAP, > + }, > }; > > static int create_tap(const char *ifname) > diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c > index 7d73b7bfe609..b6236cdf8564 100644 > --- a/tools/testing/selftests/bpf/progs/bpf_flow.c > +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c > @@ -167,9 +167,15 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto) > return export_flow_keys(keys, BPF_OK); > case IPPROTO_IPIP: > keys->is_encap = true; > + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) > + return export_flow_keys(keys, BPF_OK); > + > return parse_eth_proto(skb, bpf_htons(ETH_P_IP)); > case IPPROTO_IPV6: > keys->is_encap = true; > + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) > + return export_flow_keys(keys, BPF_OK); > + > return parse_eth_proto(skb, bpf_htons(ETH_P_IPV6)); > case IPPROTO_GRE: > 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) > keys->thoff += 4; /* Step over sequence number */ > > keys->is_encap = true; > + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) > + return export_flow_keys(keys, BPF_OK); > > if (gre->proto == bpf_htons(ETH_P_TEB)) { > eth = bpf_flow_dissect_get_header(skb, sizeof(*eth), > -- > 2.22.0.657.g960e92d24f-goog >
diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index 1ea921c4cdc0..e382264fbc40 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -41,6 +41,13 @@ struct ipv4_pkt { struct tcphdr tcp; } __packed; +struct ipip_pkt { + struct ethhdr eth; + struct iphdr iph; + struct iphdr iph_inner; + struct tcphdr tcp; +} __packed; + struct svlan_ipv4_pkt { struct ethhdr eth; __u16 vlan_tci; @@ -82,6 +89,7 @@ struct test { union { struct ipv4_pkt ipv4; struct svlan_ipv4_pkt svlan_ipv4; + struct ipip_pkt ipip; struct ipv6_pkt ipv6; struct ipv6_frag_pkt ipv6_frag; struct dvlan_ipv6_pkt dvlan_ipv6; @@ -303,6 +311,58 @@ struct test tests[] = { }, .flags = FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, }, + { + .name = "ipip-encap", + .pkt.ipip = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_IPIP, + .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), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = 0, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr) + + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_encap = true, + .sport = 80, + .dport = 8080, + }, + }, + { + .name = "ipip-no-encap", + .pkt.ipip = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_IPIP, + .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), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = FLOW_DISSECTOR_F_STOP_AT_ENCAP, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_IPIP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_encap = true, + }, + .flags = FLOW_DISSECTOR_F_STOP_AT_ENCAP, + }, }; static int create_tap(const char *ifname) diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c index 7d73b7bfe609..b6236cdf8564 100644 --- a/tools/testing/selftests/bpf/progs/bpf_flow.c +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c @@ -167,9 +167,15 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto) return export_flow_keys(keys, BPF_OK); case IPPROTO_IPIP: keys->is_encap = true; + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); + return parse_eth_proto(skb, bpf_htons(ETH_P_IP)); case IPPROTO_IPV6: keys->is_encap = true; + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); + return parse_eth_proto(skb, bpf_htons(ETH_P_IPV6)); case IPPROTO_GRE: 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) keys->thoff += 4; /* Step over sequence number */ keys->is_encap = true; + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); if (gre->proto == bpf_htons(ETH_P_TEB)) { eth = bpf_flow_dissect_get_header(skb, sizeof(*eth),
Exit as soon as we found that packet is encapped when FLOW_DISSECTOR_F_STOP_AT_ENCAP is passed. Add appropriate selftest cases. Cc: Willem de Bruijn <willemb@google.com> Cc: Petar Penkov <ppenkov@google.com> Signed-off-by: Stanislav Fomichev <sdf@google.com> --- .../selftests/bpf/prog_tests/flow_dissector.c | 60 +++++++++++++++++++ tools/testing/selftests/bpf/progs/bpf_flow.c | 8 +++ 2 files changed, 68 insertions(+)