datapath: Free skb(s) on recirculation error
authorSimon Horman <horms@verge.net.au>
Tue, 13 May 2014 05:46:18 +0000 (14:46 +0900)
committerJesse Gross <jesse@nicira.com>
Tue, 13 May 2014 20:39:53 +0000 (13:39 -0700)
commit97a360ced33fe81e29a585aa29b3c7c90c916835
treed81694ff47ee51958e218fcf75c17925e27b0145
parent75264fe5f1ceb73a33bcc8e1adb3ad9aad57237d
datapath: Free skb(s) on recirculation error

This patch attempts to ensure that skb(s) are always freed (once)
if if an error occurs in execute_recirc(). It does so in two ways:

1. Ensure that execute_recirc() always consimes skb passed to it.
   Specifically, free the skb if the call to ovs_flow_extract() fails.

2. Return from the recirc case in execute_recirc() whenever
   the skb has not been cloned immediately above.

   This is only the case if the action is both the last action and the
   keep_skb parameter of execute_recirc is not true.  As it is the last
   action and the skb is consumed one way or another by execute_recirc() it
   is correct to return here.  In particular this avoids the possibility of
   the skb, which has been consumed by execute_recirc() from being freed.

   Conversely if this is not the case then the skb has been cloned
   and the clone has been consumed by execute_recirc().
   This leads to three sub-cases:
   * If execute_recirc() returned an error code then the original skb
     will be freed by the error handling code below the case statement in
     do_execute_actions().
   * If this is not the last action then action processing will continue,
     using the original skb.
   * If this is the last action then it must also be the case that keep_skb
     is true (otherwise the skb would not have been cloned). Thus
     do_execute_actions() will return without freeing the original skb.

Signed-off-by: Simon Horman <horms@verge.net.au>
[jesse: use kfree_skb instead of consume_skb on error path]
Signed-off-by: Jesse Gross <jesse@nicira.com>
datapath/actions.c