datapath: add skb_clone NULL check in the recirc action.
authorAndy Zhou <azhou@nicira.com>
Thu, 10 Jul 2014 07:30:27 +0000 (00:30 -0700)
committerAndy Zhou <azhou@nicira.com>
Thu, 10 Jul 2014 22:00:17 +0000 (15:00 -0700)
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>
datapath/actions.c

index 603c7cb..1583a95 100644 (file)
@@ -619,15 +619,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;
                }