Added execute_or_defer_actions() that both sample and recirc
action's implementation can use.

Signed-off-by: Andy Zhou <az...@ovn.org>
---
 net/openvswitch/actions.c | 96 +++++++++++++++++++++++++++++------------------
 1 file changed, 59 insertions(+), 37 deletions(-)

diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 1638370..fd7d903 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -44,10 +44,6 @@
 #include "conntrack.h"
 #include "vport.h"
 
-static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
-                             struct sw_flow_key *key,
-                             const struct nlattr *attr, int len);
-
 struct deferred_action {
        struct sk_buff *skb;
        const struct nlattr *actions;
@@ -166,6 +162,12 @@ static bool is_flow_key_valid(const struct sw_flow_key 
*key)
        return !(key->mac_proto & SW_FLOW_KEY_INVALID);
 }
 
+static int execute_or_defer_actions(struct datapath *dp, struct sk_buff *skb,
+                                   struct sw_flow_key *clone,
+                                   struct sw_flow_key *key,
+                                   u32 *recirc_id,
+                                   const struct nlattr *actions, int len);
+
 static void update_ethertype(struct sk_buff *skb, struct ethhdr *hdr,
                             __be16 ethertype)
 {
@@ -941,7 +943,7 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
        struct nlattr *sample_arg;
        struct sw_flow_key *orig_key = key;
        int rem = nla_len(attr);
-       int err = 0;
+       int err;
        const struct sample_arg *arg;
 
        /* The first action is always 'OVS_SAMPLE_ATTR_ARG'. */
@@ -979,15 +981,8 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
                key = clone_key(key);
        }
 
-       if (key) {
-               err = do_execute_actions(dp, skb, key, actions, rem);
-       } else if (!add_deferred_actions(skb, orig_key, actions, rem)) {
-
-               if (net_ratelimit())
-                       pr_warn("%s: deferred action limit reached, drop sample 
action\n",
-                               ovs_dp_name(dp));
-               kfree_skb(skb);
-       }
+       err = execute_or_defer_actions(dp, skb, key, orig_key, NULL,
+                                      actions, rem);
 
        if (!arg->exec)
                __this_cpu_dec(exec_actions_level);
@@ -1105,8 +1100,7 @@ static int execute_recirc(struct datapath *dp, struct 
sk_buff *skb,
                          struct sw_flow_key *key,
                          const struct nlattr *a, int rem)
 {
-       struct sw_flow_key *recirc_key;
-       struct deferred_action *da;
+       u32 recirc_id;
 
        if (!is_flow_key_valid(key)) {
                int err;
@@ -1130,27 +1124,9 @@ static int execute_recirc(struct datapath *dp, struct 
sk_buff *skb,
                        return 0;
        }
 
-       /* If within the limit of 'OVS_DEFERRED_ACTION_THRESHOLD',
-        * recirc immediately, otherwise, defer it for later execution.
-        */
-       recirc_key = clone_key(key);
-       if (recirc_key) {
-               recirc_key->recirc_id = nla_get_u32(a);
-               ovs_dp_process_packet(skb, recirc_key);
-       } else {
-               da = add_deferred_actions(skb, key, NULL, 0);
-               if (da) {
-                       recirc_key = &da->pkt_key;
-                       recirc_key->recirc_id = nla_get_u32(a);
-               } else {
-                       /* Log an error in case action fifo is full.  */
-                       kfree_skb(skb);
-                       if (net_ratelimit())
-                               pr_warn("%s: deferred action limit reached, 
drop recirc action\n",
-                                       ovs_dp_name(dp));
-               }
-       }
-       return 0;
+       recirc_id = nla_get_u32(a);
+       return execute_or_defer_actions(dp, skb, clone_key(key),
+                                       key, &recirc_id, NULL, 0);
 }
 
 /* Execute a list of actions against 'skb'. */
@@ -1286,6 +1262,52 @@ static int do_execute_actions(struct datapath *dp, 
struct sk_buff *skb,
        return 0;
 }
 
+static int execute_or_defer_actions(struct datapath *dp, struct sk_buff *skb,
+                                   struct sw_flow_key *clone,
+                                   struct sw_flow_key *key,
+                                   u32 *recirc_id,
+                                   const struct nlattr *actions, int len)
+{
+       struct deferred_action *da;
+
+       /* If within the limit of 'OVS_DEFERRED_ACTION_THRESHOLD',
+        * recirc immediately, otherwise, defer it for later execution.
+        */
+       if (clone) {
+               if (recirc_id) {
+                       clone->recirc_id = *recirc_id;
+                       ovs_dp_process_packet(skb, clone);
+                       return 0;
+               } else {
+                       return do_execute_actions(dp, skb, clone,
+                                                 actions, len);
+               }
+       }
+
+       da = add_deferred_actions(skb, key, actions, len);
+       if (da) {
+               if (recirc_id) {
+                       key = &da->pkt_key;
+                       key->recirc_id = *recirc_id;
+               }
+       } else {
+               /* Drop the SKB and log an error. */
+               kfree_skb(skb);
+
+               if (net_ratelimit()) {
+                       if (recirc_id) {
+                               pr_warn("%s: deferred action limit reached, 
drop recirc action\n",
+                                       ovs_dp_name(dp));
+                       } else {
+                               pr_warn("%s: deferred action limit reached, 
drop sample action\n",
+                                       ovs_dp_name(dp));
+                       }
+               }
+       }
+
+       return 0;
+}
+
 static void process_deferred_actions(struct datapath *dp)
 {
        struct action_fifo *fifo = this_cpu_ptr(action_fifos);
-- 
1.8.3.1

Reply via email to