diff mbox series

[ovs-dev,RFC] dpif-netdev: Free packets on TUNNEL_PUSH if may_steal.

Message ID 1526062370-9929-1-git-send-email-i.maximets@samsung.com
State RFC
Headers show
Series [ovs-dev,RFC] dpif-netdev: Free packets on TUNNEL_PUSH if may_steal. | expand

Commit Message

Ilya Maximets May 11, 2018, 6:12 p.m. UTC
Unconditional return may cause packet leak in case of
'may_steal == true'.

Additionally, removed redundant checking for depth level and
clarified ignoring of the 'false' value of 'may_steal'.

CC: Sugesh Chandran <sugesh.chandran@intel.com>
Fixes: 7c12dfc527a5 ("tunneling: Avoid datapath-recirc by
                      combining recirc actions at xlate.")
Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 lib/dpif-netdev.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index f86ed2a..3e9e627 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -5574,22 +5574,14 @@  push_tnl_action(const struct dp_netdev_pmd_thread *pmd,
 {
     struct tx_port *tun_port;
     const struct ovs_action_push_tnl *data;
-    int err;
 
     data = nl_attr_get(attr);
 
     tun_port = pmd_tnl_port_cache_lookup(pmd, data->tnl_port);
     if (!tun_port) {
-        err = -EINVAL;
-        goto error;
-    }
-    err = netdev_push_header(tun_port->port->netdev, batch, data);
-    if (!err) {
-        return 0;
+        return -EINVAL;
     }
-error:
-    dp_packet_delete_batch(batch, true);
-    return err;
+    return netdev_push_header(tun_port->port->netdev, batch, data);
 }
 
 static void
@@ -5672,9 +5664,17 @@  dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
         break;
 
     case OVS_ACTION_ATTR_TUNNEL_PUSH:
-        if (*depth < MAX_RECIRC_DEPTH) {
-            dp_packet_batch_apply_cutlen(packets_);
-            push_tnl_action(pmd, a, packets_);
+        /*
+         * XXX: 'may_steal' concept is broken here, because we're
+         *      unconditionally changing the packets just like for other PUSH_*
+         *      actions in 'odp_execute()'. 'false' value could be ignored,
+         *      because we could reach here only after clone, but we still need
+         *      to free the packets in case 'may_steal == true'.
+         */
+        dp_packet_batch_apply_cutlen(packets_);
+        if (push_tnl_action(pmd, a, packets_) != 0) {
+            /* Push failed. Drop the packets to prevent further processing. */
+            dp_packet_delete_batch(packets_, true);
             return;
         }
         break;