OSDN Git Service

net/flow_dissector: move bpf case into __skb_flow_bpf_dissect
authorStanislav Fomichev <sdf@google.com>
Mon, 28 Jan 2019 16:53:53 +0000 (08:53 -0800)
committerDaniel Borkmann <daniel@iogearbox.net>
Tue, 29 Jan 2019 00:08:29 +0000 (01:08 +0100)
This way, we can reuse it for flow dissector in BPF_PROG_TEST_RUN.

No functional changes.

Signed-off-by: Stanislav Fomichev <sdf@google.com>
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
include/linux/skbuff.h
net/core/flow_dissector.c

index 93f56fd..be762fc 100644 (file)
@@ -1221,6 +1221,11 @@ static inline int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr)
 }
 #endif
 
+struct bpf_flow_keys;
+bool __skb_flow_bpf_dissect(struct bpf_prog *prog,
+                           const struct sk_buff *skb,
+                           struct flow_dissector *flow_dissector,
+                           struct bpf_flow_keys *flow_keys);
 bool __skb_flow_dissect(const struct sk_buff *skb,
                        struct flow_dissector *flow_dissector,
                        void *target_container,
index 9f28405..bb1a547 100644 (file)
@@ -683,6 +683,46 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
        }
 }
 
+bool __skb_flow_bpf_dissect(struct bpf_prog *prog,
+                           const struct sk_buff *skb,
+                           struct flow_dissector *flow_dissector,
+                           struct bpf_flow_keys *flow_keys)
+{
+       struct bpf_skb_data_end cb_saved;
+       struct bpf_skb_data_end *cb;
+       u32 result;
+
+       /* Note that even though the const qualifier is discarded
+        * throughout the execution of the BPF program, all changes(the
+        * control block) are reverted after the BPF program returns.
+        * Therefore, __skb_flow_dissect does not alter the skb.
+        */
+
+       cb = (struct bpf_skb_data_end *)skb->cb;
+
+       /* Save Control Block */
+       memcpy(&cb_saved, cb, sizeof(cb_saved));
+       memset(cb, 0, sizeof(*cb));
+
+       /* Pass parameters to the BPF program */
+       memset(flow_keys, 0, sizeof(*flow_keys));
+       cb->qdisc_cb.flow_keys = flow_keys;
+       flow_keys->nhoff = skb_network_offset(skb);
+       flow_keys->thoff = flow_keys->nhoff;
+
+       bpf_compute_data_pointers((struct sk_buff *)skb);
+       result = BPF_PROG_RUN(prog, skb);
+
+       /* Restore state */
+       memcpy(cb, &cb_saved, sizeof(cb_saved));
+
+       flow_keys->nhoff = clamp_t(u16, flow_keys->nhoff, 0, skb->len);
+       flow_keys->thoff = clamp_t(u16, flow_keys->thoff,
+                                  flow_keys->nhoff, skb->len);
+
+       return result == BPF_OK;
+}
+
 /**
  * __skb_flow_dissect - extract the flow_keys struct and return it
  * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
@@ -714,7 +754,6 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
        struct flow_dissector_key_vlan *key_vlan;
        enum flow_dissect_ret fdret;
        enum flow_dissector_key_id dissector_vlan = FLOW_DISSECTOR_KEY_MAX;
-       struct bpf_prog *attached = NULL;
        int num_hdrs = 0;
        u8 ip_proto = 0;
        bool ret;
@@ -754,53 +793,30 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
                                              FLOW_DISSECTOR_KEY_BASIC,
                                              target_container);
 
-       rcu_read_lock();
        if (skb) {
+               struct bpf_flow_keys flow_keys;
+               struct bpf_prog *attached = NULL;
+
+               rcu_read_lock();
+
                if (skb->dev)
                        attached = rcu_dereference(dev_net(skb->dev)->flow_dissector_prog);
                else if (skb->sk)
                        attached = rcu_dereference(sock_net(skb->sk)->flow_dissector_prog);
                else
                        WARN_ON_ONCE(1);
-       }
-       if (attached) {
-               /* Note that even though the const qualifier is discarded
-                * throughout the execution of the BPF program, all changes(the
-                * control block) are reverted after the BPF program returns.
-                * Therefore, __skb_flow_dissect does not alter the skb.
-                */
-               struct bpf_flow_keys flow_keys = {};
-               struct bpf_skb_data_end cb_saved;
-               struct bpf_skb_data_end *cb;
-               u32 result;
-
-               cb = (struct bpf_skb_data_end *)skb->cb;
-
-               /* Save Control Block */
-               memcpy(&cb_saved, cb, sizeof(cb_saved));
-               memset(cb, 0, sizeof(cb_saved));
 
-               /* Pass parameters to the BPF program */
-               cb->qdisc_cb.flow_keys = &flow_keys;
-               flow_keys.nhoff = nhoff;
-               flow_keys.thoff = nhoff;
-
-               bpf_compute_data_pointers((struct sk_buff *)skb);
-               result = BPF_PROG_RUN(attached, skb);
-
-               /* Restore state */
-               memcpy(cb, &cb_saved, sizeof(cb_saved));
-
-               flow_keys.nhoff = clamp_t(u16, flow_keys.nhoff, 0, skb->len);
-               flow_keys.thoff = clamp_t(u16, flow_keys.thoff,
-                                         flow_keys.nhoff, skb->len);
-
-               __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
-                                        target_container);
+               if (attached) {
+                       ret = __skb_flow_bpf_dissect(attached, skb,
+                                                    flow_dissector,
+                                                    &flow_keys);
+                       __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
+                                                target_container);
+                       rcu_read_unlock();
+                       return ret;
+               }
                rcu_read_unlock();
-               return result == BPF_OK;
        }
-       rcu_read_unlock();
 
        if (dissector_uses_key(flow_dissector,
                               FLOW_DISSECTOR_KEY_ETH_ADDRS)) {