Helpers like packet_set_ipv4() resets IP csum flags.
Inspecting and natting embedded payload in an ICMP error is thus broken
if the "outer" IP header had some Rx checksum flags that made it
elligible to Tx IP checksum.
Reset temporarily any Tx checksum to force those helpers to resolve the
checksums.

Signed-off-by: David Marchand <david.march...@redhat.com>
---
 lib/conntrack.c      |  5 +++++
 tests/dpif-netdev.at | 11 +++++++++++
 2 files changed, 16 insertions(+)

diff --git a/lib/conntrack.c b/lib/conntrack.c
index 08823234d4..a25893e0fb 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -913,6 +913,7 @@ nat_inner_packet(struct dp_packet *pkt, struct conn_key 
*key,
     const char *inner_l4 = NULL;
     uint16_t orig_l3_ofs = pkt->l3_ofs;
     uint16_t orig_l4_ofs = pkt->l4_ofs;
+    uint64_t orig_ol_flags = *dp_packet_ol_flags_ptr(pkt);
 
     void *l3 = dp_packet_l3(pkt);
     void *l4 = dp_packet_l4(pkt);
@@ -931,6 +932,9 @@ nat_inner_packet(struct dp_packet *pkt, struct conn_key 
*key,
     }
     pkt->l3_ofs += (char *) inner_l3 - (char *) l3;
     pkt->l4_ofs += inner_l4 - (char *) l4;
+    /* Drop any offloads to force below helpers to calculate checksums
+     * if needed. */
+    *dp_packet_ol_flags_ptr(pkt) &= ~DP_PACKET_OL_TX_ANY_CKSUM;
 
     /* Reverse the key for inner packet. */
     struct conn_key rev_key = *key;
@@ -956,6 +960,7 @@ nat_inner_packet(struct dp_packet *pkt, struct conn_key 
*key,
 
     pkt->l3_ofs = orig_l3_ofs;
     pkt->l4_ofs = orig_l4_ofs;
+    *dp_packet_ol_flags_ptr(pkt) = orig_ol_flags;
 }
 
 static void
diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at
index 992cfa7f22..ff226dee24 100644
--- a/tests/dpif-netdev.at
+++ b/tests/dpif-netdev.at
@@ -1632,6 +1632,17 @@ AT_CHECK([ovs-appctl coverage/read-counter 
conntrack_l3csum_err], [0], [6
 ])
 AT_CHECK([ovs-vsctl set Interface p1 options:ol_ip_rx_csum_set_bad=false])
 
+dnl Special case, check natted ICMP (for traffic flagged good).
+icmp_frame="0a8f393fe0738abf7e2f05840800450000440001000040010364c0a87b02c0a87b010303746c0000000045000028000100004006037bc0a87b01c0a87b021451d4780000000000000000500220002fc40000"
+icmp_expected="0a8f393fe0738abf7e2f05840800450000440001000040017d64c0a87b02c0a801010303fa6b00000000450000280001000040067d7bc0a80101c0a87b021451d478000000000000000050022000a9c40000"
+AT_CHECK([ovs-vsctl set Interface p1 options:ol_ip_rx_csum_set_good=true])
+AT_CHECK([ovs-ofctl add-flow br1 
'in_port=p1,icmp,ct_state=-trk,actions=ct(commit,nat(dst=192.168.1.1)),p2'])
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 ${icmp_frame}])
+AT_CHECK([ovs-pcap p2.pcap > p2.pcap.txt 2>&1])
+AT_CHECK_UNQUOTED([tail -n 1 p2.pcap.txt], [0], [${icmp_expected}
+])
+AT_CHECK([ovs-vsctl set Interface p1 options:ol_ip_rx_csum_set_good=false])
+
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
-- 
2.48.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to