Skip to content

Commit 2e03f55

Browse files
david-marchandkevintraynor
authored andcommitted
netdev-dpdk: Fallback to non tunnel checksum offloading.
The outer checksum offloading API in DPDK is ambiguous and was implemented by Intel folks in their drivers with the assumption that any outer offloading always goes with an inner offloading request. With net/i40e and net/ice drivers, in the case of encapsulating a ARP packet in a vxlan tunnel (which results in requesting outer ip checksum with a tunnel context but no inner offloading request), a Tx failure is triggered, associated with a port MDD event. 2024-03-27T16:02:07.084Z|00018|dpdk|WARN|ice_interrupt_handler(): OICR: MDD event To avoid this situation, if no checksum or segmentation offloading is requested on the inner part of a packet, fallback to "normal" (non outer) offloading request. Reported-at: openvswitch/ovs-issues#321 Fixes: 084c808 ("userspace: Support VXLAN and GENEVE TSO.") Fixes: f81d782 ("netdev-native-tnl: Mark all vxlan/geneve packets as tunneled.") Signed-off-by: David Marchand <[email protected]> Acked-by: Kevin Traynor <[email protected]> Signed-off-by: Kevin Traynor <[email protected]>
1 parent 7916a24 commit 2e03f55

File tree

1 file changed

+41
-30
lines changed

1 file changed

+41
-30
lines changed

lib/netdev-dpdk.c

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,16 +2583,18 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
25832583
struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf);
25842584
struct tcp_header *th;
25852585

2586-
const uint64_t all_requests = (RTE_MBUF_F_TX_IP_CKSUM |
2587-
RTE_MBUF_F_TX_L4_MASK |
2588-
RTE_MBUF_F_TX_OUTER_IP_CKSUM |
2589-
RTE_MBUF_F_TX_OUTER_UDP_CKSUM |
2590-
RTE_MBUF_F_TX_TCP_SEG);
2591-
const uint64_t all_marks = (RTE_MBUF_F_TX_IPV4 |
2592-
RTE_MBUF_F_TX_IPV6 |
2593-
RTE_MBUF_F_TX_OUTER_IPV4 |
2594-
RTE_MBUF_F_TX_OUTER_IPV6 |
2595-
RTE_MBUF_F_TX_TUNNEL_MASK);
2586+
const uint64_t all_inner_requests = (RTE_MBUF_F_TX_IP_CKSUM |
2587+
RTE_MBUF_F_TX_L4_MASK |
2588+
RTE_MBUF_F_TX_TCP_SEG);
2589+
const uint64_t all_outer_requests = (RTE_MBUF_F_TX_OUTER_IP_CKSUM |
2590+
RTE_MBUF_F_TX_OUTER_UDP_CKSUM);
2591+
const uint64_t all_requests = all_inner_requests | all_outer_requests;
2592+
const uint64_t all_inner_marks = (RTE_MBUF_F_TX_IPV4 |
2593+
RTE_MBUF_F_TX_IPV6);
2594+
const uint64_t all_outer_marks = (RTE_MBUF_F_TX_OUTER_IPV4 |
2595+
RTE_MBUF_F_TX_OUTER_IPV6 |
2596+
RTE_MBUF_F_TX_TUNNEL_MASK);
2597+
const uint64_t all_marks = all_inner_marks | all_outer_marks;
25962598

25972599
if (!(mbuf->ol_flags & all_requests)) {
25982600
/* No offloads requested, no marks should be set. */
@@ -2613,34 +2615,43 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
26132615
* l2 len and outer l3 len. Inner l2/l3/l4 len are calculated
26142616
* before. */
26152617
const uint64_t tunnel_type = mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK;
2616-
if (tunnel_type == RTE_MBUF_F_TX_TUNNEL_GENEVE ||
2617-
tunnel_type == RTE_MBUF_F_TX_TUNNEL_VXLAN) {
2618-
mbuf->outer_l2_len = (char *) dp_packet_l3(pkt) -
2619-
(char *) dp_packet_eth(pkt);
2620-
mbuf->outer_l3_len = (char *) dp_packet_l4(pkt) -
2621-
(char *) dp_packet_l3(pkt);
2622-
2623-
/* If neither inner checksums nor TSO is requested, inner marks
2624-
* should not be set. */
2625-
if (!(mbuf->ol_flags & (RTE_MBUF_F_TX_IP_CKSUM |
2626-
RTE_MBUF_F_TX_L4_MASK |
2627-
RTE_MBUF_F_TX_TCP_SEG))) {
2628-
mbuf->ol_flags &= ~(RTE_MBUF_F_TX_IPV4 |
2629-
RTE_MBUF_F_TX_IPV6);
2630-
}
2631-
} else if (OVS_UNLIKELY(tunnel_type)) {
2618+
if (OVS_UNLIKELY(tunnel_type &&
2619+
tunnel_type != RTE_MBUF_F_TX_TUNNEL_GENEVE &&
2620+
tunnel_type != RTE_MBUF_F_TX_TUNNEL_VXLAN)) {
26322621
VLOG_WARN_RL(&rl, "%s: Unexpected tunnel type: %#"PRIx64,
26332622
netdev_get_name(&dev->up), tunnel_type);
26342623
netdev_dpdk_mbuf_dump(netdev_get_name(&dev->up),
26352624
"Packet with unexpected tunnel type", mbuf);
26362625
return false;
2626+
}
2627+
2628+
if (tunnel_type && (mbuf->ol_flags & all_inner_requests)) {
2629+
mbuf->outer_l2_len = (char *) dp_packet_l3(pkt) -
2630+
(char *) dp_packet_eth(pkt);
2631+
mbuf->outer_l3_len = (char *) dp_packet_l4(pkt) -
2632+
(char *) dp_packet_l3(pkt);
26372633
} else {
2638-
mbuf->l2_len = (char *) dp_packet_l3(pkt) -
2639-
(char *) dp_packet_eth(pkt);
2640-
mbuf->l3_len = (char *) dp_packet_l4(pkt) -
2641-
(char *) dp_packet_l3(pkt);
2634+
if (tunnel_type) {
2635+
/* No inner offload is requested, fallback to non tunnel
2636+
* checksum offloads. */
2637+
mbuf->ol_flags &= ~all_inner_marks;
2638+
if (mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM) {
2639+
mbuf->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM;
2640+
mbuf->ol_flags |= RTE_MBUF_F_TX_IPV4;
2641+
}
2642+
if (mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM) {
2643+
mbuf->ol_flags |= RTE_MBUF_F_TX_UDP_CKSUM;
2644+
mbuf->ol_flags |= mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_IPV4
2645+
? RTE_MBUF_F_TX_IPV4 : RTE_MBUF_F_TX_IPV6;
2646+
}
2647+
mbuf->ol_flags &= ~(all_outer_requests | all_outer_marks);
2648+
}
26422649
mbuf->outer_l2_len = 0;
26432650
mbuf->outer_l3_len = 0;
2651+
mbuf->l2_len = (char *) dp_packet_l3(pkt) -
2652+
(char *) dp_packet_eth(pkt);
2653+
mbuf->l3_len = (char *) dp_packet_l4(pkt) -
2654+
(char *) dp_packet_l3(pkt);
26442655
}
26452656
th = dp_packet_l4(pkt);
26462657

0 commit comments

Comments
 (0)