Instead of dropping we can switch to software segmentation before encapsulating packets already encapsulated in a tunnel.
Signed-off-by: David Marchand <[email protected]> --- lib/netdev.c | 56 +++++++++++++++++----------------- tests/dpif-netdev.at | 71 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 27 deletions(-) diff --git a/lib/netdev.c b/lib/netdev.c index 1288ae7871..7cdab1e47d 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -964,43 +964,45 @@ netdev_push_header(const struct netdev *netdev, struct dp_packet_batch *batch, const struct ovs_action_push_tnl *data) { + bool supported_offloads = (data->tnl_type == OVS_VPORT_TYPE_GENEVE) + || (data->tnl_type == OVS_VPORT_TYPE_VXLAN) + || (data->tnl_type == OVS_VPORT_TYPE_GRE) + || (data->tnl_type == OVS_VPORT_TYPE_IP6GRE); struct dp_packet *packet; - size_t i, size = dp_packet_batch_size(batch); - DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, packet, batch) { - if (OVS_UNLIKELY(data->tnl_type != OVS_VPORT_TYPE_GENEVE && - data->tnl_type != OVS_VPORT_TYPE_VXLAN && - data->tnl_type != OVS_VPORT_TYPE_GRE && - data->tnl_type != OVS_VPORT_TYPE_IP6GRE && - dp_packet_get_tso_segsz(packet))) { - COVERAGE_INC(netdev_push_header_drops); - dp_packet_delete(packet); - VLOG_WARN_RL(&rl, "%s: Tunneling packets with TSO is not " - "supported for %s tunnels: packet dropped", - netdev_get_name(netdev), netdev_get_type(netdev)); - } else { - if (data->tnl_type != OVS_VPORT_TYPE_GENEVE && - data->tnl_type != OVS_VPORT_TYPE_VXLAN && - data->tnl_type != OVS_VPORT_TYPE_GRE && - data->tnl_type != OVS_VPORT_TYPE_IP6GRE) { - dp_packet_ol_send_prepare(packet, 0); - } else if (dp_packet_tunnel(packet)) { - if (dp_packet_get_tso_segsz(packet)) { + if (userspace_tso_enabled()) { + if (OVS_UNLIKELY(!supported_offloads)) { + size_t i, size = dp_packet_batch_size(batch); + + DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, packet, batch) { + if (OVS_UNLIKELY(dp_packet_get_tso_segsz(packet))) { COVERAGE_INC(netdev_push_header_drops); dp_packet_delete(packet); VLOG_WARN_RL(&rl, "%s: Tunneling packets with TSO is not " - "supported with multiple levels of " - "VXLAN, GENEVE, or GRE encapsulation.", - netdev_get_name(netdev)); + "supported for %s tunnels: packet dropped", + netdev_get_name(netdev), + netdev_get_type(netdev)); continue; } - dp_packet_ol_send_prepare(packet, 0); + dp_packet_batch_add(batch, packet); } - netdev->netdev_class->push_header(netdev, packet, data); + } else { + DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { + if (dp_packet_tunnel(packet) + && dp_packet_get_tso_segsz(packet)) { + dp_packet_gso_batch(batch); + break; + } + } + } + } - pkt_metadata_init(&packet->md, data->out_port); - dp_packet_batch_add(batch, packet); + DP_PACKET_BATCH_FOR_EACH (i, packet, batch) { + if (!supported_offloads || dp_packet_tunnel(packet)) { + dp_packet_ol_send_prepare(packet, 0); } + netdev->netdev_class->push_header(netdev, packet, data); + pkt_metadata_init(&packet->md, data->out_port); } return 0; diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at index b4eb64ffd0..4adef9428f 100644 --- a/tests/dpif-netdev.at +++ b/tests/dpif-netdev.at @@ -3436,6 +3436,77 @@ AT_CHECK([ovs-vsctl get interface p2 statistics:tx_packets], [0], [35 OVS_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([dpif-netdev - tso + dual tunnel encap]) +AT_KEYWORDS([userspace offload]) +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-br br2 -- set bridge br2 datapath-type=dummy -- \ + set bridge br2 other-config:hwaddr=aa:66:aa:66:00:00 -- \ + add-port br2 p2 -- \ + set Interface p2 type=dummy -- \ + add-br br3 -- set bridge br3 datapath-type=dummy -- \ + set bridge br3 other-config:hwaddr=aa:66:bb:66:00:00 -- \ + add-port br3 p3 -- \ + set Interface p3 type=dummy]) + +AT_CHECK([ovs-vsctl add-port br1 t1 \ + -- set Interface t1 type=vxlan \ + options:remote_ip=1.1.2.92 options:key=123 \ + ofport_request=11], [0]) +AT_CHECK([ovs-vsctl add-port br2 t2 \ + -- set Interface t2 type=vxlan \ + options:remote_ip=1.1.3.92 options:key=456 \ + ofport_request=21], [0]) + +AT_CHECK([ovs-ofctl del-flows br1]) +AT_CHECK([ovs-ofctl add-flow br1 in_port=p1,actions=output:11]) +AT_CHECK([ovs-ofctl del-flows br2]) +AT_CHECK([ovs-ofctl add-flow br2 in_port=br2,actions=output:21]) + +AT_CHECK([ovs-appctl netdev-dummy/ip4addr br2 1.1.2.88/24], [0], [OK +]) +AT_CHECK([ovs-appctl tnl/neigh/set br2 1.1.2.92 aa:66:aa:66:00:01], [0], [OK +]) +AT_CHECK([ovs-appctl netdev-dummy/ip4addr br3 1.1.3.88/24], [0], [OK +]) +AT_CHECK([ovs-appctl tnl/neigh/set br3 1.1.3.92 aa:66:bb:66:00:01], [0], [OK +]) + +AT_CHECK([ovs-vsctl set Interface p1 options:ol_tso_segsz=1000]) + +flow_s="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:01:00),eth_type(0x0800), \ + ipv4(src=10.0.1.1,dst=10.0.0.1,proto=6,tos=0,ttl=64,frag=no), \ + tcp(src=1234,dst=80),tcp_flags(ack)" +AT_CHECK([ovs-appctl netdev-dummy/receive p1 "${flow_s}" --len 2000]) + +dnl Interface statistics and coverage counters take some time to refresh. +OVS_WAIT_UNTIL([test `ovs-vsctl get interface p1 statistics:rx_packets` -eq 1]) +CHECK_COVERAGE([netdev_received], [1]) +CHECK_COVERAGE([dp_packet_gso], [1]) +CHECK_COVERAGE([netdev_send_multi], [0]) +CHECK_COVERAGE([netdev_sent], [1]) +AT_CHECK([ovs-vsctl get interface p3 statistics:tx_packets], [0], [2 +]) + +OVS_CHECK_BATCH_GROW([0]) +AT_CHECK([ovs-appctl netdev-dummy/receive p1 "${flow_s}" --len 35000]) + +OVS_WAIT_UNTIL([test `ovs-vsctl get interface p1 statistics:rx_packets` -eq 2]) +CHECK_COVERAGE([netdev_received], [2]) +OVS_CHECK_BATCH_GROW([1]) +CHECK_COVERAGE([dp_packet_gso], [2]) +CHECK_COVERAGE([dpif_netdev_output_big_batch], [1]) +CHECK_COVERAGE([netdev_send_multi], [0]) +CHECK_COVERAGE([netdev_sent], [3]) +AT_CHECK([ovs-vsctl get interface p3 statistics:tx_packets], [0], [37 +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP + AT_SETUP([dpif-netdev - revalidators handle dp modification fail correctly]) OVS_VSWITCHD_START( [add-port br0 p1 \ -- 2.53.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
