@@ -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;
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(-)