@@ -1184,7 +1184,7 @@ dp_packet_hwol_is_tunnel_vxlan(struct dp_packet *b)
/* Returns 'true' if packet 'b' is marked for outer IPv4 checksum offload. */
static inline bool
-dp_packet_hwol_is_outer_ipv4_cksum(struct dp_packet *b)
+dp_packet_hwol_is_outer_ipv4_cksum(const struct dp_packet *b)
{
return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_OUTER_IP_CKSUM);
}
@@ -1384,6 +1384,22 @@ dp_packet_ip_checksum_bad(const struct dp_packet *p)
DP_PACKET_OL_RX_IP_CKSUM_BAD;
}
+/* Return 'true' is packet 'b' is not encapsulated and is marked for IPv4
+ * checksum offload, or if 'b' is encapsulated and the outer layer is marked
+ * for IPv4 checksum offload. IPv6 packets and non offloaded packets return
+ * 'false'. */
+static inline bool
+dp_packet_hwol_l3_csum_ipv4_ol(const struct dp_packet *b)
+{
+ if (dp_packet_hwol_is_outer_ipv4(b)) {
+ return dp_packet_hwol_is_outer_ipv4_cksum(b);
+ } else if (!dp_packet_hwol_is_outer_ipv6(b)) {
+ return dp_packet_hwol_tx_ip_csum(b) &&
+ !dp_packet_ip_checksum_good(b);
+ }
+ return false;
+}
+
/* Calculate and set the IPv4 header checksum in packet 'p'. */
static inline void
dp_packet_ip_set_header_csum(struct dp_packet *p, bool inner)
@@ -7199,10 +7199,11 @@ netdev_linux_prepend_vnet_hdr(struct dp_packet *b, int mtu)
/* The packet has good L4 checksum. No need to validate again. */
vnet->csum_start = vnet->csum_offset = (OVS_FORCE __virtio16) 0;
vnet->flags = VIRTIO_NET_HDR_F_DATA_VALID;
- if (!dp_packet_ip_checksum_good(b)) {
- /* It is possible that L4 is good but the IP checksum isn't
- * complete. For example in the case of UDP encapsulation of an ARP
- * packet where the UDP checksum is 0. */
+
+ /* It is possible that L4 is good but the IPv4 checksum isn't
+ * complete. For example in the case of UDP encapsulation of an ARP
+ * packet where the UDP checksum is 0. */
+ if (dp_packet_hwol_l3_csum_ipv4_ol(b)) {
dp_packet_ip_set_header_csum(b, false);
}
} else if (dp_packet_hwol_tx_l4_checksum(b)) {
Previously a change was added to the vnet prepend code to solve for the case where no L4 checksum offloading was needed but the L3 checksum hadn't been calculated. But the added check didn't properly account for IPv6 traffic. Fixes: 85bcbbed839a ("userspace: Enable tunnel tests with TSO.") Reported-by: David Marchand <david.marchand@redhat.com> Signed-off-by: Mike Pattrick <mkp@redhat.com> --- lib/dp-packet.h | 18 +++++++++++++++++- lib/netdev-linux.c | 9 +++++---- 2 files changed, 22 insertions(+), 5 deletions(-)