bpf/flow_dissector: pass input flags to BPF flow dissector program
authorStanislav Fomichev <sdf@google.com>
Thu, 25 Jul 2019 22:52:25 +0000 (15:52 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 26 Jul 2019 01:00:41 +0000 (18:00 -0700)
C flow dissector supports input flags that tell it to customize parsing
by either stopping early or trying to parse as deep as possible. Pass
those flags to the BPF flow dissector so it can make the same
decisions. In the next commits I'll add support for those flags to
our reference bpf_flow.c

v3:
* Export copy of flow dissector flags instead of moving (Alexei Starovoitov)

Acked-by: Petar Penkov <ppenkov@google.com>
Acked-by: Willem de Bruijn <willemb@google.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Song Liu <songliubraving@fb.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Petar Penkov <ppenkov@google.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/linux/skbuff.h
include/uapi/linux/bpf.h
net/bpf/test_run.c
net/core/flow_dissector.c

index 718742b1c50502f1891378621d3c622ff388c008..9b7a8038beec28a00a74d87ae91cdd05b468a453 100644 (file)
@@ -1271,7 +1271,7 @@ static inline int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr)
 
 struct bpf_flow_dissector;
 bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
-                     __be16 proto, int nhoff, int hlen);
+                     __be16 proto, int nhoff, int hlen, unsigned int flags);
 
 bool __skb_flow_dissect(const struct net *net,
                        const struct sk_buff *skb,
index fa1c753dcdbc7f170a65dbaa8b01683de5e6e942..88b9d743036f11f491f5238702f071ca4bf56a28 100644 (file)
@@ -3507,6 +3507,10 @@ enum bpf_task_fd_type {
        BPF_FD_TYPE_URETPROBE,          /* filename + offset */
 };
 
+#define BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG            (1U << 0)
+#define BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL                (1U << 1)
+#define BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP             (1U << 2)
+
 struct bpf_flow_keys {
        __u16   nhoff;
        __u16   thoff;
@@ -3528,6 +3532,7 @@ struct bpf_flow_keys {
                        __u32   ipv6_dst[4];    /* in6_addr; network order */
                };
        };
+       __u32   flags;
 };
 
 struct bpf_func_info {
index 80e6f3a6864d74a327736927e311f5af04a26d54..4e41d15a10986e3e9c79179d22d3cd7ebab0e4d7 100644 (file)
@@ -419,7 +419,7 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
        time_start = ktime_get_ns();
        for (i = 0; i < repeat; i++) {
                retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN,
-                                         size);
+                                         size, 0);
 
                if (signal_pending(current)) {
                        preempt_enable();
index 3e6fedb57bc100e8ce002deddbade59371a73065..50ed1a688709f5df9a42bb301d433532a8d6874a 100644 (file)
@@ -784,7 +784,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
 }
 
 bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
-                     __be16 proto, int nhoff, int hlen)
+                     __be16 proto, int nhoff, int hlen, unsigned int flags)
 {
        struct bpf_flow_keys *flow_keys = ctx->flow_keys;
        u32 result;
@@ -795,6 +795,14 @@ bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
        flow_keys->nhoff = nhoff;
        flow_keys->thoff = flow_keys->nhoff;
 
+       BUILD_BUG_ON((int)BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG !=
+                    (int)FLOW_DISSECTOR_F_PARSE_1ST_FRAG);
+       BUILD_BUG_ON((int)BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL !=
+                    (int)FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
+       BUILD_BUG_ON((int)BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP !=
+                    (int)FLOW_DISSECTOR_F_STOP_AT_ENCAP);
+       flow_keys->flags = flags;
+
        preempt_disable();
        result = BPF_PROG_RUN(prog, ctx);
        preempt_enable();
@@ -914,7 +922,7 @@ bool __skb_flow_dissect(const struct net *net,
                        }
 
                        ret = bpf_flow_dissect(attached, &ctx, n_proto, nhoff,
-                                              hlen);
+                                              hlen, flags);
                        __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
                                                 target_container);
                        rcu_read_unlock();