diff options
author | Andy Zhou <azhou@nicira.com> | 2014-07-10 00:30:27 -0700 |
---|---|---|
committer | Andy Zhou <azhou@nicira.com> | 2014-07-10 14:58:55 -0700 |
commit | 37dfe5264b7a832f9e447217585df68158881578 (patch) | |
tree | fda805701bcaa093cc41c11217f4d689cb265d2a /datapath/actions.c | |
parent | aa359b5f8b5c2e887a7b7d6434d04c7a04fe6d3d (diff) | |
download | openvswitch-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.c | 16 |
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; } |