bpf, flow_dissector: Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode for bpf progs
authorShmulik Ladkani <shmulik.ladkani@gmail.com>
Sun, 21 Aug 2022 11:35:17 +0000 (14:35 +0300)
committerDaniel Borkmann <daniel@iogearbox.net>
Tue, 23 Aug 2022 20:47:55 +0000 (22:47 +0200)
Currently, attaching BPF_PROG_TYPE_FLOW_DISSECTOR programs completely
replaces the flow-dissector logic with custom dissection logic. This
forces implementors to write programs that handle dissection for any
flows expected in the namespace.

It makes sense for flow-dissector BPF programs to just augment the
dissector with custom logic (e.g. dissecting certain flows or custom
protocols), while enjoying the broad capabilities of the standard
dissector for any other traffic.

Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode. Flow-dissector BPF
programs may return this to indicate no dissection was made, and
fallback to the standard dissector is requested.

Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Stanislav Fomichev <sdf@google.com>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20220821113519.116765-3-shmulik.ladkani@gmail.com
include/uapi/linux/bpf.h
net/core/flow_dissector.c
tools/include/uapi/linux/bpf.h

index 934a2a8beb87fc305923fc2a0dbae62c17552ee6..7f87012b012e167cc6aa42a232961f2b5c463edd 100644 (file)
@@ -5861,6 +5861,11 @@ enum bpf_ret_code {
         *    represented by BPF_REDIRECT above).
         */
        BPF_LWT_REROUTE = 128,
+       /* BPF_FLOW_DISSECTOR_CONTINUE: used by BPF_PROG_TYPE_FLOW_DISSECTOR
+        *   to indicate that no custom dissection was performed, and
+        *   fallback to standard dissector is requested.
+        */
+       BPF_FLOW_DISSECTOR_CONTINUE = 129,
 };
 
 struct bpf_sock {
index a01817fb4ef4225776ae8bd0d38e45c91c9f3580..990429c69ccd41400eba69008f00f35cfc336559 100644 (file)
@@ -1022,11 +1022,14 @@ bool __skb_flow_dissect(const struct net *net,
                        prog = READ_ONCE(run_array->items[0].prog);
                        result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff,
                                                  hlen, flags);
+                       if (result == BPF_FLOW_DISSECTOR_CONTINUE)
+                               goto dissect_continue;
                        __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
                                                 target_container);
                        rcu_read_unlock();
                        return result == BPF_OK;
                }
+dissect_continue:
                rcu_read_unlock();
        }
 
index 1d6085e15fc8e6a0e34af04220602fa455f5b687..f38814fbb6186124829ebd4f119f10fb6c7a2539 100644 (file)
@@ -5861,6 +5861,11 @@ enum bpf_ret_code {
         *    represented by BPF_REDIRECT above).
         */
        BPF_LWT_REROUTE = 128,
+       /* BPF_FLOW_DISSECTOR_CONTINUE: used by BPF_PROG_TYPE_FLOW_DISSECTOR
+        *   to indicate that no custom dissection was performed, and
+        *   fallback to standard dissector is requested.
+        */
+       BPF_FLOW_DISSECTOR_CONTINUE = 129,
 };
 
 struct bpf_sock {