2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +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

@@ -810,7 +810,6 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
uint8_t nw_frag, nw_tos, nw_ttl, nw_proto;
uint8_t *ct_nw_proto_p = NULL;
ovs_be16 ct_tp_src = 0, ct_tp_dst = 0;
bool tunneling;
/* Metadata. */
if (flow_tnl_dst_is_set(&md->tunnel)) {
@@ -864,8 +863,7 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
/* Initialize packet's layer pointer and offsets. */
frame = data;
tunneling = dp_packet_tunnel(packet);
if (tunneling) {
if (dp_packet_tunnel(packet)) {
/* Preserve inner offsets from previous circulation. */
dp_packet_reset_outer_offsets(packet);
} else {
@@ -1063,10 +1061,7 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
} else if (dl_type == htons(ETH_TYPE_IPV6)) {
dp_packet_update_rss_hash_ipv6_tcp_udp(packet);
}
if (dp_packet_l4_checksum_good(packet)
|| dp_packet_ol_l4_csum_partial(packet)) {
dp_packet_hwol_set_csum_tcp(packet);
}
dp_packet_l4_proto_set_tcp(packet);
}
}
} else if (OVS_LIKELY(nw_proto == IPPROTO_UDP)) {
@@ -1082,14 +1077,7 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
} else if (dl_type == htons(ETH_TYPE_IPV6)) {
dp_packet_update_rss_hash_ipv6_tcp_udp(packet);
}
if (dp_packet_l4_checksum_good(packet)
|| dp_packet_ol_l4_csum_partial(packet)) {
if (tunneling) {
dp_packet_hwol_set_outer_udp_csum(packet);
} else {
dp_packet_hwol_set_csum_udp(packet);
}
}
dp_packet_l4_proto_set_udp(packet);
}
} else if (OVS_LIKELY(nw_proto == IPPROTO_SCTP)) {
if (OVS_LIKELY(size >= SCTP_HEADER_LEN)) {
@@ -1099,10 +1087,7 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
miniflow_push_be16(mf, tp_dst, sctp->sctp_dst);
miniflow_push_be16(mf, ct_tp_src, ct_tp_src);
miniflow_push_be16(mf, ct_tp_dst, ct_tp_dst);
if (dp_packet_l4_checksum_good(packet)
|| dp_packet_ol_l4_csum_partial(packet)) {
dp_packet_hwol_set_csum_sctp(packet);
}
dp_packet_l4_proto_set_sctp(packet);
}
} else if (OVS_LIKELY(nw_proto == IPPROTO_ICMP)) {
if (OVS_LIKELY(size >= ICMP_HEADER_LEN)) {
@@ -1284,21 +1269,12 @@ parse_tcp_flags(struct dp_packet *packet,
if (nw_proto == IPPROTO_TCP && size >= TCP_HEADER_LEN) {
const struct tcp_header *tcp = data;
if (dp_packet_l4_checksum_good(packet)
|| dp_packet_ol_l4_csum_partial(packet)) {
dp_packet_hwol_set_csum_tcp(packet);
}
dp_packet_l4_proto_set_tcp(packet);
return TCP_FLAGS(tcp->tcp_ctl);
} else if (nw_proto == IPPROTO_UDP && size >= UDP_HEADER_LEN) {
if (dp_packet_l4_checksum_good(packet)
|| dp_packet_ol_l4_csum_partial(packet)) {
dp_packet_hwol_set_csum_udp(packet);
}
dp_packet_l4_proto_set_udp(packet);
} else if (nw_proto == IPPROTO_SCTP && size >= SCTP_HEADER_LEN) {
if (dp_packet_l4_checksum_good(packet)
|| dp_packet_ol_l4_csum_partial(packet)) {
dp_packet_hwol_set_csum_sctp(packet);
}
dp_packet_l4_proto_set_sctp(packet);
}
}
@@ -3245,7 +3221,7 @@ flow_compose_l4_csum(struct dp_packet *p, const struct flow *flow,
tcp->tcp_csum = 0;
tcp->tcp_csum = csum_finish(csum_continue(pseudo_hdr_csum,
tcp, l4_len));
dp_packet_ol_set_l4_csum_good(p);
dp_packet_l4_checksum_set_good(p);
} else if (flow->nw_proto == IPPROTO_UDP) {
struct udp_header *udp = dp_packet_l4(p);
@@ -3255,7 +3231,7 @@ flow_compose_l4_csum(struct dp_packet *p, const struct flow *flow,
if (!udp->udp_csum) {
udp->udp_csum = htons(0xffff);
}
dp_packet_ol_set_l4_csum_good(p);
dp_packet_l4_checksum_set_good(p);
} else if (flow->nw_proto == IPPROTO_ICMP) {
struct icmp_header *icmp = dp_packet_l4(p);