On Thu, Feb 15, 2024 at 4:59 PM Mike Pattrick <[email protected]> wrote:
>
> Previously some packets were excluded from the tunnel mark if they
> weren't L4. However, this causes problems with multi encapsulated
> packets like arp.
>
> Due to these flags being set, additional checks are required in checksum
> modification code.
>
> Fixes: 084c8087292c ("userspace: Support VXLAN and GENEVE TSO.")
> Reported-by: David Marchand <[email protected]>
> Signed-off-by: Mike Pattrick <[email protected]>
> ---
>  lib/dp-packet.h         | 19 +++++++++++++++++--
>  lib/netdev-native-tnl.c | 10 ++++++++--
>  lib/packets.c           |  8 ++++----
>  3 files changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/lib/dp-packet.h b/lib/dp-packet.h
> index 770ddc1b9..2fa17d814 100644
> --- a/lib/dp-packet.h
> +++ b/lib/dp-packet.h
> @@ -1386,8 +1386,8 @@ dp_packet_ip_checksum_bad(const struct dp_packet *p)
>
>  /* 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'. */
> + * for IPv4 checksum offload. IPv6 packets, non offloaded packets, and IPv4
> + * packets that are marked as good return 'false'. */
>  static inline bool
>  dp_packet_hwol_l3_csum_ipv4_ol(const struct dp_packet *b)
>  {
> @@ -1400,6 +1400,21 @@ dp_packet_hwol_l3_csum_ipv4_ol(const struct dp_packet 
> *b)
>      return false;
>  }
>
> +/* 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_ipv4(const struct dp_packet *b)
> +{
> +    if (dp_packet_hwol_is_outer_ipv4(b)) {
> +        return true;
> +    } else if (!dp_packet_hwol_is_outer_ipv6(b)) {
> +        return dp_packet_hwol_tx_ip_csum(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)
> diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c
> index 0d6d803fe..dee9ab344 100644
> --- a/lib/netdev-native-tnl.c
> +++ b/lib/netdev-native-tnl.c
> @@ -91,8 +91,7 @@ netdev_tnl_ip_extract_tnl_md(struct dp_packet *packet, 
> struct flow_tnl *tnl,
>
>          /* A packet coming from a network device might have the
>           * csum already checked. In this case, skip the check. */
> -        if (OVS_UNLIKELY(!dp_packet_ip_checksum_good(packet))
> -            && !dp_packet_hwol_tx_ip_csum(packet)) {
> +        if (OVS_UNLIKELY(!dp_packet_hwol_l3_csum_ipv4_ol(packet))) {
>              if (csum(ip, IP_IHL(ip->ip_ihl_ver) * 4)) {
>                  VLOG_WARN_RL(&err_rl, "ip packet has invalid checksum");
>                  return NULL;
> @@ -299,6 +298,13 @@ dp_packet_tnl_ol_process(struct dp_packet *packet,
>                                           (char *) dp_packet_eth(packet) +
>                                           VXLAN_HLEN);
>          }
> +    } else {
> +        /* Mark non-l4 packets as tunneled. */
> +        if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) {
> +            dp_packet_hwol_set_tunnel_geneve(packet);
> +        } else if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) {
> +            dp_packet_hwol_set_tunnel_vxlan(packet);
> +        }
>      }
>  }
>
> diff --git a/lib/packets.c b/lib/packets.c
> index 36c6692e5..ed185b4ec 100644
> --- a/lib/packets.c
> +++ b/lib/packets.c
> @@ -1149,7 +1149,7 @@ packet_set_ipv4_addr(struct dp_packet *packet,
>          }
>      }
>
> -    if (dp_packet_hwol_tx_ip_csum(packet)) {
> +    if (dp_packet_hwol_l3_ipv4(packet)) {
>          dp_packet_ol_reset_ip_csum_good(packet);
>      } else {
>          nh->ip_csum = recalc_csum32(nh->ip_csum, old_addr, new_addr);
> @@ -1328,7 +1328,7 @@ packet_set_ipv4(struct dp_packet *packet, ovs_be32 src, 
> ovs_be32 dst,
>      if (nh->ip_tos != tos) {
>          uint8_t *field = &nh->ip_tos;
>
> -        if (dp_packet_hwol_tx_ip_csum(packet)) {
> +        if (dp_packet_hwol_l3_ipv4(packet)) {
>              dp_packet_ol_reset_ip_csum_good(packet);
>          } else {
>              nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t) 
> *field),
> @@ -1341,7 +1341,7 @@ packet_set_ipv4(struct dp_packet *packet, ovs_be32 src, 
> ovs_be32 dst,
>      if (nh->ip_ttl != ttl) {
>          uint8_t *field = &nh->ip_ttl;
>
> -        if (dp_packet_hwol_tx_ip_csum(packet)) {
> +        if (dp_packet_hwol_l3_ipv4(packet)) {
>              dp_packet_ol_reset_ip_csum_good(packet);
>          } else {
>              nh->ip_csum = recalc_csum16(nh->ip_csum, htons(*field << 8),
> @@ -1979,7 +1979,7 @@ IP_ECN_set_ce(struct dp_packet *pkt, bool is_ipv6)
>
>          tos |= IP_ECN_CE;
>          if (nh->ip_tos != tos) {
> -            if (dp_packet_hwol_tx_ip_csum(pkt)) {
> +            if (dp_packet_hwol_l3_ipv4(packet)) {

Will resubmit with this change corrected.

-M

>                  dp_packet_ol_reset_ip_csum_good(pkt);
>              } else {
>                  nh->ip_csum = recalc_csum16(nh->ip_csum, htons(nh->ip_tos),
> --
> 2.39.3
>

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to