This way, we can reuse it for flow dissector in BPF_PROG_TEST_RUN.

No functional changes.

Signed-off-by: Stanislav Fomichev <s...@google.com>
---
 include/linux/skbuff.h    |  5 +++
 net/core/flow_dissector.c | 85 +++++++++++++++++++++++----------------
 2 files changed, 56 insertions(+), 34 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 73902acf2b71..c10b27bb0cab 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1215,6 +1215,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,
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 2e8d91e54179..3c8a78decbc0 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -683,6 +683,41 @@ 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);
+
+       bpf_compute_data_pointers((struct sk_buff *)skb);
+       result = BPF_PROG_RUN(prog, skb);
+
+       /* Restore state */
+       memcpy(cb, &cb_saved, sizeof(cb_saved));
+
+       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 +749,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,49 +788,32 @@ 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;
-
-               bpf_compute_data_pointers((struct sk_buff *)skb);
-               result = BPF_PROG_RUN(attached, skb);
-
-               /* Restore state */
-               memcpy(cb, &cb_saved, sizeof(cb_saved));
-
-               __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
-                                        target_container);
-               key_control->thoff = min_t(u16, key_control->thoff, skb->len);
+               if (attached) {
+                       ret = __skb_flow_bpf_dissect(attached, skb,
+                                                    flow_dissector,
+                                                    &flow_keys);
+                       __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
+                                                target_container);
+                       key_control->thoff = min_t(u16, key_control->thoff,
+                                                  skb->len);
+                       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)) {
-- 
2.20.0.rc1.387.gf8505762e3-goog

Reply via email to