summaryrefslogtreecommitdiff
path: root/datapath/actions.c
diff options
context:
space:
mode:
authorAndy Zhou <azhou@nicira.com>2014-07-10 00:30:27 -0700
committerAndy Zhou <azhou@nicira.com>2014-07-10 14:58:55 -0700
commit37dfe5264b7a832f9e447217585df68158881578 (patch)
treefda805701bcaa093cc41c11217f4d689cb265d2a /datapath/actions.c
parentaa359b5f8b5c2e887a7b7d6434d04c7a04fe6d3d (diff)
downloadopenvswitch-37dfe5264b7a832f9e447217585df68158881578.tar.gz
datapath: add skb_clone NULL check in the recirc action.
Refactoring recirc action implementation. The main change is to fix a bug where the NULL check after skb clone() call is missing. The fix is to return -ENOMEM whenever skb_clone() failed to create a clone. Also rearranged adjacent code to improve readability. Reported-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: Andy Zhou <azhou@nicira.com> Acked-by: Pravin B Shelar <pshelar@nicira.com>
Diffstat (limited to 'datapath/actions.c')
-rw-r--r--datapath/actions.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/datapath/actions.c b/datapath/actions.c
index 1f12f55ba..caf432ee2 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -729,15 +729,17 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
case OVS_ACTION_ATTR_RECIRC: {
struct sk_buff *recirc_skb;
- if (!last_action(a, rem))
- recirc_skb = skb_clone(skb, GFP_ATOMIC);
- else
- recirc_skb = skb;
+ if (last_action(a, rem))
+ return execute_recirc(dp, skb, a);
- err = execute_recirc(dp, recirc_skb, a);
+ /* Recirc action is the not the last action
+ * of the action list. */
+ recirc_skb = skb_clone(skb, GFP_ATOMIC);
- if (recirc_skb == skb)
- return err;
+ /* Skip the recirc action when out of memory, but
+ * continue on with the rest of the action list. */
+ if (recirc_skb)
+ err = execute_recirc(dp, recirc_skb, a);
break;
}