Mike Pattrick <m...@redhat.com> writes: > Currently the ovs-tcpdump utility creates a virtual tunnel to send > packets to. This method functions perfectly fine, however, it can > greatly impact performance of the monitored port. > > It has been reported to reduce packet throughput significantly. I was > able to reproduce a reduction in throughput of up 70 percent in some > tests with a simple setup of two hosts communicating through a single > bridge on Linux with the kernel module datapath. Another more complex > test was configured for DPDK and the usermode datapath. This test > involved a data path going from a VM, through a port into one OVS > bridge, out through a network card which could be DPDK enabled for the > relevant tests, in to a different network interface, then into a > different OVS bridge, through another port, and then into a virtual > machine. > > Using the dummy driver resulted in the following impact to performance > compared to no ovs-tcpdump. Due to intra-test variance and fluctuations > during the first few seconds after installing a tap; multiple samples > were taken over multiple test runs. The first few seconds worth of > results were discarded and then results were averaged out. > > Original Script > =============== > Category Impact on Throughput > Kernel datapath - 65% > Usermode datapath - 26% > DPDK datapath - 37% > > New Script > ========== > Category Impact on Throughput > Kernel datapath - 5% > Usermode datapath - 16% > DPDK datapath - 29% > > Signed-off-by: Mike Pattrick <m...@redhat.com> > ---
Looks good to me. Thanks for preserving the port teardown as well. Acked-by: Aaron Conole <acon...@redhat.com> > utilities/ovs-tcpdump.in | 42 +++++++++++++++++++++------------------- > 1 file changed, 22 insertions(+), 20 deletions(-) > > diff --git a/utilities/ovs-tcpdump.in b/utilities/ovs-tcpdump.in > index 5ec02383c..10989dfc1 100755 > --- a/utilities/ovs-tcpdump.in > +++ b/utilities/ovs-tcpdump.in > @@ -14,12 +14,9 @@ > # See the License for the specific language governing permissions and > # limitations under the License. > > -import fcntl > - > import os > import pwd > from random import randint > -import struct > import subprocess > import sys > import time > @@ -52,8 +49,8 @@ except Exception: > print(" the correct location.") > sys.exit(1) > > -tapdev_fd = None > _make_taps = {} > +_del_taps = {} > _make_mirror_name = {} > IFNAMSIZ_LINUX = 15 # this is the max name size, excluding the null > byte. > > @@ -67,21 +64,11 @@ def _doexec(*args, **kwargs): > return proc > > > -def _install_tap_linux(tap_name, mtu_value=None): > - """Uses /dev/net/tun to create a tap device""" > - global tapdev_fd > - > - IFF_TAP = 0x0002 > - IFF_NO_PI = 0x1000 > - TUNSETIFF = 0x400454CA # This is derived by printf() of TUNSETIFF > - TUNSETOWNER = TUNSETIFF + 2 > - > - tapdev_fd = os.open('/dev/net/tun', os.O_RDWR) > - ifr = struct.pack('16sH', tap_name.encode('utf8'), IFF_TAP | IFF_NO_PI) > - fcntl.ioctl(tapdev_fd, TUNSETIFF, ifr) > - fcntl.ioctl(tapdev_fd, TUNSETOWNER, os.getegid()) > +def _install_dst_if_linux(tap_name, mtu_value=None): > + _doexec( > + *['ip', 'link', 'add', str(tap_name), 'type', 'dummy'] > + ).wait() > > - time.sleep(1) # required to give the new device settling time > if mtu_value is not None: > pipe = _doexec( > *(['ip', 'link', 'set', 'dev', str(tap_name), 'mtu', > @@ -93,14 +80,22 @@ def _install_tap_linux(tap_name, mtu_value=None): > pipe.wait() > > > +def _remove_dst_if_linux(tap_name): > + _doexec( > + *['ip', 'link', 'del', str(tap_name)] > + ).wait() > + > + > def _make_linux_mirror_name(interface_name): > if len(interface_name) > IFNAMSIZ_LINUX - 2: > return "ovsmi%06d" % randint(1, 999999) > return "mi%s" % interface_name > > > -_make_taps['linux'] = _install_tap_linux > -_make_taps['linux2'] = _install_tap_linux > +_make_taps['linux'] = _install_dst_if_linux > +_make_taps['linux2'] = _install_dst_if_linux > +_del_taps['linux'] = _remove_dst_if_linux > +_del_taps['linux2'] = _remove_dst_if_linux > _make_mirror_name['linux'] = _make_linux_mirror_name > _make_mirror_name['linux2'] = _make_linux_mirror_name > > @@ -455,6 +450,9 @@ def main(): > mirror_interface not in interfaces(): > _make_taps[sys.platform](mirror_interface, > ovsdb.interface_mtu(interface)) > + tap_created = True > + else: > + tap_created = False > > if mirror_interface not in interfaces(): > print("ERROR: Please create an interface called `%s`" % > @@ -480,6 +478,8 @@ def main(): > print("ERROR: Unable to properly setup the mirror: %s." % str(oe)) > try: > ovsdb.destroy_port(mirror_interface, > ovsdb.port_bridge(interface)) > + if tap_created is True: > + _del_taps[sys.platform](mirror_interface) > except Exception: > pass > sys.exit(1) > @@ -498,6 +498,8 @@ def main(): > > ovsdb.destroy_mirror(interface, ovsdb.port_bridge(interface)) > ovsdb.destroy_port(mirror_interface, ovsdb.port_bridge(interface)) > + if tap_created is True: > + _del_taps[sys.platform](mirror_interface) > except Exception: > print("Unable to tear down the ports and mirrors.") > print("Please use ovs-vsctl to remove the ports and mirrors > created.") _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev