Hello Mike,
On Fri, Oct 21, 2022 at 5:37 AM Mike Pattrick <[email protected]> wrote:
>
> From: Flavio Leitner <[email protected]>
>
> The netdev receiving packets is supposed to provide the flags
> indicating if the L4 csum was verified and it is OK or BAD,
> otherwise the stack will check when appropriate by software.
>
> If the packet comes with good checksum, then postpone the
> checksum calculation to the egress device if needed.
>
> When encapsulate a packet with that flag, set the checksum
> of the inner L4 header since that is not yet supported.
>
> Calculate the L4 csum when the packet is going to be sent over
> a device that doesn't support the feature.
>
> Linux tap devices allows enabling L3 and L4 offload, so this
> patch enables the feature. However, Linux socket interface
> remains disabled because the API doesn't allow enabling
> those two features without enabling TSO too.
>
> Signed-off-by: Flavio Leitner <[email protected]>
> Co-authored-by: Mike Pattrick <[email protected]>
> Signed-off-by: Mike Pattrick <[email protected]>
> ---
> lib/conntrack.c | 15 +--
> lib/dp-packet.c | 24 ++++
> lib/dp-packet.h | 78 ++++++++++++-
> lib/flow.c | 23 ++++
> lib/netdev-dpdk.c | 188 ++++++++++++++++++++----------
> lib/netdev-linux.c | 252 ++++++++++++++++++++++++++--------------
> lib/netdev-native-tnl.c | 32 +----
> lib/netdev.c | 46 ++------
> lib/packets.c | 175 ++++++++++++++++++++++------
> lib/packets.h | 3 +
> 10 files changed, 579 insertions(+), 257 deletions(-)
>
> diff --git a/lib/conntrack.c b/lib/conntrack.c
> index 973f6cdb0..5b20a10dc 100644
> --- a/lib/conntrack.c
> +++ b/lib/conntrack.c
> @@ -2118,13 +2118,12 @@ conn_key_extract(struct conntrack *ct, struct
> dp_packet *pkt, ovs_be16 dl_type,
> }
>
> if (ok) {
> - bool hwol_bad_l4_csum = dp_packet_l4_checksum_bad(pkt);
> - if (!hwol_bad_l4_csum) {
> - bool hwol_good_l4_csum = dp_packet_l4_checksum_good(pkt)
> - || dp_packet_hwol_tx_l4_checksum(pkt);
> + if (!dp_packet_l4_checksum_bad(pkt)) {
> /* Validate the checksum only when hwol is not supported. */
> if (extract_l4(&ctx->key, l4, dp_packet_l4_size(pkt),
> - &ctx->icmp_related, l3, !hwol_good_l4_csum,
> + &ctx->icmp_related, l3,
> + !dp_packet_l4_checksum_good(pkt) &&
> + !dp_packet_hwol_tx_l4_checksum(pkt),
> NULL)) {
> ctx->hash = conn_key_hash(&ctx->key, ct->hash_basis);
> return true;
> @@ -3449,8 +3448,10 @@ handle_ftp_ctl(struct conntrack *ct, const struct
> conn_lookup_ctx *ctx,
> adj_seqnum(&th->tcp_seq, ec->seq_skew);
> }
>
> - th->tcp_csum = 0;
> - if (!dp_packet_hwol_tx_l4_checksum(pkt)) {
> + if (dp_packet_hwol_tx_l4_checksum(pkt)) {
> + dp_packet_ol_reset_l4_csum_good(pkt);
> + } else {
> + th->tcp_csum = 0;
> if (ctx->key.dl_type == htons(ETH_TYPE_IPV6)) {
> th->tcp_csum = packet_csum_upperlayer6(nh6, th,
> ctx->key.nw_proto,
> dp_packet_l4_size(pkt));
> diff --git a/lib/dp-packet.c b/lib/dp-packet.c
> index 5609c2397..19b4e23be 100644
> --- a/lib/dp-packet.c
> +++ b/lib/dp-packet.c
> @@ -38,6 +38,9 @@ dp_packet_init__(struct dp_packet *b, size_t allocated,
> enum dp_packet_source so
> dp_packet_init_specific(b);
> /* By default assume the packet type to be Ethernet. */
> b->packet_type = htonl(PT_ETH);
> + /* Reset csum start and offset. */
> + b->csum_start = 0;
> + b->csum_offset = 0;
> }
>
> static void
> @@ -544,4 +547,25 @@ dp_packet_ol_send_prepare(struct dp_packet *p, const
> uint64_t flags)
> }
> dp_packet_hwol_reset_tx_ip_csum(p);
> }
> +
> + if (dp_packet_l4_checksum_good(p) || !dp_packet_hwol_tx_l4_checksum(p)) {
> + return;
> + }
> +
> + if (dp_packet_hwol_l4_is_tcp(p)
> + && !(flags & NETDEV_TX_OFFLOAD_TCP_CKSUM)) {
> + packet_tcp_complete_csum(p);
> + dp_packet_ol_set_l4_csum_good(p);
> + dp_packet_ol_reset_tx_l4_csum(p);
> + } else if (dp_packet_hwol_l4_is_udp(p)
> + && !(flags & NETDEV_TX_OFFLOAD_UDP_CKSUM)) {
> + packet_udp_complete_csum(p);
> + dp_packet_ol_set_l4_csum_good(p);
> + dp_packet_ol_reset_tx_l4_csum(p);
> + } else if (!(flags & NETDEV_TX_OFFLOAD_SCTP_CKSUM)
> + && dp_packet_hwol_l4_is_sctp(p)) {
> + packet_sctp_complete_csum(p);
> + dp_packet_ol_set_l4_csum_good(p);
> + dp_packet_ol_reset_tx_l4_csum(p);
> + }
> }
Same as my comment on patch 3, if OVS knows the l4 checksum is good,
it's better not to request hw offloading.
if (dp_packet_l4_checksum_good(p) || !dp_packet_hwol_tx_l4_checksum(p)) {
+ dp_packet_ol_reset_tx_l4_csum(p);
return;
}
> diff --git a/lib/dp-packet.h b/lib/dp-packet.h
> index f60618716..a2c450682 100644
> --- a/lib/dp-packet.h
> +++ b/lib/dp-packet.h
> @@ -140,6 +140,8 @@ struct dp_packet {
> or UINT16_MAX. */
> uint32_t cutlen; /* length in bytes to cut from the end. */
> ovs_be32 packet_type; /* Packet type as defined in OpenFlow */
> + uint16_t csum_start; /* Position to start checksumming from. */
> + uint16_t csum_offset; /* Offset to place checksum. */
> union {
> struct pkt_metadata md;
> uint64_t data[DP_PACKET_CONTEXT_SIZE / 8];
> @@ -995,6 +997,13 @@ dp_packet_hwol_is_ipv4(const struct dp_packet *b)
> return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_IPV4);
> }
>
> +/* Returns 'true' if packet 'p' is marked as IPv6. */
> +static inline bool
> +dp_packet_ol_tx_ipv6(const struct dp_packet *p)
For consistency: dp_packet_hwol_is_ipv6.
> +{
> + return !!(*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_TX_IPV6);
> +}
> +
> /* Returns 'true' if packet 'b' is marked for TCP checksum offloading. */
> static inline bool
> dp_packet_hwol_l4_is_tcp(const struct dp_packet *b)
> @@ -1019,18 +1028,26 @@ dp_packet_hwol_l4_is_sctp(struct dp_packet *b)
> DP_PACKET_OL_TX_SCTP_CKSUM;
> }
>
> -/* Mark packet 'b' for IPv4 checksum offloading. */
> static inline void
> -dp_packet_hwol_set_tx_ipv4(struct dp_packet *b)
> +dp_packet_ol_reset_tx_l4_csum(struct dp_packet *p)
> +{
> + *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_TX_L4_MASK;
> +}
For consistency, dp_packet_hwol_reset_tx_l4_csum.
The rest lgtm.
I'll do a final pass on next revision.
--
David Marchand
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev