summaryrefslogtreecommitdiff
path: root/lib/dpif-netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dpif-netdev.c')
-rw-r--r--lib/dpif-netdev.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 48fff8784..f1317973a 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -3745,7 +3745,10 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
flow_hash_5tuple(execute->flow, 0));
}
- dp_packet_batch_init_packet(&pp, execute->packet);
+ /* Making a copy because the packet might be stolen during the execution
+ * and caller might still need it. */
+ struct dp_packet *packet_clone = dp_packet_clone(execute->packet);
+ dp_packet_batch_init_packet(&pp, packet_clone);
dp_netdev_execute_actions(pmd, &pp, false, execute->flow,
execute->actions, execute->actions_len);
dp_netdev_pmd_flush_output_packets(pmd, true);
@@ -3755,6 +3758,14 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
dp_netdev_pmd_unref(pmd);
}
+ if (dp_packet_batch_size(&pp)) {
+ /* Packet wasn't dropped during the execution. Swapping content with
+ * the original packet, because the caller might expect actions to
+ * modify it. */
+ dp_packet_swap(execute->packet, packet_clone);
+ dp_packet_delete_batch(&pp, true);
+ }
+
return 0;
}