2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-05 00:35:33 +00:00

dp-packet: Rework L4 checksum offloads.

The DPDK mbuf API specifies 4 status when it comes to L4 checksums:
- RTE_MBUF_F_RX_L4_CKSUM_UNKNOWN: no information about the RX L4 checksum
- RTE_MBUF_F_RX_L4_CKSUM_BAD: the L4 checksum in the packet is wrong
- RTE_MBUF_F_RX_L4_CKSUM_GOOD: the L4 checksum in the packet is valid
- RTE_MBUF_F_RX_L4_CKSUM_NONE: the L4 checksum is not correct in the packet
  data, but the integrity of the L4 data is verified.

Similarly to the IP checksum offloads API, revise OVS L4 offloads API.

No information about the L4 protocol is provided by any netdev-*
implementation, so OVS needs to mark this L4 protocol during flow
extraction.

Rename current API for consistency with dp_packet_(inner_)?l4_checksum_.

Signed-off-by: David Marchand <david.marchand@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
David Marchand
2025-06-17 09:20:58 +02:00
committed by Ilya Maximets
parent 3daf04a4c5
commit 2956a61265
13 changed files with 358 additions and 398 deletions

View File

@@ -2652,19 +2652,22 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
{
struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf);
const struct ip_header *ip;
bool is_sctp;
bool l3_csum;
bool l4_csum;
bool is_tcp;
bool is_udp;
void *l2;
void *l3;
void *l4;
const uint64_t all_inner_requests = (RTE_MBUF_F_TX_L4_MASK
| RTE_MBUF_F_TX_TCP_SEG);
const uint64_t all_outer_requests = RTE_MBUF_F_TX_OUTER_UDP_CKSUM;
const uint64_t all_requests = all_inner_requests | all_outer_requests;
const uint64_t all_inner_requests = RTE_MBUF_F_TX_TCP_SEG;
if (!dp_packet_ip_checksum_partial(pkt)
&& !dp_packet_inner_ip_checksum_partial(pkt)
&& !(mbuf->ol_flags & all_requests)) {
&& !dp_packet_l4_checksum_partial(pkt)
&& !dp_packet_inner_l4_checksum_partial(pkt)
&& !(mbuf->ol_flags & all_inner_requests)) {
uint64_t unexpected = mbuf->ol_flags & RTE_MBUF_F_TX_OFFLOAD_MASK;
if (OVS_UNLIKELY(unexpected)) {
@@ -2679,9 +2682,10 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
if (dp_packet_tunnel(pkt)
&& (dp_packet_inner_ip_checksum_partial(pkt)
|| dp_packet_inner_l4_checksum_partial(pkt)
|| (mbuf->ol_flags & all_inner_requests))) {
if (dp_packet_ip_checksum_partial(pkt)
|| (mbuf->ol_flags & all_outer_requests)) {
|| dp_packet_l4_checksum_partial(pkt)) {
mbuf->outer_l2_len = (char *) dp_packet_l3(pkt) -
(char *) dp_packet_eth(pkt);
mbuf->outer_l3_len = (char *) dp_packet_l4(pkt) -
@@ -2700,6 +2704,11 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
mbuf->ol_flags |= RTE_MBUF_F_TX_OUTER_IP_CKSUM;
}
if (dp_packet_l4_checksum_partial(pkt)) {
ovs_assert(dp_packet_l4_proto_udp(pkt));
mbuf->ol_flags |= RTE_MBUF_F_TX_OUTER_UDP_CKSUM;
}
ip = dp_packet_l3(pkt);
mbuf->ol_flags |= IP_VER(ip->ip_ihl_ver) == 4
? RTE_MBUF_F_TX_OUTER_IPV4
@@ -2710,6 +2719,10 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
l3 = dp_packet_inner_l3(pkt);
l3_csum = dp_packet_inner_ip_checksum_partial(pkt);
l4 = dp_packet_inner_l4(pkt);
l4_csum = dp_packet_inner_l4_checksum_partial(pkt);
is_tcp = dp_packet_inner_l4_proto_tcp(pkt);
is_udp = dp_packet_inner_l4_proto_udp(pkt);
is_sctp = dp_packet_inner_l4_proto_sctp(pkt);
} else {
mbuf->outer_l2_len = 0;
mbuf->outer_l3_len = 0;
@@ -2719,16 +2732,12 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
l3 = dp_packet_inner_l3(pkt);
l3_csum = dp_packet_inner_ip_checksum_partial(pkt);
l4 = dp_packet_inner_l4(pkt);
l4_csum = dp_packet_inner_l4_checksum_partial(pkt);
is_tcp = dp_packet_inner_l4_proto_tcp(pkt);
is_udp = dp_packet_inner_l4_proto_udp(pkt);
is_sctp = dp_packet_inner_l4_proto_sctp(pkt);
}
} else {
if (dp_packet_tunnel(pkt)) {
/* No inner offload is requested, fallback to non tunnel
* checksum offloads. */
if (mbuf->ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM) {
mbuf->ol_flags |= RTE_MBUF_F_TX_UDP_CKSUM;
}
mbuf->ol_flags &= ~all_outer_requests;
}
mbuf->outer_l2_len = 0;
mbuf->outer_l3_len = 0;
@@ -2736,6 +2745,10 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
l3 = dp_packet_l3(pkt);
l3_csum = dp_packet_ip_checksum_partial(pkt);
l4 = dp_packet_l4(pkt);
l4_csum = dp_packet_l4_checksum_partial(pkt);
is_tcp = dp_packet_l4_proto_tcp(pkt);
is_udp = dp_packet_l4_proto_udp(pkt);
is_sctp = dp_packet_l4_proto_sctp(pkt);
}
ovs_assert(l4);
@@ -2748,6 +2761,17 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
mbuf->ol_flags |= RTE_MBUF_F_TX_IP_CKSUM;
}
if (l4_csum) {
if (is_tcp) {
mbuf->ol_flags |= RTE_MBUF_F_TX_TCP_CKSUM;
} else if (is_udp) {
mbuf->ol_flags |= RTE_MBUF_F_TX_UDP_CKSUM;
} else {
ovs_assert(is_sctp);
mbuf->ol_flags |= RTE_MBUF_F_TX_SCTP_CKSUM;
}
}
mbuf->l2_len = (char *) l3 - (char *) l2;
mbuf->l3_len = (char *) l4 - (char *) l3;