Merge branches 'work.lookups', 'work.misc' and 'work.preadv2' into for-next
[deliverable/linux.git] / net / openvswitch / actions.c
index c88d0f2d3e019b2caff3c19742c9b4c0886e6298..2d59df521915747db6d46aa12e85e9154e4a9291 100644 (file)
@@ -1160,17 +1160,26 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
                        const struct sw_flow_actions *acts,
                        struct sw_flow_key *key)
 {
-       int level = this_cpu_read(exec_actions_level);
-       int err;
+       static const int ovs_recursion_limit = 5;
+       int err, level;
+
+       level = __this_cpu_inc_return(exec_actions_level);
+       if (unlikely(level > ovs_recursion_limit)) {
+               net_crit_ratelimited("ovs: recursion limit reached on datapath %s, probable configuration error\n",
+                                    ovs_dp_name(dp));
+               kfree_skb(skb);
+               err = -ENETDOWN;
+               goto out;
+       }
 
-       this_cpu_inc(exec_actions_level);
        err = do_execute_actions(dp, skb, key,
                                 acts->actions, acts->actions_len);
 
-       if (!level)
+       if (level == 1)
                process_deferred_actions(dp);
 
-       this_cpu_dec(exec_actions_level);
+out:
+       __this_cpu_dec(exec_actions_level);
        return err;
 }
 
This page took 0.145966 seconds and 5 git commands to generate.