On 27 Aug 2024, at 22:31, Mike Pattrick wrote:

> When sending packets that are flagged as requiring segmentation to an
> interface that does not support this feature, send the packet to the TSO
> software fallback instead of dropping it.
>
> Reviewed-by: David Marchand <[email protected]>
> Signed-off-by: Mike Pattrick <[email protected]>

I think the code looks good, I did some style cleanups on the unit tests.

See the diffs below, if there are no technical blocking comments coming, we 
could apply these during the commit.

Cheers,

Eelco

> ---
> v2:
>  - Fixed udp tunnel length
>  - Added test that UDP headers are correct
>  - Split inner and outer ip_id into different counters
>  - Set tunnel flags in reset_tcp_seg
>
> v3:
>  - Changed logic of netdev_send() to account for NICs that support
>  tunnel offload but not checksum offload
>  - Adjusted udp tunnel header length during software tso
>
> v4:
>  - Moved a bugfix into its own patch
>  - Fixed an indentation issue
>  - Changed the scope of ip_hdr
>
> v5:
>  - Change order of tso fallback check
>  - Added a unit test
> v6:
>  - Removed segsize adjustment patch, adjusted tests to accomidate.
> Signed-off-by: Mike Pattrick <[email protected]>
> ---
>  lib/dp-packet-gso.c     |  90 ++++++++++++++++-----
>  lib/dp-packet.h         |  34 ++++++++
>  lib/netdev.c            |  44 +++++-----
>  tests/dpif-netdev.at    | 173 ++++++++++++++++++++++++++++++++++++++++
>  tests/system-traffic.at |  95 ++++++++++++++++++++++
>  5 files changed, 395 insertions(+), 41 deletions(-)
>
> diff --git a/lib/dp-packet-gso.c b/lib/dp-packet-gso.c
> index 847685ad9..04ebb19da 100644
> --- a/lib/dp-packet-gso.c
> +++ b/lib/dp-packet-gso.c
> @@ -47,6 +47,8 @@ dp_packet_gso_seg_new(const struct dp_packet *p, size_t 
> hdr_len,
>      seg->l2_5_ofs = p->l2_5_ofs;
>      seg->l3_ofs = p->l3_ofs;
>      seg->l4_ofs = p->l4_ofs;
> +    seg->inner_l3_ofs = p->inner_l3_ofs;
> +    seg->inner_l4_ofs = p->inner_l4_ofs;
>
>      /* The protocol headers remain the same, so preserve hash and mark. */
>      *dp_packet_rss_ptr(seg) = *dp_packet_rss_ptr(p);
> @@ -71,7 +73,12 @@ dp_packet_gso_nr_segs(struct dp_packet *p)
>      const char *data_tail;
>      const char *data_pos;
>
> -    data_pos = dp_packet_get_tcp_payload(p);
> +    if (dp_packet_hwol_is_tunnel_vxlan(p) ||
> +        dp_packet_hwol_is_tunnel_geneve(p)) {
> +        data_pos = dp_packet_get_inner_tcp_payload(p);
> +    } else {
> +        data_pos = dp_packet_get_tcp_payload(p);
> +    }
>      data_tail = (char *) dp_packet_tail(p) - dp_packet_l2_pad_size(p);
>
>      return DIV_ROUND_UP(data_tail - data_pos, segsz);
> @@ -89,14 +96,16 @@ dp_packet_gso(struct dp_packet *p, struct dp_packet_batch 
> **batches)
>      static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
>      struct dp_packet_batch *curr_batch = *batches;
>      struct tcp_header *tcp_hdr;
> -    struct ip_header *ip_hdr;
> +    uint16_t inner_ip_id = 0;
> +    uint16_t outer_ip_id = 0;
>      struct dp_packet *seg;
>      uint16_t tcp_offset;
>      uint16_t tso_segsz;
>      uint32_t tcp_seq;
> -    uint16_t ip_id;
> +    bool outer_ipv4;
>      int hdr_len;
>      int seg_len;
> +    bool tnl;
>
>      tso_segsz = dp_packet_get_tso_segsz(p);
>      if (!tso_segsz) {
> @@ -105,20 +114,37 @@ dp_packet_gso(struct dp_packet *p, struct 
> dp_packet_batch **batches)
>          return false;
>      }
>
> -    tcp_hdr = dp_packet_l4(p);
> +    if (dp_packet_hwol_is_tunnel_vxlan(p) ||
> +        dp_packet_hwol_is_tunnel_geneve(p)) {
> +        outer_ipv4 = dp_packet_hwol_is_outer_ipv4(p);
> +        tcp_hdr = dp_packet_inner_l4(p);
> +        tnl = true;
> +
> +        if (outer_ipv4) {
> +            outer_ip_id = ntohs(((struct ip_header *) 
> dp_packet_l3(p))->ip_id);
> +        }
> +        if (dp_packet_hwol_is_ipv4(p)) {
> +            struct ip_header *ip_hdr = dp_packet_inner_l3(p);
> +            inner_ip_id = ntohs(ip_hdr->ip_id);
> +        }
> +    } else {
> +        outer_ipv4 = dp_packet_hwol_is_ipv4(p);
> +        tcp_hdr = dp_packet_l4(p);
> +        tnl = false;
> +
> +        if (outer_ipv4) {
> +            struct ip_header *ip_hdr = dp_packet_l3(p);
> +            outer_ip_id = ntohs(ip_hdr->ip_id);
> +        }
> +    }
> +
>      tcp_offset = TCP_OFFSET(tcp_hdr->tcp_ctl);
>      tcp_seq = ntohl(get_16aligned_be32(&tcp_hdr->tcp_seq));
> -    hdr_len = ((char *) dp_packet_l4(p) - (char *) dp_packet_eth(p))
> +    hdr_len = ((char *) tcp_hdr - (char *) dp_packet_eth(p))
>                + tcp_offset * 4;
> -    ip_id = 0;
> -    if (dp_packet_hwol_is_ipv4(p)) {
> -        ip_hdr = dp_packet_l3(p);
> -        ip_id = ntohs(ip_hdr->ip_id);
> -    }
> -
>      const char *data_tail = (char *) dp_packet_tail(p)
>                              - dp_packet_l2_pad_size(p);
> -    const char *data_pos = dp_packet_get_tcp_payload(p);
> +    const char *data_pos = (char *) tcp_hdr + tcp_offset * 4;
>      int n_segs = dp_packet_gso_nr_segs(p);
>
>      for (int i = 0; i < n_segs; i++) {
> @@ -130,14 +156,36 @@ dp_packet_gso(struct dp_packet *p, struct 
> dp_packet_batch **batches)
>          seg = dp_packet_gso_seg_new(p, hdr_len, data_pos, seg_len);
>          data_pos += seg_len;
>
> +        if (tnl) {
> +            /* Update tunnel UDP header length. */
> +            struct udp_header *tnl_hdr;
> +
> +            tnl_hdr = dp_packet_l4(seg);
> +            tnl_hdr->udp_len = htons(dp_packet_l4_size(seg));
> +
> +            /* Update tunnel inner L3 header. */
> +            if (dp_packet_hwol_is_ipv4(seg)) {
> +                struct ip_header *ip_hdr = dp_packet_inner_l3(seg);
> +                ip_hdr->ip_tot_len = htons(dp_packet_inner_l3_size(seg));
> +                ip_hdr->ip_id = htons(inner_ip_id);
> +                ip_hdr->ip_csum = 0;
> +                inner_ip_id++;
> +            } else {
> +                struct ovs_16aligned_ip6_hdr *ip6_hdr;
> +
> +                ip6_hdr = dp_packet_inner_l3(seg);
> +                ip6_hdr->ip6_ctlun.ip6_un1.ip6_un1_plen
> +                    = htons(dp_packet_inner_l3_size(seg) - sizeof *ip6_hdr);
> +            }
> +        }
> +
>          /* Update L3 header. */
> -        if (dp_packet_hwol_is_ipv4(seg)) {
> -            ip_hdr = dp_packet_l3(seg);
> -            ip_hdr->ip_tot_len = htons(sizeof *ip_hdr +
> -                                       dp_packet_l4_size(seg));
> -            ip_hdr->ip_id = htons(ip_id);
> +        if (outer_ipv4) {
> +            struct ip_header *ip_hdr = dp_packet_l3(seg);
> +            ip_hdr->ip_tot_len = htons(dp_packet_l3_size(seg));
> +            ip_hdr->ip_id = htons(outer_ip_id);
>              ip_hdr->ip_csum = 0;
> -            ip_id++;
> +            outer_ip_id++;
>          } else {
>              struct ovs_16aligned_ip6_hdr *ip6_hdr = dp_packet_l3(seg);
>
> @@ -146,7 +194,11 @@ dp_packet_gso(struct dp_packet *p, struct 
> dp_packet_batch **batches)
>          }
>
>          /* Update L4 header. */
> -        tcp_hdr = dp_packet_l4(seg);
> +        if (tnl) {
> +            tcp_hdr = dp_packet_inner_l4(seg);
> +        } else {
> +            tcp_hdr = dp_packet_l4(seg);
> +        }
>          put_16aligned_be32(&tcp_hdr->tcp_seq, htonl(tcp_seq));
>          tcp_seq += seg_len;
>          if (OVS_LIKELY(i < (n_segs - 1))) {
> diff --git a/lib/dp-packet.h b/lib/dp-packet.h
> index a75b1c5cd..af1ff088f 100644
> --- a/lib/dp-packet.h
> +++ b/lib/dp-packet.h
> @@ -529,6 +529,16 @@ dp_packet_inner_l3(const struct dp_packet *b)
>             : NULL;
>  }
>
> +static inline size_t
> +dp_packet_inner_l3_size(const struct dp_packet *b)
> +{
> +    return OVS_LIKELY(b->inner_l3_ofs != UINT16_MAX)
> +           ? (const char *) dp_packet_tail(b)
> +           - (const char *) dp_packet_inner_l3(b)
> +           - dp_packet_l2_pad_size(b)
> +           : 0;
> +}
> +
>  static inline void *
>  dp_packet_inner_l4(const struct dp_packet *b)
>  {
> @@ -563,6 +573,22 @@ dp_packet_get_tcp_payload(const struct dp_packet *b)
>      return NULL;
>  }
>
> +static inline const void *
> +dp_packet_get_inner_tcp_payload(const struct dp_packet *b)
> +{
> +    size_t l4_size = dp_packet_inner_l4_size(b);
> +
> +    if (OVS_LIKELY(l4_size >= TCP_HEADER_LEN)) {
> +        struct tcp_header *tcp = dp_packet_inner_l4(b);
> +        int tcp_len = TCP_OFFSET(tcp->tcp_ctl) * 4;
> +
> +        if (OVS_LIKELY(tcp_len >= TCP_HEADER_LEN && tcp_len <= l4_size)) {
> +            return (const char *) tcp + tcp_len;
> +        }
> +    }
> +    return NULL;
> +}
> +
>  static inline uint32_t
>  dp_packet_get_tcp_payload_length(const struct dp_packet *pkt)
>  {
> @@ -1320,6 +1346,14 @@ dp_packet_hwol_reset_tcp_seg(struct dp_packet *p)
>          ol_flags |= DP_PACKET_OL_TX_IP_CKSUM;
>      }
>
> +    if (ol_flags & (DP_PACKET_OL_TX_TUNNEL_VXLAN |
> +                    DP_PACKET_OL_TX_TUNNEL_GENEVE)) {
> +        if (ol_flags & DP_PACKET_OL_TX_OUTER_IPV4) {
> +            ol_flags |= DP_PACKET_OL_TX_OUTER_IP_CKSUM;
> +        }
> +        ol_flags |= DP_PACKET_OL_TX_OUTER_UDP_CKSUM;
> +    }
> +
>      *dp_packet_ol_flags_ptr(p) = ol_flags;
>  }
>
> diff --git a/lib/netdev.c b/lib/netdev.c
> index f2d921ed6..02beac9d0 100644
> --- a/lib/netdev.c
> +++ b/lib/netdev.c
> @@ -69,8 +69,6 @@ COVERAGE_DEFINE(netdev_received);
>  COVERAGE_DEFINE(netdev_sent);
>  COVERAGE_DEFINE(netdev_add_router);
>  COVERAGE_DEFINE(netdev_get_stats);
> -COVERAGE_DEFINE(netdev_vxlan_tso_drops);
> -COVERAGE_DEFINE(netdev_geneve_tso_drops);
>  COVERAGE_DEFINE(netdev_push_header_drops);
>  COVERAGE_DEFINE(netdev_soft_seg_good);
>  COVERAGE_DEFINE(netdev_soft_seg_drops);
> @@ -910,28 +908,30 @@ netdev_send(struct netdev *netdev, int qid, struct 
> dp_packet_batch *batch,
>      struct dp_packet *packet;
>      int error;
>
> -    if (userspace_tso_enabled() &&
> -        !(netdev_flags & NETDEV_TX_OFFLOAD_TCP_TSO)) {
> -        DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
> -            if (dp_packet_hwol_is_tso(packet)) {
> -                if (dp_packet_hwol_is_tunnel_vxlan(packet)
> -                    && !(netdev_flags & NETDEV_TX_VXLAN_TNL_TSO)) {
> -                        VLOG_WARN_RL(&rl, "%s: No VXLAN TSO support",
> -                                     netdev_get_name(netdev));
> -                        COVERAGE_INC(netdev_vxlan_tso_drops);
> -                        dp_packet_delete_batch(batch, true);
> -                        return false;
> +    if (userspace_tso_enabled()) {
> +        if (!(netdev_flags & NETDEV_TX_OFFLOAD_TCP_TSO)) {
> +            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
> +                if (dp_packet_hwol_is_tso(packet)) {
> +                    return netdev_send_tso(netdev, qid, batch, 
> concurrent_txq);
>                  }
> -
> -                if (dp_packet_hwol_is_tunnel_geneve(packet)
> -                    && !(netdev_flags & NETDEV_TX_GENEVE_TNL_TSO)) {
> -                        VLOG_WARN_RL(&rl, "%s: No GENEVE TSO support",
> -                                     netdev_get_name(netdev));
> -                        COVERAGE_INC(netdev_geneve_tso_drops);
> -                        dp_packet_delete_batch(batch, true);
> -                        return false;
> +            }
> +        } else if (!(netdev_flags & (NETDEV_TX_VXLAN_TNL_TSO |
> +                                     NETDEV_TX_GENEVE_TNL_TSO))) {
> +            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
> +                if (dp_packet_hwol_is_tso(packet) &&
> +                    (dp_packet_hwol_is_tunnel_vxlan(packet) ||
> +                     dp_packet_hwol_is_tunnel_geneve(packet))) {
> +                    return netdev_send_tso(netdev, qid, batch, 
> concurrent_txq);
> +                }
> +            }
> +        } else if (!(netdev_flags & NETDEV_TX_OFFLOAD_OUTER_UDP_CKSUM)) {
> +            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
> +                if (dp_packet_hwol_is_tso(packet) &&
> +                    (dp_packet_hwol_is_tunnel_vxlan(packet) ||
> +                     dp_packet_hwol_is_tunnel_geneve(packet)) &&
> +                    dp_packet_hwol_is_outer_udp_cksum(packet)) {
> +                    return netdev_send_tso(netdev, qid, batch, 
> concurrent_txq);
>                  }
> -                return netdev_send_tso(netdev, qid, batch, concurrent_txq);
>              }
>          }
>      }
> diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at
> index bdc24cc30..2977bfe77 100644
> --- a/tests/dpif-netdev.at
> +++ b/tests/dpif-netdev.at
> @@ -884,6 +884,179 @@ AT_CHECK_UNQUOTED([ovs-pcap p2.pcap], [0], [dnl
>  OVS_VSWITCHD_STOP
>  AT_CLEANUP
>
> +AT_SETUP([userspace offload - tunnel tso fallback])

This test could use some cleanup to be <80 chars where possible. Here is a diff:

diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at
index fddad7839..36cea6aa9 100644
--- a/tests/dpif-netdev.at
+++ b/tests/dpif-netdev.at
@@ -921,8 +921,10 @@ AT_CLEANUP

 AT_SETUP([userspace offload - tunnel tso fallback])
 OVS_VSWITCHD_START([set Open_vSwitch . other_config:userspace-tso-enable=true \
-                    -- add-br br1 -- set bridge br1 datapath-type=dummy 
other-config:hwaddr=aa:55:aa:55:00:03 \
-                    -- add-port br1 p1 -- set Interface p1 type=dummy 
ofport_request=1])
+                    -- add-br br1 -- set bridge br1 datapath-type=dummy \
+                       other-config:hwaddr=aa:55:aa:55:00:03 \
+                    -- add-port br1 p1 -- set Interface p1 type=dummy \
+                       ofport_request=1])
 AT_CHECK([ovs-vsctl add-br int-br -- set bridge int-br datapath_type=dummy \
                     -- add-port int-br t1 -- set Interface t1 type=vxlan \
                        options:remote_ip=1.1.2.92 options:key=123 \
@@ -937,12 +939,12 @@ AT_CHECK([ovs-vsctl add-br int-br -- set bridge int-br 
datapath_type=dummy \
                        options:remote_ip=2001:cafe::93 options:key=123 \
                        options:csum=true ofport_request=5], [0])

-flow_s="eth(src=8a:bf:7e:2f:05:84,dst=0a:8f:39:4f:e0:73),eth_type(0x0800), \
-        
ipv4(src=192.168.123.2,dst=192.168.123.1,proto=6,tos=1,ttl=64,frag=no), \
+flow_s="eth(src=8a:bf:7e:2f:05:84,dst=0a:8f:39:4f:e0:73),eth_type(0x0800),
+        ipv4(src=192.168.123.2,dst=192.168.123.1,proto=6,tos=1,ttl=64,frag=no),
         tcp(src=54392,dst=5201),tcp_flags(ack)"

-flow_s_v6="eth(src=8a:bf:7e:2f:05:84,dst=0a:8f:39:4f:e0:73),eth_type(0x86dd), \
-           ipv6(src=2001:cafe::88,dst=2001:cafe::92,proto=6), \
+flow_s_v6="eth(src=8a:bf:7e:2f:05:84,dst=0a:8f:39:4f:e0:73),eth_type(0x86dd),
+           ipv6(src=2001:cafe::88,dst=2001:cafe::92,proto=6),
            tcp(src=54392,dst=5201),tcp_flags(ack)"

 dnl Setup dummy interface tunnel connectivity.
@@ -952,7 +954,8 @@ AT_CHECK([ovs-appctl netdev-dummy/ip6addr br1 
2001:cafe::88/24], [0], [OK
 ])
 AT_CHECK([ovs-appctl tnl/neigh/set br1 1.1.2.92 aa:bb:cc:00:00:01], [0], [OK
 ])
-AT_CHECK([ovs-appctl tnl/neigh/set br1 2001:cafe::93 aa:bb:cc:00:00:06], [0], 
[OK
+AT_CHECK([ovs-appctl tnl/neigh/set br1 2001:cafe::93 aa:bb:cc:00:00:06], [0],
+         [OK
 ])
 AT_CHECK([ovs-appctl tnl/egress_port_range 57363 57363], [0], [OK
 ])
@@ -965,8 +968,10 @@ AT_CHECK([ovs-vsctl set Interface p1 
options:tx_pcap=p1.pcap -- \
                     set Interface int-br options:ol_ip_csum_set_good=false -- \
                     set Interface int-br options:ol_tso_segsz=500])

-AT_CHECK([ovs-appctl netdev-dummy/receive int-br "in_port(2),${flow_s}" --len 
2054])
-AT_CHECK([ovs-appctl netdev-dummy/receive int-br "in_port(2),${flow_s_v6}" 
--len 2074])
+AT_CHECK([ovs-appctl netdev-dummy/receive int-br "in_port(2),${flow_s}" \
+          --len 2054])
+AT_CHECK([ovs-appctl netdev-dummy/receive int-br "in_port(2),${flow_s_v6}" \
+          --len 2074])

 dnl Check that first we have the following packets:
 dnl - IPv4 VXLAN tunnel with IPv4 payload
@@ -979,7 +984,7 @@ dnl - IPv6 Geneve tunnel with IPv4 payload
 dnl - IPv6 Geneve tunnel with IPv6 payload
 dnl - IPv6 Geneve tunnel with IPv4 payload
 dnl - IPv6 Geneve tunnel with IPv6 payload
-dnl These are sorted because OVS may send the payloads to the tunnels in any 
order.
+dnl These are sorted since OVS may send payloads to the tunnels in any order.
 zero400=$(printf '0%.0s' $(seq 800))
 zero100=$(printf '0%.0s' $(seq 200))
 AT_CHECK_UNQUOTED([ovs-pcap p1.pcap | sort], [0], [dnl

> +OVS_VSWITCHD_START([set Open_vSwitch . 
> other_config:userspace-tso-enable=true \
> +                    -- add-br br1 -- set bridge br1 datapath-type=dummy 
> other-config:hwaddr=aa:55:aa:55:00:03 \
> +                    -- add-port br1 p1 -- set Interface p1 type=dummy 
> ofport_request=1])
> +AT_CHECK([ovs-vsctl add-br int-br -- set bridge int-br datapath_type=dummy \
> +                    -- add-port int-br t1 -- set Interface t1 type=vxlan \
> +                       options:remote_ip=1.1.2.92 options:key=123 \
> +                       options:csum=true ofport_request=2 \
> +                    -- add-port int-br t2 -- set Interface t2 type=geneve \
> +                       options:remote_ip=1.1.2.92 options:key=123 \
> +                       options:csum=true ofport_request=3 \
> +                    -- add-port int-br t3 -- set Interface t3 type=vxlan \
> +                       options:remote_ip=2001:cafe::93 options:key=123 \
> +                       options:csum=true ofport_request=4 \
> +                    -- add-port int-br t4 -- set Interface t4 type=geneve \
> +                       options:remote_ip=2001:cafe::93 options:key=123 \
> +                       options:csum=true ofport_request=5], [0])
> +
> +flow_s="eth(src=8a:bf:7e:2f:05:84,dst=0a:8f:39:4f:e0:73),eth_type(0x0800), \
> +        
> ipv4(src=192.168.123.2,dst=192.168.123.1,proto=6,tos=1,ttl=64,frag=no), \
> +        tcp(src=54392,dst=5201),tcp_flags(ack)"
> +
> +flow_s_v6="eth(src=8a:bf:7e:2f:05:84,dst=0a:8f:39:4f:e0:73),eth_type(0x86dd),
>  \
> +           ipv6(src=2001:cafe::88,dst=2001:cafe::92,proto=6), \
> +           tcp(src=54392,dst=5201),tcp_flags(ack)"
> +
> +dnl Setup dummy interface tunnel connectivity.
> +AT_CHECK([ovs-appctl netdev-dummy/ip4addr br1 1.1.2.88/24], [0], [OK
> +])
> +AT_CHECK([ovs-appctl netdev-dummy/ip6addr br1 2001:cafe::88/24], [0], [OK
> +])
> +AT_CHECK([ovs-appctl tnl/neigh/set br1 1.1.2.92 aa:bb:cc:00:00:01], [0], [OK
> +])
> +AT_CHECK([ovs-appctl tnl/neigh/set br1 2001:cafe::93 aa:bb:cc:00:00:06], 
> [0], [OK
> +])
> +AT_CHECK([ovs-appctl tnl/egress_port_range 57363 57363], [0], [OK
> +])
> +AT_CHECK([ovs-ofctl add-flow br1 action=normal])
> +AT_CHECK([ovs-ofctl add-flow int-br action=normal])
> +
> +dnl Configure the TX interface to segment.
> +AT_CHECK([ovs-vsctl set Interface p1 options:tx_pcap=p1.pcap -- \
> +                    set Interface int-br options:ol_ip_csum=true -- \
> +                    set Interface int-br options:ol_ip_csum_set_good=false 
> -- \
> +                    set Interface int-br options:ol_tso_segsz=500])
> +
> +AT_CHECK([ovs-appctl netdev-dummy/receive int-br "in_port(2),${flow_s}" 
> --len 2054])
> +AT_CHECK([ovs-appctl netdev-dummy/receive int-br "in_port(2),${flow_s_v6}" 
> --len 2074])
> +
> +dnl Check that first we have the following packets:
> +dnl - IPv4 VXLAN tunnel with IPv4 payload
> +dnl - IPv4 VXLAN tunnel with IPv6 payload
> +dnl - IPv6 VXLAN tunnel with IPv4 payload
> +dnl - IPv6 VXLAN tunnel with IPv6 payload
> +dnl - IPv4 Geneve tunnel with IPv4 payload
> +dnl - IPv4 Geneve tunnel with IPv6 payload
> +dnl - IPv6 Geneve tunnel with IPv4 payload
> +dnl - IPv6 Geneve tunnel with IPv6 payload
> +dnl - IPv6 Geneve tunnel with IPv4 payload
> +dnl - IPv6 Geneve tunnel with IPv6 payload
> +dnl These are sorted because OVS may send the payloads to the tunnels in any 
> order.
> +zero400=$(printf '0%.0s' $(seq 800))
> +zero100=$(printf '0%.0s' $(seq 200))
> +AT_CHECK_UNQUOTED([ovs-pcap p1.pcap | sort], [0], [dnl
> +[aabbcc000001aa55aa55000308004500026200004000401131d6010102580101025ce01312b5024e5f360800000000007b00]dnl
> +[0a8f394fe0738abf7e2f058486dd60000000020806002001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000092d4781451000000000000000050100000edfd0000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004500026200004000401131d6010102580101025ce01317c1024efcd10000655800007b00]dnl
> +[0a8f394fe0738abf7e2f058486dd60000000020806002001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000092d4781451000000000000000050100000edfd0000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004500026200014000401131d5010102580101025ce01312b5024e5f360800000000007b00]dnl
> +[0a8f394fe0738abf7e2f058486dd60000000020806002001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000092d4781451000001f40000000050100000ec090000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004500026200014000401131d5010102580101025ce01317c1024efcd10000655800007b00]dnl
> +[0a8f394fe0738abf7e2f058486dd60000000020806002001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000092d4781451000001f40000000050100000ec090000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004500026200024000401131d4010102580101025ce01312b5024e5f360800000000007b00]dnl
> +[0a8f394fe0738abf7e2f058486dd60000000020806002001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000092d4781451000003e80000000050100000ea150000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004500026200024000401131d4010102580101025ce01317c1024efcd10000655800007b00]dnl
> +[0a8f394fe0738abf7e2f058486dd60000000020806002001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000092d4781451000003e80000000050100000ea150000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004500026200034000401131d3010102580101025ce01312b5024e5f360800000000007b00]dnl
> +[0a8f394fe0738abf7e2f058486dd60000000020806002001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000092d4781451000005dc0000000050100000e8210000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004500026200034000401131d3010102580101025ce01317c1024efcd10000655800007b00]dnl
> +[0a8f394fe0738abf7e2f058486dd60000000020806002001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000092d4781451000005dc0000000050100000e8210000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004501024e00004000401131e9010102580101025ce01312b5023abd990800000000007b00]dnl
> +[0a8f394fe0738abf7e2f058408004501021c0000000040060187c0a87b02c0a87b01d4781451000000000000000050100000]dnl
> +[4dc20000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004501024e00004000401131e9010102580101025ce01317c1023a5b350000655800007b00]dnl
> +[0a8f394fe0738abf7e2f058408004501021c0000000040060187c0a87b02c0a87b01d4781451000000000000000050100000]dnl
> +[4dc20000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004501024e00014000401131e8010102580101025ce01312b5023abd990800000000007b00]dnl
> +[0a8f394fe0738abf7e2f058408004501021c0001000040060186c0a87b02c0a87b01d4781451000001f40000000050100000]dnl
> +[4bce0000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004501024e00014000401131e8010102580101025ce01317c1023a5b350000655800007b00]dnl
> +[0a8f394fe0738abf7e2f058408004501021c0001000040060186c0a87b02c0a87b01d4781451000001f40000000050100000]dnl
> +[4bce0000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004501024e00024000401131e7010102580101025ce01312b5023abd990800000000007b00]dnl
> +[0a8f394fe0738abf7e2f058408004501021c0002000040060185c0a87b02c0a87b01d4781451000003e80000000050100000]dnl
> +[49da0000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004501024e00024000401131e7010102580101025ce01317c1023a5b350000655800007b00]dnl
> +[0a8f394fe0738abf7e2f058408004501021c0002000040060185c0a87b02c0a87b01d4781451000003e80000000050100000]dnl
> +[49da0000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004501024e00034000401131e6010102580101025ce01312b5023abd990800000000007b00]dnl
> +[0a8f394fe0738abf7e2f058408004501021c0003000040060184c0a87b02c0a87b01d4781451000005dc0000000050100000]dnl
> +[47e60000${zero100}${zero400}]
> +[aabbcc000001aa55aa55000308004501024e00034000401131e6010102580101025ce01317c1023a5b350000655800007b00]dnl
> +[0a8f394fe0738abf7e2f058408004501021c0003000040060184c0a87b02c0a87b01d4781451000005dc0000000050100000]dnl
> +[47e60000${zero100}${zero400}]
> +[aabbcc000006aa55aa55000386dd60000000024e11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01312b5024e8ed10800000000007b000a8f394fe0738abf7e2f058486dd60000000020806002001cafe00000000]dnl
> +[00000000000000882001cafe000000000000000000000092d4781451000000000000000050100000edfd0000${zero100}]dnl
> +[${zero400}]
> +[aabbcc000006aa55aa55000386dd60000000024e11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01312b5024e8ed10800000000007b000a8f394fe0738abf7e2f058486dd60000000020806002001cafe00000000]dnl
> +[00000000000000882001cafe000000000000000000000092d4781451000001f40000000050100000ec090000${zero100}]dnl
> +[${zero400}]
> +[aabbcc000006aa55aa55000386dd60000000024e11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01312b5024e8ed10800000000007b000a8f394fe0738abf7e2f058486dd60000000020806002001cafe00000000]dnl
> +[00000000000000882001cafe000000000000000000000092d4781451000003e80000000050100000ea150000${zero100}]dnl
> +[${zero400}]
> +[aabbcc000006aa55aa55000386dd60000000024e11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01312b5024e8ed10800000000007b000a8f394fe0738abf7e2f058486dd60000000020806002001cafe00000000]dnl
> +[00000000000000882001cafe000000000000000000000092d4781451000005dc0000000050100000e8210000${zero100}]dnl
> +[${zero400}]
> +[aabbcc000006aa55aa55000386dd60000000024e11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01317c1024e2c6d0000655800007b000a8f394fe0738abf7e2f058486dd60000000020806002001cafe00000000]dnl
> +[00000000000000882001cafe000000000000000000000092d4781451000000000000000050100000edfd0000${zero100}]dnl
> +[${zero400}]
> +[aabbcc000006aa55aa55000386dd60000000024e11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01317c1024e2c6d0000655800007b000a8f394fe0738abf7e2f058486dd60000000020806002001cafe00000000]dnl
> +[00000000000000882001cafe000000000000000000000092d4781451000001f40000000050100000ec090000${zero100}]dnl
> +[${zero400}]
> +[aabbcc000006aa55aa55000386dd60000000024e11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01317c1024e2c6d0000655800007b000a8f394fe0738abf7e2f058486dd60000000020806002001cafe00000000]dnl
> +[00000000000000882001cafe000000000000000000000092d4781451000003e80000000050100000ea150000${zero100}]dnl
> +[${zero400}]
> +[aabbcc000006aa55aa55000386dd60000000024e11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01317c1024e2c6d0000655800007b000a8f394fe0738abf7e2f058486dd60000000020806002001cafe00000000]dnl
> +[00000000000000882001cafe000000000000000000000092d4781451000005dc0000000050100000e8210000${zero100}]dnl
> +[${zero400}]
> +[aabbcc000006aa55aa55000386dd60100000023a11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01312b5023aed340800000000007b000a8f394fe0738abf7e2f058408004501021c0000000040060187c0a87b02]dnl
> +[c0a87b01d47814510000000000000000501000004dc20000${zero100}${zero400}]
> +[aabbcc000006aa55aa55000386dd60100000023a11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01312b5023aed340800000000007b000a8f394fe0738abf7e2f058408004501021c0001000040060186c0a87b02]dnl
> +[c0a87b01d4781451000001f400000000501000004bce0000${zero100}${zero400}]
> +[aabbcc000006aa55aa55000386dd60100000023a11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01312b5023aed340800000000007b000a8f394fe0738abf7e2f058408004501021c0002000040060185c0a87b02]dnl
> +[c0a87b01d4781451000003e8000000005010000049da0000${zero100}${zero400}]
> +[aabbcc000006aa55aa55000386dd60100000023a11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01312b5023aed340800000000007b000a8f394fe0738abf7e2f058408004501021c0003000040060184c0a87b02]dnl
> +[c0a87b01d4781451000005dc000000005010000047e60000${zero100}${zero400}]
> +[aabbcc000006aa55aa55000386dd60100000023a11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01317c1023a8ad00000655800007b000a8f394fe0738abf7e2f058408004501021c0000000040060187c0a87b02]dnl
> +[c0a87b01d47814510000000000000000501000004dc20000${zero100}${zero400}]
> +[aabbcc000006aa55aa55000386dd60100000023a11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01317c1023a8ad00000655800007b000a8f394fe0738abf7e2f058408004501021c0001000040060186c0a87b02]dnl
> +[c0a87b01d4781451000001f400000000501000004bce0000${zero100}${zero400}]
> +[aabbcc000006aa55aa55000386dd60100000023a11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01317c1023a8ad00000655800007b000a8f394fe0738abf7e2f058408004501021c0002000040060185c0a87b02]dnl
> +[c0a87b01d4781451000003e8000000005010000049da0000${zero100}${zero400}]
> +[aabbcc000006aa55aa55000386dd60100000023a11402001cafe0000000000000000000000882001cafe0000000000000000]dnl
> +[00000093e01317c1023a8ad00000655800007b000a8f394fe0738abf7e2f058408004501021c0003000040060184c0a87b02]dnl
> +[c0a87b01d4781451000005dc000000005010000047e60000${zero100}${zero400}]
> +])
> +
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
>  AT_SETUP([dpif-netdev - revalidators handle dp modification fail correctly])
>  OVS_VSWITCHD_START(
>    [add-port br0 p1 \
> diff --git a/tests/system-traffic.at b/tests/system-traffic.at
> index 202ff0492..02d5ccbcb 100644
> --- a/tests/system-traffic.at
> +++ b/tests/system-traffic.at
> @@ -351,6 +351,101 @@ OVS_WAIT_UNTIL([diff -q payload.bin udp_data])
>  OVS_TRAFFIC_VSWITCHD_STOP
>  AT_CLEANUP
>
> +AT_SETUP([datapath - tcp over vxlan tunnel with software fallback])
> +AT_SKIP_IF([test $HAVE_NC = no])
> +AT_SKIP_IF([test $HAVE_TCPDUMP = no])
> +OVS_CHECK_VXLAN()
> +
> +dnl This test is only valid with tso. If the kernel segments the packets, the
> +dnl packet lengths in the final test will be different.
> +m4_ifndef([CHECK_SYSTEM_TSO], [AT_SKIP_IF(:)])
> +
> +OVS_TRAFFIC_VSWITCHD_START()
> +ADD_BR([br-underlay])
> +
> +AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
> +AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
> +
> +ADD_NAMESPACES(at_ns0)
> +
> +dnl Set up underlay link from host into the namespace using veth pair.
> +ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")
> +AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
> +AT_CHECK([ip link set dev br-underlay up])
> +
> +dnl Test the case where only one side has all checksum and tso offload 
> disabled.
> +AT_CHECK([ethtool -K ovs-p0 tso off], [0], [ignore], [ignore])
> +AT_CHECK([ethtool -K ovs-p0 sg off], [0], [ignore], [ignore])
> +
> +dnl Reinitialize.
> +AT_CHECK([ovs-vsctl del-port ovs-p0])
> +AT_CHECK([ovs-vsctl add-port br-underlay ovs-p0])
> +
> +dnl Set up tunnel endpoints on OVS outside the namespace and with a native
> +dnl linux device inside the namespace.
> +ADD_OVS_TUNNEL([vxlan], [br0], [at_vxlan0], [172.31.1.1], [10.1.1.100/24])
> +ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], 
> [10.1.1.1/24],
> +                  [id 0 dstport 4789])
> +
> +dnl Set MTU for tunnel to generate 1500 byte packets.
> +AT_CHECK([ip link set dev br0 mtu 1400])
> +
> +dnl First, check the underlay.
> +NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 172.31.1.100 | 
> FORMAT_PING], [0], [dnl
> +3 packets transmitted, 3 received, 0% packet loss, time 0ms
> +])
> +
> +dnl Check that the tunnel is up.
> +NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 10.1.1.100 | FORMAT_PING], 
> [0], [dnl
> +3 packets transmitted, 3 received, 0% packet loss, time 0ms
> +])
> +
> +dnl Start tcpdump to capture the encapsulated packets.
> +OVS_DAEMONIZE([tcpdump -i ovs-p0 -w p0.pcap], [tcpdump.pid])
> +
> +dnl Wait until the pcap is written, which happens after the interface
> +dnl is opened by tcpdump.
> +OVS_WAIT_UNTIL([test -e p0.pcap])
> +
> +dnl Initialize the listener before it is needed.
> +NETNS_DAEMONIZE([at_ns0], [nc -l 10.1.1.1 1234 > data2], [nc.pid])
> +
> +dnl Verify that ncat is ready.
> +OVS_WAIT_UNTIL([NS_EXEC([at_ns0], [netstat -ln | grep :1234])])
> +
> +dnl Large TCP transfer aimed towards ovs-p0, which has TSO disabled.
> +AT_CHECK([dd if=/dev/urandom of=payload.bin bs=60000 count=1 2> /dev/null])
> +AT_CHECK([nc $NC_EOF_OPT 10.1.1.1 1234 < payload.bin])
> +
> +dnl Wait until transfer completes before checking.
> +OVS_WAIT_WHILE([kill -0 $(cat nc.pid)])
> +AT_CHECK([diff -q payload.bin data2], [0])
> +dnl sleep 5

I guess this is a test leftover which should be removed.

> +OVS_WAIT_WHILE([test $(stat -c %s p0.pcap) -le 68000 ])
> +
> +dnl Stop OVS and tcpdump and verify the results.
> +
> +AT_CHECK([kill -15 $(cat tcpdump.pid)])
> +
> +OVS_WAIT_WHILE([kill -0 $(cat tcpdump.pid)])
> +
> +ovs-pcap p0.pcap

Also a left over.

> +dnl The exact number of packets sent will vary, but we check that the 
> largest segments have the correct
> +dnl lengths and certain other fields.
> +AT_CHECK([test $(ovs-pcap p0.pcap | grep -Ec dnl
> +"^.{24}0800"dnl Ethernet
> +"450005aa....4000..11....ac1f0164ac1f0101"dnl IP(len=1450, DF, UDP, 
> 172.31.1.100->172.31.1.1)
> +"....12b505960000"dnl UDP(len=1430, dport=4789)
> +"0800000000000000"dnl VXLAN(gpid=0, vni=0)
> +".{24}0800"dnl Ethernet
> +"45000578....4000..06....0a0101640a010101"dnl IP(len=1400, DF, TCP, 
> 10.1.1.100->10.1.1.1)
> +"....04d2............................0000"dnl TCP(dport=1234
> +) -ge 20])
> +

I cleaned up this test to be 80 chars wide and removed some cr/lf and the 
leftover commands.
This is the diff:

diff --git a/tests/system-traffic.at b/tests/system-traffic.at
index 02d5ccbcb..724b25fa9 100644
--- a/tests/system-traffic.at
+++ b/tests/system-traffic.at
@@ -373,7 +373,7 @@ ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24")
 AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
 AT_CHECK([ip link set dev br-underlay up])

-dnl Test the case where only one side has all checksum and tso offload 
disabled.
+dnl Test the case where one side has all checksum and TSO offload disabled.
 AT_CHECK([ethtool -K ovs-p0 tso off], [0], [ignore], [ignore])
 AT_CHECK([ethtool -K ovs-p0 sg off], [0], [ignore], [ignore])

@@ -384,19 +384,21 @@ AT_CHECK([ovs-vsctl add-port br-underlay ovs-p0])
 dnl Set up tunnel endpoints on OVS outside the namespace and with a native
 dnl linux device inside the namespace.
 ADD_OVS_TUNNEL([vxlan], [br0], [at_vxlan0], [172.31.1.1], [10.1.1.100/24])
-ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], 
[10.1.1.1/24],
-                  [id 0 dstport 4789])
+ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100],
+                  [10.1.1.1/24], [id 0 dstport 4789])

 dnl Set MTU for tunnel to generate 1500 byte packets.
 AT_CHECK([ip link set dev br0 mtu 1400])

 dnl First, check the underlay.
-NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 172.31.1.100 | FORMAT_PING], 
[0], [dnl
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 172.31.1.100 | FORMAT_PING],
+              [0], [dnl
 3 packets transmitted, 3 received, 0% packet loss, time 0ms
 ])

 dnl Check that the tunnel is up.
-NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 10.1.1.100 | FORMAT_PING], 
[0], [dnl
+NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 10.1.1.100 | FORMAT_PING],
+              [0], [dnl
 3 packets transmitted, 3 received, 0% packet loss, time 0ms
 ])

@@ -420,19 +422,14 @@ AT_CHECK([nc $NC_EOF_OPT 10.1.1.1 1234 < payload.bin])
 dnl Wait until transfer completes before checking.
 OVS_WAIT_WHILE([kill -0 $(cat nc.pid)])
 AT_CHECK([diff -q payload.bin data2], [0])
-dnl sleep 5
 OVS_WAIT_WHILE([test $(stat -c %s p0.pcap) -le 68000 ])

 dnl Stop OVS and tcpdump and verify the results.
-
 AT_CHECK([kill -15 $(cat tcpdump.pid)])
-
 OVS_WAIT_WHILE([kill -0 $(cat tcpdump.pid)])

-ovs-pcap p0.pcap
-
-dnl The exact number of packets sent will vary, but we check that the largest 
segments have the correct
-dnl lengths and certain other fields.
+dnl The exact number of packets sent will vary, but we check that the largest
+dnl segments have the correct lengths and certain other fields.
 AT_CHECK([test $(ovs-pcap p0.pcap | grep -Ec dnl
 "^.{24}0800"dnl Ethernet
 "450005aa....4000..11....ac1f0164ac1f0101"dnl IP(len=1450, DF, UDP, 
172.31.1.100->172.31.1.1)

> +OVS_TRAFFIC_VSWITCHD_STOP
> +AT_CLEANUP
> +
>  AT_SETUP([datapath - ping vlan over vxlan tunnel])
>  OVS_CHECK_TUNNEL_TSO()
>  OVS_CHECK_VXLAN()
> -- 
> 2.43.5
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev

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

Reply via email to