ovs-vlan-test was designed to check for VLAN bugs in old Linux kernels. These kernel issues have long been fixed and the tool is no longer relevant.
Suggested-by: Ilya Maximets <[email protected]> Signed-off-by: Timothy Redaelli <[email protected]> --- Documentation/automake.mk | 5 +- Documentation/conf.py | 2 - .../contributing/documentation-style.rst | 2 +- Documentation/ref/index.rst | 5 - Documentation/ref/ovs-vlan-test.8.rst | 106 ----- NEWS | 2 + debian/openvswitch-switch.install | 2 - rhel/openvswitch-fedora.spec.in | 2 - rhel/openvswitch.spec.in | 2 - utilities/.gitignore | 2 - utilities/automake.mk | 5 +- utilities/ovs-vlan-test.in | 435 ------------------ 12 files changed, 6 insertions(+), 564 deletions(-) delete mode 100644 Documentation/ref/ovs-vlan-test.8.rst delete mode 100755 utilities/ovs-vlan-test.in diff --git a/Documentation/automake.mk b/Documentation/automake.mk index 8cc5058cb..279159ad3 100644 --- a/Documentation/automake.mk +++ b/Documentation/automake.mk @@ -166,7 +166,6 @@ RST_MANPAGES = \ ovs-pki.8.rst \ ovs-tcpdump.8.rst \ ovs-tcpundump.1.rst \ - ovs-vlan-test.8.rst \ ovsdb-server.7.rst \ ovsdb.5.rst \ ovsdb.7.rst @@ -204,8 +203,8 @@ set_mandirs = \ man8dir='$(man8dir)' \ man9dir='$(man9dir)' -# Given an $rst of "ovs-vlan-test.8.rst", sets $stem to -# "ovs-vlan-test", $section to "8", and $mandir to $man8dir. +# Given an $rst of "ovs-tcpdump.8.rst", sets $stem to +# "ovs-tcpdump", $section to "8", and $mandir to $man8dir. extract_stem_and_section = \ stem=`echo "$$rst" | sed -n 's/^\(.*\)\.\([0-9]\).rst$$/\1/p'`; \ section=`echo "$$rst" | sed -n 's/^\(.*\)\.\([0-9]\).rst$$/\2/p'`; \ diff --git a/Documentation/conf.py b/Documentation/conf.py index dc62c3fd4..ddcf98a4c 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -140,8 +140,6 @@ _man_pages = [ u'Dump traffic from an Open vSwitch port using tcpdump'), ('ovs-tcpundump.1', u'convert "tcpdump -xx" output to hex strings'), - ('ovs-vlan-test.8', - u'Check Linux drivers for problems with vlan traffic'), ('ovsdb-server.7', u'Open vSwitch Database Server Protocol'), ('ovsdb.5', diff --git a/Documentation/internals/contributing/documentation-style.rst b/Documentation/internals/contributing/documentation-style.rst index 2eec4c4d2..ebffa5af3 100644 --- a/Documentation/internals/contributing/documentation-style.rst +++ b/Documentation/internals/contributing/documentation-style.rst @@ -347,7 +347,7 @@ In addition to the above, man pages have some specific requirements: - The man page must be included in the list of man page documents found in `conf.py`__ -Refer to existing man pages, such as :doc:`/ref/ovs-vlan-test.8` for a worked +Refer to existing man pages, such as :doc:`/ref/ovs-tcpdump.8` for a worked example. __ http://www.sphinx-doc.org/en/stable/domains.html#directive-program diff --git a/Documentation/ref/index.rst b/Documentation/ref/index.rst index 9d931018a..342c6a376 100644 --- a/Documentation/ref/index.rst +++ b/Documentation/ref/index.rst @@ -47,7 +47,6 @@ time: ovs-sim.1 ovs-tcpdump.8 ovs-tcpundump.1 - ovs-vlan-test.8 ovsdb-server.7 ovsdb.5 ovsdb.7 @@ -96,10 +95,6 @@ The remainder are still in roff format can be found below: - `(pdf) <http://www.openvswitch.org/support/dist-docs/ovs-testcontroller.8.pdf>`__ - `(html) <http://www.openvswitch.org/support/dist-docs/ovs-testcontroller.8.html>`__ - `(plain text) <http://www.openvswitch.org/support/dist-docs/ovs-testcontroller.8.txt>`__ - * - ovs-vlan-test(8) - - `(pdf) <http://www.openvswitch.org/support/dist-docs/ovs-vlan-test.8.pdf>`__ - - `(html) <http://www.openvswitch.org/support/dist-docs/ovs-vlan-test.8.html>`__ - - `(plain text) <http://www.openvswitch.org/support/dist-docs/ovs-vlan-test.8.txt>`__ * - ovs-vsctl(8) - `(pdf) <http://www.openvswitch.org/support/dist-docs/ovs-vsctl.8.pdf>`__ - `(html) <http://www.openvswitch.org/support/dist-docs/ovs-vsctl.8.html>`__ diff --git a/Documentation/ref/ovs-vlan-test.8.rst b/Documentation/ref/ovs-vlan-test.8.rst deleted file mode 100644 index bd945c016..000000000 --- a/Documentation/ref/ovs-vlan-test.8.rst +++ /dev/null @@ -1,106 +0,0 @@ -============= -ovs-vlan-test -============= - -Synopsis -======== - -**ovs-vlan-test** [**-s** | **--server**] *control_ip* *vlan_ip* - -Description -=========== - -The :program:`ovs-vlan-test` program may be used to check for problems sending -802.1Q traffic which may occur when running Open vSwitch. These problems can -occur when Open vSwitch is used to send 802.1Q traffic through physical -interfaces running certain drivers of certain Linux kernel versions. To run a -test, configure Open vSwitch to tag traffic originating from `vlan_ip` and -forward it out the target interface. Then run the :program:`ovs-vlan-test` in -client mode connecting to an :program:`ovs-vlan-test` server. -:program:`ovs-vlan-test` will display "OK" if it did not detect problems. - -Some examples of the types of problems that may be encountered are: - -- When NICs use VLAN stripping on receive they must pass a pointer to a - `vlan_group` when reporting the stripped tag to the networking core. If no - `vlan_group` is in use then some drivers just drop the extracted tag. - Drivers are supposed to only enable stripping if a `vlan_group` is registered - but not all of them do that. - -- On receive, some drivers handle priority tagged packets specially and don't - pass the tag onto the network stack at all, so Open vSwitch never has a - chance to see it. - -- Some drivers size their receive buffers based on whether a `vlan_group` is - enabled, meaning that a maximum size packet with a VLAN tag will not fit if - no `vlan_group` is configured. - -- On transmit, some drivers expect that VLAN acceleration will be used if it is - available, which can only be done if a `vlan_group` is configured. In these - cases, the driver may fail to parse the packet and correctly setup checksum - offloading or TSO. - -Client Mode - An :program:`ovs-vlan-test` client may be run on a host to check for VLAN - connectivity problems. The client must be able to establish HTTP connections - with an :program:`ovs-vlan-test` server located at the specified `control_ip` - address. UDP traffic sourced at `vlan_ip` should be tagged and directed out - the interface whose connectivity is being tested. - -Server Mode - To conduct tests, an :program:`ovs-vlan-test` server must be running on a - host known not to have VLAN connectivity problems. The server must have a - `control_ip` on a non-VLAN network which clients can establish connectivity - with. It must also have a `vlan_ip` address on a VLAN network which clients - will use to test their VLAN connectivity. Multiple clients may test against a - single :program:`ovs-vlan-test` server concurrently. - -Options -======= - -.. program:: ovs-vlan-test - -.. option:: -s, --server - - Run in server mode. - -.. option:: -h, --help - - Prints a brief help message to the console. - -.. option:: -V, --version - - Prints version information to the console. - -Examples -======== - -Display the Linux kernel version and driver of `eth1`:: - - uname -r - ethtool -i eth1 - -Set up a bridge which forwards traffic originating from `1.2.3.4` out `eth1` -with VLAN tag 10:: - - ovs-vsctl -- add-br vlan-br \ - -- add-port vlan-br eth1 \ - -- add-port vlan-br vlan-br-tag tag=10 \ - -- set Interface vlan-br-tag type=internal - ip addr add 1.2.3.4/8 dev vlan-br-tag - ip link set vlan-br-tag up - -Run an :program:`ovs-vlan-test` server listening for client control traffic on -`172.16.0.142` port `8080` and VLAN traffic on the default port of `1.2.3.3`:: - - ovs-vlan-test -s 172.16.0.142:8080 1.2.3.3 - -Run an :program:`ovs-vlan-test` client with a control server located at -`172.16.0.142` port `8080` and a local VLAN IP of `1.2.3.4`:: - - ovs-vlan-test 172.16.0.142:8080 1.2.3.4 - -See Also -======== - -`ovs-vswitchd(8)`, `ovs-ofctl(8)`, `ovs-vsctl(8)`, `ethtool(8)`, `uname(1)` diff --git a/NEWS b/NEWS index 82042163c..a41870374 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ Post-v3.7.0 preferred for performance testing. - Removed ovstest Python module. It was only used by the now removed ovs-test and ovs-l3ping utilities. + - Removed ovs-vlan-test. It was designed to check for VLAN bugs in + old Linux kernels that have long been fixed. - Userspace datapath: * ARP/ND lookups for native tunnel are now rate limited. The holdout timer can be configured with 'tnl/neigh/retrans_time'. diff --git a/debian/openvswitch-switch.install b/debian/openvswitch-switch.install index 9d74dfda5..d1c52964d 100755 --- a/debian/openvswitch-switch.install +++ b/debian/openvswitch-switch.install @@ -9,7 +9,6 @@ usr/bin/ovs-dpctl-top usr/bin/ovs-pcap usr/bin/ovs-tcpdump usr/bin/ovs-tcpundump -usr/bin/ovs-vlan-test usr/bin/ovs-vsctl usr/sbin/ovs-vswitchd usr/lib/openvswitch-switch/ usr/share/man/man1/ovs-pcap.1 @@ -20,7 +19,6 @@ usr/share/man/man8/ovs-dpctl-top.8 usr/share/man/man8/ovs-dpctl.8 usr/share/man/man8/ovs-kmod-ctl.8 usr/share/man/man8/ovs-tcpdump.8 -usr/share/man/man8/ovs-vlan-test.8 usr/share/man/man8/ovs-vsctl.8 usr/share/man/man8/ovs-vswitchd.8 usr/share/openvswitch/scripts/ovs-check-dead-ifs diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in index 72bd676e8..810d8d600 100644 --- a/rhel/openvswitch-fedora.spec.in +++ b/rhel/openvswitch-fedora.spec.in @@ -418,12 +418,10 @@ fi %{python3_sitelib}/ovs %files test -%{_bindir}/ovs-vlan-test %{_bindir}/ovs-pcap %{_bindir}/ovs-tcpdump %{_bindir}/ovs-tcpundump %{_datadir}/openvswitch/scripts/usdt/* -%{_mandir}/man8/ovs-vlan-test.8* %{_mandir}/man1/ovs-pcap.1* %{_mandir}/man8/ovs-tcpdump.8* %{_mandir}/man1/ovs-tcpundump.1* diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in index f119b7ae4..db2f68ded 100644 --- a/rhel/openvswitch.spec.in +++ b/rhel/openvswitch.spec.in @@ -190,7 +190,6 @@ exit 0 /usr/bin/ovs-pki /usr/bin/ovs-tcpdump /usr/bin/ovs-tcpundump -/usr/bin/ovs-vlan-test /usr/bin/ovs-vsctl /usr/bin/ovsdb-client /usr/bin/ovsdb-tool @@ -223,7 +222,6 @@ exit 0 /usr/share/man/man8/ovs-ofctl.8.gz /usr/share/man/man8/ovs-pki.8.gz /usr/share/man/man8/ovs-tcpdump.8.gz -/usr/share/man/man8/ovs-vlan-test.8.gz /usr/share/man/man8/ovs-vsctl.8.gz /usr/share/man/man8/ovs-vswitchd.8.gz /usr/share/man/man8/vtep-ctl.8.gz diff --git a/utilities/.gitignore b/utilities/.gitignore index 3f140a744..7e58da6bd 100644 --- a/utilities/.gitignore +++ b/utilities/.gitignore @@ -26,8 +26,6 @@ /ovs-tcpdump.8 /ovs-tcpundump /ovs-tcpundump.1 -/ovs-vlan-test -/ovs-vlan-test.8 /ovs-vsctl /ovs-vsctl.8 /ovs-sim diff --git a/utilities/automake.mk b/utilities/automake.mk index e83c283b8..59acafe01 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -9,8 +9,7 @@ bin_SCRIPTS += utilities/ovs-docker \ utilities/ovs-pcap \ utilities/ovs-tcpdump \ utilities/ovs-tcpundump \ - utilities/ovs-dpctl-top \ - utilities/ovs-vlan-test + utilities/ovs-dpctl-top scripts_SCRIPTS += \ utilities/ovs-check-dead-ifs \ utilities/ovs-ctl \ @@ -57,7 +56,6 @@ EXTRA_DIST += \ utilities/ovs-save \ utilities/ovs-tcpdump.in \ utilities/ovs-tcpundump.in \ - utilities/ovs-vlan-test.in \ utilities/ovs-vsctl-bashcomp.bash \ utilities/checkpatch.py \ utilities/checkpatch_dict.txt \ @@ -101,7 +99,6 @@ CLEANFILES += \ utilities/ovs-sim \ utilities/ovs-tcpdump \ utilities/ovs-tcpundump \ - utilities/ovs-vlan-test \ utilities/ovs-vsctl.8 man_MANS += \ diff --git a/utilities/ovs-vlan-test.in b/utilities/ovs-vlan-test.in deleted file mode 100755 index 3c15e2b13..000000000 --- a/utilities/ovs-vlan-test.in +++ /dev/null @@ -1,435 +0,0 @@ -#! @PYTHON3@ -# -# Copyright (c) 2010 Nicira, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import getopt -import http.client -import http.server -import os -import threading -import time -import signal #Causes keyboard interrupts to go to the main thread. -import socket -import sys - -print_safe_lock = threading.Lock() -def print_safe(s): - print_safe_lock.acquire() - print(s) - print_safe_lock.release() - -def start_thread(target, args): - t = threading.Thread(target=target, args=args) - t.setDaemon(True) - t.start() - return t - -#Caller is responsible for catching socket.error exceptions. -def send_packet(key, length, dest_ip, dest_port): - - length -= 20 + 8 #IP and UDP headers. - - packet = str(key) - packet += chr(0) * (length - len(packet)) - - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.sendto(packet, (dest_ip, dest_port)) - sock.close() - -#UDP Receiver -class UDPReceiver: - def __init__(self, vlan_ip, vlan_port): - self.vlan_ip = vlan_ip - self.vlan_port = vlan_port - self.recv_callbacks = {} - self.udp_run = False - - def recv_packet(self, key, success_callback, timeout_callback): - - event = threading.Event() - - def timeout_cb(): - timeout_callback() - event.set() - - timer = threading.Timer(30, timeout_cb) - timer.daemon = True - - def success_cb(): - timer.cancel() - success_callback() - event.set() - - # Start the timer first to avoid a timer.cancel() race condition. - timer.start() - self.recv_callbacks[key] = success_cb - return event - - def udp_receiver(self): - - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.settimeout(1) - - try: - sock.bind((self.vlan_ip, self.vlan_port)) - except socket.error as e: - print_safe('Failed to bind to %s:%d with error: %s' - % (self.vlan_ip, self.vlan_port, e)) - os._exit(1) #sys.exit only exits the current thread. - - while self.udp_run: - - try: - data, _ = sock.recvfrom(4096) - except socket.timeout: - continue - except socket.error as e: - print_safe('Failed to receive from %s:%d with error: %s' - % (self.vlan_ip, self.vlan_port, e)) - os._exit(1) - - data_str = data.split(chr(0))[0] - - if not data_str.isdigit(): - continue - - key = int(data_str) - - if key in self.recv_callbacks: - self.recv_callbacks[key]() - del self.recv_callbacks[key] - - def start(self): - self.udp_run = True - start_thread(self.udp_receiver, ()) - - def stop(self): - self.udp_run = False - -#Server -vlan_server = None -class VlanServer: - - def __init__(self, server_ip, server_port, vlan_ip, vlan_port): - global vlan_server - - vlan_server = self - - self.server_ip = server_ip - self.server_port = server_port - - self.recv_response = '%s:%d:' % (vlan_ip, vlan_port) - - self.result = {} - self.result_lock = threading.Lock() - - self._test_id = 0 - self._test_id_lock = threading.Lock() - - self.udp_recv = UDPReceiver(vlan_ip, vlan_port) - - def get_test_id(self): - self._test_id_lock.acquire() - - self._test_id += 1 - ret = self._test_id - - self._test_id_lock.release() - return ret - - def set_result(self, key, value): - - self.result_lock.acquire() - - if key not in self.result: - self.result[key] = value - - self.result_lock.release() - - def recv(self, test_id): - self.udp_recv.recv_packet(test_id, - lambda : self.set_result(test_id, 'Success'), - lambda : self.set_result(test_id, 'Timeout')) - - return self.recv_response + str(test_id) - - def send(self, test_id, data): - try: - ip, port, size = data.split(':') - port = int(port) - size = int(size) - except ValueError: - self.set_result(test_id, - 'Server failed to parse send request: %s' % data) - return - - def send_thread(): - send_time = 10 - for _ in range(send_time * 2): - try: - send_packet(test_id, size, ip, port) - except socket.error as e: - self.set_result(test_id, 'Failure: ' + str(e)) - return - time.sleep(.5) - - self.set_result(test_id, 'Success') - - start_thread(send_thread, ()) - - return str(test_id) - - def run(self): - self.udp_recv.start() - try: - http.server.HTTPServer((self.server_ip, self.server_port), - VlanServerHandler).serve_forever() - except socket.error as e: - print_safe('Failed to start control server: %s' % e) - self.udp_recv.stop() - - return 1 - -class VlanServerHandler(http.server.BaseHTTPRequestHandler): - def do_GET(self): - - #Guarantee three arguments. - path = (self.path.lower().lstrip('/') + '//').split('/') - - resp = 404 - body = None - - if path[0] == 'start': - test_id = vlan_server.get_test_id() - - if path[1] == 'recv': - resp = 200 - body = vlan_server.recv(test_id) - elif path[1] == 'send': - resp = 200 - body = vlan_server.send(test_id, path[2]) - elif (path[0] == 'result' - and path[1].isdigit() - and int(path[1]) in vlan_server.result): - resp = 200 - body = vlan_server.result[int(path[1])] - elif path[0] == 'ping': - resp = 200 - body = 'pong' - - self.send_response(resp) - self.end_headers() - - if body: - self.wfile.write(body) - -#Client -class VlanClient: - - def __init__(self, server_ip, server_port, vlan_ip, vlan_port): - self.server_ip_port = '%s:%d' % (server_ip, server_port) - self.vlan_ip_port = "%s:%d" % (vlan_ip, vlan_port) - self.udp_recv = UDPReceiver(vlan_ip, vlan_port) - - def request(self, resource): - conn = http.client.HTTPConnection(self.server_ip_port) - conn.request('GET', resource) - return conn - - def send(self, size): - - def error_msg(e): - print_safe('Send size %d unsuccessful: %s' % (size, e)) - - try: - conn = self.request('/start/recv') - data = conn.getresponse().read() - except (socket.error, http.client.HTTPException) as e: - error_msg(e) - return False - - try: - ip, port, test_id = data.split(':') - port = int(port) - test_id = int(test_id) - except ValueError: - error_msg("Received invalid response from control server (%s)" % - data) - return False - - send_time = 5 - - for _ in range(send_time * 4): - - try: - send_packet(test_id, size, ip, port) - resp = self.request('/result/%d' % test_id).getresponse() - data = resp.read() - except (socket.error, http.client.HTTPException) as e: - error_msg(e) - return False - - if resp.status == 200 and data == 'Success': - print_safe('Send size %d successful' % size) - return True - elif resp.status == 200: - error_msg(data) - return False - - time.sleep(.25) - - error_msg('Timeout') - return False - - def recv(self, size): - - def error_msg(e): - print_safe('Receive size %d unsuccessful: %s' % (size, e)) - - resource = '/start/send/%s:%d' % (self.vlan_ip_port, size) - try: - conn = self.request(resource) - test_id = conn.getresponse().read() - except (socket.error, http.client.HTTPException) as e: - error_msg(e) - return False - - if not test_id.isdigit(): - error_msg('Invalid response %s' % test_id) - return False - - success = [False] #Primitive datatypes can't be set from closures. - - def success_cb(): - success[0] = True - - def failure_cb(): - success[0] = False - - self.udp_recv.recv_packet(int(test_id), success_cb, failure_cb).wait() - - if success[0]: - print_safe('Receive size %d successful' % size) - else: - error_msg('Timeout') - - return success[0] - - def server_up(self): - - def error_msg(e): - print_safe('Failed control server connectivity test: %s' % e) - - try: - resp = self.request('/ping').getresponse() - data = resp.read() - except (socket.error, http.client.HTTPException) as e: - error_msg(e) - return False - - if resp.status != 200: - error_msg('Invalid status %d' % resp.status) - elif data != 'pong': - error_msg('Invalid response %s' % data) - - return True - - def run(self): - - if not self.server_up(): - return 1 - - self.udp_recv.start() - - success = True - for size in [50, 500, 1000, 1500]: - success = self.send(size) and success - success = self.recv(size) and success - - self.udp_recv.stop() - - if success: - print_safe('OK') - return 0 - else: - print_safe('FAILED') - return 1 - -def usage(): - print_safe("""\ -%(argv0)s: Test vlan connectivity -usage: %(argv0)s server vlan - -The following options are also available: - -s, --server run in server mode - -h, --help display this help message - -V, --version display version information\ -""" % {'argv0': sys.argv[0]}) - -def main(): - - try: - options, args = getopt.gnu_getopt(sys.argv[1:], 'hVs', - ['help', 'version', 'server']) - except getopt.GetoptError as geo: - print_safe('%s: %s\n' % (sys.argv[0], geo.msg)) - return 1 - - server = False - for key, _ in options: - if key in ['-h', '--help']: - usage() - return 0 - elif key in ['-V', '--version']: - print_safe('ovs-vlan-test (Open vSwitch) @VERSION@@VERSION_SUFFIX@') - return 0 - elif key in ['-s', '--server']: - server = True - else: - print_safe('Unexpected option %s. (use --help for help)' % key) - return 1 - - if len(args) != 2: - print_safe('Expecting two arguments. (use --help for help)') - return 1 - - try: - server_ip, server_port = args[0].split(':') - server_port = int(server_port) - except ValueError: - server_ip = args[0] - server_port = 80 - - try: - vlan_ip, vlan_port = args[1].split(':') - vlan_port = int(vlan_port) - except ValueError: - vlan_ip = args[1] - vlan_port = 15213 - - if server: - return VlanServer(server_ip, server_port, vlan_ip, vlan_port).run() - else: - return VlanClient(server_ip, server_port, vlan_ip, vlan_port).run() - -if __name__ == '__main__': - main_ret = main() - - # Python can throw exceptions if threads are running at exit. - for th in threading.enumerate(): - if th != threading.currentThread(): - th.join() - - sys.exit(main_ret) -- 2.54.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
