Test that netdev-dummy is able to send and recieve segment offloaded packets.
Signed-off-by: Mike Pattrick <[email protected]> --- v2: Fix clang build error: mutex needed to access netdev_dummy members Signed-off-by: Mike Pattrick <[email protected]> --- lib/netdev-dummy.c | 32 +++++++++++++++++++++++++++- tests/dpif-netdev.at | 50 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 8c6e6d448..9d9a28892 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -44,6 +44,7 @@ #include "unaligned.h" #include "timeval.h" #include "unixctl.h" +#include "userspace-tso.h" #include "reconnect.h" VLOG_DEFINE_THIS_MODULE(netdev_dummy); @@ -152,6 +153,8 @@ struct netdev_dummy { bool ol_ip_csum OVS_GUARDED; /* Flag RX packet with good csum. */ bool ol_ip_csum_set_good OVS_GUARDED; + /* Set the segment size for netdev TSO support. */ + int ol_tso_segsz OVS_GUARDED; }; /* Max 'recv_queue_len' in struct netdev_dummy. */ @@ -806,6 +809,10 @@ netdev_dummy_get_config(const struct netdev *dev, struct smap *args) smap_add_format(args, "ol_ip_csum_set_good", "%s", "true"); } + if (netdev->ol_tso_segsz && userspace_tso_enabled()) { + smap_add_format(args, "ol_tso_segsz", "%d", netdev->ol_tso_segsz); + } + /* 'dummy-pmd' specific config. */ if (!netdev_is_pmd(dev)) { goto exit; @@ -937,6 +944,14 @@ netdev_dummy_set_config(struct netdev *netdev_, const struct smap *args, netdev_->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM; } + if (userspace_tso_enabled()) { + netdev->ol_tso_segsz = smap_get_int(args, "ol_tso_segsz", 0); + if (netdev->ol_tso_segsz) { + netdev_->ol_flags |= (NETDEV_TX_OFFLOAD_TCP_TSO + | NETDEV_TX_OFFLOAD_TCP_CKSUM); + } + } + netdev_change_seq_changed(netdev_); /* 'dummy-pmd' specific config. */ @@ -1119,6 +1134,15 @@ netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet_batch *batch, /* The netdev hardware sets the flag when the packet has good csum. */ dp_packet_ol_set_ip_csum_good(packet); } + + if (userspace_tso_enabled() && netdev->ol_tso_segsz) { + dp_packet_set_tso_segsz(packet, netdev->ol_tso_segsz); + dp_packet_hwol_set_tcp_seg(packet); + dp_packet_hwol_set_tx_ip_csum(packet); + dp_packet_hwol_set_tx_ipv4(packet); + dp_packet_hwol_set_csum_tcp(packet); + } + ovs_mutex_unlock(&netdev->mutex); dp_packet_batch_init_packet(batch, packet); @@ -1174,6 +1198,12 @@ netdev_dummy_send(struct netdev *netdev, int qid, DP_PACKET_BATCH_FOR_EACH(i, packet, batch) { const void *buffer = dp_packet_data(packet); size_t size = dp_packet_size(packet); + bool is_tso; + + ovs_mutex_lock(&dev->mutex); + is_tso = userspace_tso_enabled() && dev->ol_tso_segsz && + dp_packet_hwol_is_tso(packet); + ovs_mutex_unlock(&dev->mutex); if (!dp_packet_is_eth(packet)) { error = EPFNOSUPPORT; @@ -1194,7 +1224,7 @@ netdev_dummy_send(struct netdev *netdev, int qid, if (eth->eth_type == htons(ETH_TYPE_VLAN)) { max_size += VLAN_HEADER_LEN; } - if (size > max_size) { + if (size > max_size && !is_tso) { error = EMSGSIZE; break; } diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at index d0359b5ea..2d9b8eb5f 100644 --- a/tests/dpif-netdev.at +++ b/tests/dpif-netdev.at @@ -810,6 +810,56 @@ AT_CHECK_UNQUOTED([tail -n 1 p2.pcap.txt], [0], [${good_expected} OVS_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([userspace offload - tso]) +OVS_VSWITCHD_START( + [set Open_vSwitch . other_config:userspace-tso-enable=true -- \ + add-br br1 -- set bridge br1 datapath-type=dummy -- \ + add-port br1 p1 -- \ + set Interface p1 type=dummy -- \ + add-port br1 p2 -- \ + set Interface p2 type=dummy --]) + +dnl Modify the ip_dst addr to force changing the IP csum. +AT_CHECK([ovs-ofctl add-flow br1 in_port=p1,actions=output:p2]) + +flow_s="\ + eth_src=8a:bf:7e:2f:05:84,eth_dst=0a:8f:39:4f:e0:73,dl_type=0x0800,\ + nw_src=192.168.123.2,nw_dst=192.168.123.1,nw_proto=6,nw_ttl=64,nw_frag=no,\ + tp_src=54392,tp_dst=5201,tcp_flags=ack" + +payload=$(dd if=/dev/zero bs=2000 count=1 | hexdump -ve '1/1 "%02x"') + +big_frame=$(ovs-ofctl compose-packet --bare "${flow_s}" "${payload}") + +dnl Send from tso to no-tso. +AT_CHECK([ovs-vsctl set Interface p2 options:tx_pcap=p2.pcap]) +AT_CHECK([ovs-vsctl set Interface p1 options:ol_ip_csum=true]) +AT_CHECK([ovs-vsctl set Interface p1 options:ol_ip_csum_set_good=false]) +AT_CHECK([ovs-vsctl set Interface p1 options:ol_tso_segsz=500]) +AT_CHECK([ovs-appctl netdev-dummy/receive p1 ${big_frame}]) +AT_CHECK([tcpdump -vvnnr p2.pcap > p2.pcap.txt 2>&1]) + +dnl Send from tso to tso. +dnl AT_CHECK([ovs-vsctl set Interface p2 options:tx_pcap=p2_tso.pcap]) +AT_CHECK([ovs-vsctl set Interface p2 options:ol_ip_csum=true]) +AT_CHECK([ovs-vsctl set Interface p2 options:ol_ip_csum_set_good=false]) +AT_CHECK([ovs-vsctl set Interface p2 options:ol_tso_segsz=500]) +AT_CHECK([ovs-appctl netdev-dummy/receive p1 ${big_frame}]) +AT_CHECK([tcpdump -vvnnr p2.pcap > p2.pcap.txt 2>&1]) + +dnl Verify 5 packets with good checksums, 4 500 bytes and one 2000 bytes. +AT_CHECK([grep -c "length 2000" p2.pcap.txt], [0], [1 +]) +AT_CHECK([grep -c "length 500" p2.pcap.txt], [0], [4 +]) +AT_CHECK([grep -c "bad cksum" p2.pcap.txt], [1], [0 +]) +AT_CHECK([grep -c "incorrect" p2.pcap.txt], [1], [0 +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP + AT_SETUP([dpif-netdev - revalidators handle dp modification fail correctly]) OVS_VSWITCHD_START( [add-port br0 p1 \ -- 2.39.3 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
