[ovs-dev] [PATCH] ovs-l3ping: A new test utility that allows to detect L3 tunneling issues
Reid Price
reid at nicira.com
Fri Jun 29 00:06:05 UTC 2012
Looks good from a quick read-through, skimmed the documentation
additions, a few minor comments inline.
-Reid
On Thu, Jun 28, 2012 at 4:02 PM, Ansis Atteka <aatteka at nicira.com> wrote:
> ovs-l3ping is similar to ovs-test, but the main difference
> is that it does not require administrator to open firewall
> holes for the XML/RPC control connection. This is achieved
> by encapsulating the Control Connection over the L3 tunnel
> itself.
>
> This tool is not intended as a replacement for ovs-test,
> because ovs-test covers much broader set of test cases.
>
> Sample usage:
> Node1: ovs-l3ping -s 192.168.122.236,10.1.1.1 -t gre
> Node2: ovs-l3ping -c 192.168.122.220,10.1.1.2,10.1.1.1 -t gre
>
> Issue#11791
> Signed-off-by: Ansis Atteka <aatteka at nicira.com>
> ---
> NEWS | 5 +
> debian/openvswitch-test.install | 1 +
> debian/openvswitch-test.manpages | 1 +
> manpages.mk | 8 ++
> python/automake.mk | 1 +
> python/ovstest/args.py | 74 ++++++++++
> python/ovstest/rpcserver.py | 6 +
> python/ovstest/tests.py | 230 +++++++++++++++++++++++++++++
> python/ovstest/util.py | 82 +++++++++++
> rhel/openvswitch.spec.in | 2 +
> utilities/.gitignore | 2 +
> utilities/automake.mk | 6 +
> utilities/ovs-l3ping.8.in | 108 ++++++++++++++
> utilities/ovs-l3ping.in | 76 ++++++++++
> utilities/ovs-test.in | 286
> ++-----------------------------------
> xenserver/openvswitch-xen.spec.in | 6 +-
> 16 files changed, 617 insertions(+), 277 deletions(-)
> create mode 100644 python/ovstest/tests.py
> create mode 100644 utilities/ovs-l3ping.8.in
> create mode 100644 utilities/ovs-l3ping.in
>
> diff --git a/NEWS b/NEWS
> index f0b2490..d71daf7 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -1,6 +1,11 @@
> post-v1.7.0
> ------------------------
> - New FAQ. Please send updates and additions!
> + - ovs-l3ping:
> + - A new test utility that can create L3 tunnel between two Open
> + vSwitches and detect connectivity issues. This utility does
> + not require administrator to open firewall hole for the XML/RPC
> + control channel.
> - ovs-ofctl:
> - "mod-port" command can now control all OpenFlow config flags.
> - OpenFlow:
> diff --git a/debian/openvswitch-test.install
> b/debian/openvswitch-test.install
> index a36c828..2b0f8de 100644
> --- a/debian/openvswitch-test.install
> +++ b/debian/openvswitch-test.install
> @@ -1,2 +1,3 @@
> usr/share/openvswitch/python/ovstest usr/lib/python2.6/dist-packages/
> usr/bin/ovs-test
> +usr/bin/ovs-l3ping
> \ No newline at end of file
> diff --git a/debian/openvswitch-test.manpages
> b/debian/openvswitch-test.manpages
> index 683c978..1a7f6d4 100644
> --- a/debian/openvswitch-test.manpages
> +++ b/debian/openvswitch-test.manpages
> @@ -1 +1,2 @@
> _debian/utilities/ovs-test.8
> +_debian/utilities/ovs-l3ping.8
> diff --git a/manpages.mk b/manpages.mk
> index 1773263..f391fdf 100644
> --- a/manpages.mk
> +++ b/manpages.mk
> @@ -120,6 +120,14 @@ utilities/ovs-dpctl.8.in:
> lib/common.man:
> lib/vlog.man:
>
> +utilities/ovs-l3ping.8: \
> + utilities/ovs-l3ping.8.in \
> + lib/common-syn.man \
> + lib/common.man
> +utilities/ovs-l3ping.8.in:
> +lib/common-syn.man:
> +lib/common.man:
> +
> utilities/ovs-ofctl.8: \
> utilities/ovs-ofctl.8.in \
> lib/common.man \
> diff --git a/python/automake.mk b/python/automake.mk
> index 96869e3..b656f08 100644
> --- a/python/automake.mk
> +++ b/python/automake.mk
> @@ -3,6 +3,7 @@ ovstest_pyfiles = \
> python/ovstest/args.py \
> python/ovstest/rpcserver.py \
> python/ovstest/tcp.py \
> + python/ovstest/tests.py \
> python/ovstest/udp.py \
> python/ovstest/util.py \
> python/ovstest/vswitch.py
> diff --git a/python/ovstest/args.py b/python/ovstest/args.py
> index 8e23a89..1dd97c1 100644
> --- a/python/ovstest/args.py
> +++ b/python/ovstest/args.py
> @@ -78,6 +78,23 @@ def ip_optional_port(string, default_port, ip_callback):
> "must be colon-separated")
>
>
> +def ip_optional_port_port(string, default_port1, default_port2,
> ip_callback):
> + """Convert a string into IP, Port1, Port2 tuple. If any of ports were
> + missing, then default ports will be used. The fourth argument is a
> + callback that verifies whether IP address is given in the expected
> + format."""
> + value = string.split(':')
> + if len(value) == 1:
> + return (ip_callback(value[0]), default_port1, default_port2)
> + elif len(value) == 2:
> + return (ip_callback(value[0]), port(value[1]), default_port2)
> + elif len(value) == 3:
> + return (ip_callback(value[0]), port(value[1]), port(value[2]))
> + else:
> + raise argparse.ArgumentTypeError("IP address from optional ports "
> + "must be colon-separated")
> +
> +
> def vlan_tag(string):
> """
> This function verifies whether given string is a correct VLAN tag.
> @@ -154,6 +171,29 @@ def tunnel_types(string):
> return string.split(',')
>
>
> +def l3_endpoint_client(string):
> + """
> + This function parses command line argument string in
> + remoteIP,localInnerIP[/mask][:ControlPort[:TestPort]],remoteInnerIP[:
> + ControlPort[:TestPort]] format.
> + """
> + remote_ip, me, he = string.split(',')
> + r = (ip_address(remote_ip),
> + ip_optional_port_port(me, CONTROL_PORT, DATA_PORT,
> ip_optional_mask),
> + ip_optional_port_port(he, CONTROL_PORT, DATA_PORT, ip_address))
> + return r
> +
> +
> +def l3_endpoint_server(string):
> + """
> + This function parses a command line argument string in
> + remoteIP,localInnerIP[/mask][:ControlPort] format.
> + """
> + remote_ip, me = string.split(',')
> + return (ip_address(remote_ip),
> + ip_optional_port(me, CONTROL_PORT, ip_optional_mask))
> +
> +
> def ovs_initialize_args():
> """
> Initialize argument parsing for ovs-test utility.
> @@ -197,3 +237,37 @@ def ovs_initialize_args():
> 'ovs-test server in the client mode by using 127.0.0.1 as '
> 'OuterIP.')
> return parser.parse_args()
> +
> +def l3_initialize_args():
> + """
> + Initialize argument parsing for ovs-l3ping utility.
> + """
> + parser = argparse.ArgumentParser(description='Test L3 tunnel '
> + 'connectivity between two Open vSwitch
> instances.')
> +
> + parser.add_argument('-v', '--version', action='version',
> + version='ovs-l3ping (Open vSwitch) @VERSION@')
> +
> + parser.add_argument("-b", "--bandwidth", action='store',
> + dest="targetBandwidth", default="1M", type=bandwidth,
> + help='Target bandwidth for UDP tests in bits/second. Use '
> + 'postfix M or K to alter unit magnitude.')
> + parser.add_argument("-i", "--interval", action='store',
> + dest="testInterval", default=5, type=int,
> + help='Interval for how long to run each test in seconds.')
> +
> + parser.add_argument("-t", "--tunnel-mode", action='store',
> + dest="tunnelMode", required=True,
> + help='Do L3 tests with this tunnel type.')
> +
> + group = parser.add_mutually_exclusive_group(required=True)
> + group.add_argument("-s", "--server", action="store", dest="server",
> + metavar="TUNNELIP,SERVER",
> + type=l3_endpoint_server,
> + help='Run in server mode and wait for the client to '
> + 'connect.')
> + group.add_argument('-c', "--client", action="store", dest="client",
> + metavar="TUNNELIP,CLIENT,SERVER",
> + type=l3_endpoint_client,
> + help='Run in client mode and connect to the server.')
> + return parser.parse_args()
> diff --git a/python/ovstest/rpcserver.py b/python/ovstest/rpcserver.py
> index 82bec3b..5c92014 100644
> --- a/python/ovstest/rpcserver.py
> +++ b/python/ovstest/rpcserver.py
> @@ -343,6 +343,12 @@ class TestArena(xmlrpc.XMLRPC):
> """
> return util.get_driver(iface)
>
> + def xmlrpc_get_interface_from_routing_decision(self, ip):
> + """
> + Returns driver version
> + """
> + return util.get_interface_from_routing_decision(ip)
> +
>
> def start_rpc_server(port):
> """
> diff --git a/python/ovstest/tests.py b/python/ovstest/tests.py
> new file mode 100644
> index 0000000..866c207
> --- /dev/null
> +++ b/python/ovstest/tests.py
> @@ -0,0 +1,230 @@
> +import math
> +import time
> +
> +import ovstest.util as util
> +
> +DEFAULT_TEST_BRIDGE = "ovstestbr0"
> +DEFAULT_TEST_PORT = "ovstestport0"
> +DEFAULT_TEST_TUN = "ovstestport1"
> +
> +
> +def do_udp_tests(receiver, sender, tbwidth, duration, port_sizes):
> + """Schedule UDP tests between receiver and sender"""
> + server1 = util.rpc_client(receiver[0], receiver[1])
> + server2 = util.rpc_client(sender[0], sender[1])
> +
> + udpformat = '{0:>15} {1:>15} {2:>15} {3:>15} {4:>15}'
> +
> + print ("UDP test from %s:%u to %s:%u with target bandwidth %s" %
> + (sender[0], sender[1], receiver[0],
> receiver[1],
> + util.bandwidth_to_string(tbwidth)))
> + print udpformat.format("Datagram Size", "Snt Datagrams", "Rcv
> Datagrams",
> + "Datagram Loss", "Bandwidth")
> +
> + for size in port_sizes:
>
> + listen_handle = -1
> + send_handle = -1
>
It seems like a constant for NO_HANDLE might be friendly throughout, fine
as-is.
> + try:
> + packetcnt = (tbwidth * duration) / size
> +
> + listen_handle = server1.create_udp_listener(receiver[3])
> + if listen_handle == -1:
> + print ("Server could not open UDP listening socket on
> port"
> + " %u. Try to restart the server.\n" % receiver[3])
> + return
> + send_handle = server2.create_udp_sender(
> +
> (util.ip_from_cidr(receiver[2]),
> + receiver[3]), packetcnt,
> size,
> + duration)
> +
> + # Using sleep here because there is no other synchronization
> + # source that would notify us when all sent packets were
> received
> + time.sleep(duration + 1)
> +
> + rcv_packets = server1.get_udp_listener_results(listen_handle)
> + snt_packets = server2.get_udp_sender_results(send_handle)
> +
> + loss = math.ceil(((snt_packets - rcv_packets) * 10000.0) /
> + snt_packets) / 100
> + bwidth = (rcv_packets * size) / duration
> +
> + print udpformat.format(size, snt_packets, rcv_packets,
> + '%.2f%%' % loss,
> util.bandwidth_to_string(bwidth))
> + finally:
> + if listen_handle != -1:
> + server1.close_udp_listener(listen_handle)
> + if send_handle != -1:
> + server2.close_udp_sender(send_handle)
> + print "\n"
> +
> +
> +def do_tcp_tests(receiver, sender, duration):
> + """Schedule TCP tests between receiver and sender"""
> + server1 = util.rpc_client(receiver[0], receiver[1])
> + server2 = util.rpc_client(sender[0], sender[1])
> +
> + tcpformat = '{0:>15} {1:>15} {2:>15}'
> + print "TCP test from %s:%u to %s:%u (full speed)" % (sender[0],
> sender[1],
> + receiver[0],
> receiver[1])
> + print tcpformat.format("Snt Bytes", "Rcv Bytes", "Bandwidth")
> +
> + listen_handle = -1
> + send_handle = -1
> + try:
> + listen_handle = server1.create_tcp_listener(receiver[3])
> + if listen_handle == -1:
> + print ("Server was unable to open TCP listening socket on
> port"
> + " %u. Try to restart the server.\n" % receiver[3])
> + return
> + send_handle =
> server2.create_tcp_sender(util.ip_from_cidr(receiver[2]),
> + receiver[3], duration)
> +
> + time.sleep(duration + 1)
> +
> + rcv_bytes = long(server1.get_tcp_listener_results(listen_handle))
> + snt_bytes = long(server2.get_tcp_sender_results(send_handle))
> +
> + bwidth = rcv_bytes / duration
> +
> + print tcpformat.format(snt_bytes, rcv_bytes,
> + util.bandwidth_to_string(bwidth))
> + finally:
> + if listen_handle != -1:
> + server1.close_tcp_listener(listen_handle)
> + if send_handle != -1:
> + server2.close_tcp_sender(send_handle)
> + print "\n"
> +
> +
> +def do_l3_tests(node1, node2, bandwidth, duration, ps, type):
> + """
> + Do L3 tunneling tests.
> + """
> + server1 = util.rpc_client(node1[0], node1[1])
> + server2 = util.rpc_client(node2[0], node2[1])
> + servers_with_bridges = []
> + try:
> + server1.create_bridge(DEFAULT_TEST_BRIDGE)
> + servers_with_bridges.append(server1)
> + server2.create_bridge(DEFAULT_TEST_BRIDGE)
> + servers_with_bridges.append(server2)
> +
> + server1.interface_up(DEFAULT_TEST_BRIDGE)
> + server2.interface_up(DEFAULT_TEST_BRIDGE)
> +
> + server1.interface_assign_ip(DEFAULT_TEST_BRIDGE, node1[2], None)
> + server2.interface_assign_ip(DEFAULT_TEST_BRIDGE, node2[2], None)
> +
> + server1.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_TUN)
> + server2.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_TUN)
> +
> + server1.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "type",
> + None, type)
> + server2.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "type",
> + None, type)
> + server1.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "options",
> + "remote_ip", node2[0])
> + server2.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "options",
> + "remote_ip", node1[0])
> +
> + do_udp_tests(node1, node2, bandwidth, duration, ps)
> + do_udp_tests(node2, node1, bandwidth, duration, ps)
> + do_tcp_tests(node1, node2, duration)
> + do_tcp_tests(node2, node1, duration)
> +
> + finally:
> + for server in servers_with_bridges:
> + server.del_bridge(DEFAULT_TEST_BRIDGE)
> +
> +
+
>
> +def do_vlan_tests(node1, node2, bandwidth, duration, ps, tag):
> + """
> + Do VLAN tests between node1 and node2.
+ """
>
Marking what node1 and node2 are might be useful in these functions, it's
not obvious what the indices are supposed to represent in passing.
+ server1 = util.rpc_client(node1[0], node1[1])
> + server2 = util.rpc_client(node2[0], node2[1])
> +
> + br_name1 = None
> + br_name2 = None
> +
> + servers_with_test_ports = []
> +
> + try:
> + interface_node1 = server1.get_interface(node1[0])
> + interface_node2 = server2.get_interface(node2[0])
> +
> + if server1.is_ovs_bridge(interface_node1):
> + br_name1 = interface_node1
> + else:
> + br_name1 = DEFAULT_TEST_BRIDGE
> + server1.create_test_bridge(br_name1, interface_node1)
> +
> + if server2.is_ovs_bridge(interface_node2):
> + br_name2 = interface_node2
> + else:
> + br_name2 = DEFAULT_TEST_BRIDGE
> + server2.create_test_bridge(br_name2, interface_node2)
> +
> + server1.add_port_to_bridge(br_name1, DEFAULT_TEST_PORT)
> + servers_with_test_ports.append(server1)
> + server2.add_port_to_bridge(br_name2, DEFAULT_TEST_PORT)
> + servers_with_test_ports.append(server2)
> +
> + server1.ovs_vsctl_set("Port", DEFAULT_TEST_PORT, "tag", None, tag)
> + server2.ovs_vsctl_set("Port", DEFAULT_TEST_PORT, "tag", None, tag)
> +
> + server1.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type",
> None,
> + "internal")
> + server2.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type",
> None,
> + "internal")
> +
> + server1.interface_assign_ip(DEFAULT_TEST_PORT, node1[2], None)
> + server2.interface_assign_ip(DEFAULT_TEST_PORT, node2[2], None)
> +
> + server1.interface_up(DEFAULT_TEST_PORT)
> + server2.interface_up(DEFAULT_TEST_PORT)
> +
> + do_udp_tests(node1, node2, bandwidth, duration, ps)
> + do_udp_tests(node2, node1, bandwidth, duration, ps)
> + do_tcp_tests(node1, node2, duration)
> + do_tcp_tests(node2, node1, duration)
> +
> + finally:
> + for server in servers_with_test_ports:
> + server.del_port_from_bridge(DEFAULT_TEST_PORT)
> + if br_name1 == DEFAULT_TEST_BRIDGE:
> + server1.del_test_bridge(br_name1, interface_node1)
> + if br_name2 == DEFAULT_TEST_BRIDGE:
> + server2.del_test_bridge(br_name2, interface_node2)
> +
> +
> +def do_direct_tests(node1, node2, bandwidth, duration, ps):
> + """
> + Do tests between outer IPs without involving Open vSwitch
> + """
> + n1 = (node1[0], node1[1], node1[0], node1[3])
> + n2 = (node2[0], node2[1], node2[0], node2[3])
> +
> + do_udp_tests(n1, n2, bandwidth, duration, ps)
> + do_udp_tests(n2, n1, bandwidth, duration, ps)
> + do_tcp_tests(n1, n2, duration)
> + do_tcp_tests(n2, n1, duration)
> +
> +
> +def configure_l3(conf, tunnel_mode):
> + """
> + This function creates a temporary test bridge and adds L3 tunnel.
>
s/adds L3/adds an L3/
> + """
> + s = util.start_local_server(conf[1][1])
> + server = util.rpc_client("127.0.0.1", conf[1][1])
> + server.create_bridge(DEFAULT_TEST_BRIDGE)
> + server.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_PORT)
> + server.interface_up(DEFAULT_TEST_BRIDGE)
> + server.interface_assign_ip(DEFAULT_TEST_BRIDGE, conf[1][0],
> + None)
> + server.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type",
> + None, tunnel_mode)
> + server.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "options",
> + "remote_ip", conf[0])
> + return s
> diff --git a/python/ovstest/util.py b/python/ovstest/util.py
> index ee2a878..138a8f4 100644
> --- a/python/ovstest/util.py
> +++ b/python/ovstest/util.py
> @@ -19,11 +19,15 @@ import array
> import exceptions
> import fcntl
> import os
> +import select
> import socket
> import struct
> +import signal
> import subprocess
>
> import re
>
> +import xmlrpclib
> +
>
You can drop the newline between re and xmlrpclib
>
> def str_ip(ip_address):
> """
> @@ -147,3 +151,81 @@ def move_routes(iface1, iface2):
> for route in out.splitlines():
> args = ["ip", "route", "replace", "dev", iface2] +
> route.split()
> start_process(args)
> +
> +
> +def get_interface_from_routing_decision(ip):
> + """
> + This function returns the interface through which the given ip address
> + is reachable.
> + """
> + args = ["ip", "route", "get", ip]
> + ret, out, _err = start_process(args)
> + if ret == 0:
> + iface = re.search(r'dev (\S+)', out)
> + if iface:
> + return iface.group(1)
> + return None
> +
> +
> +def rpc_client(ip, port):
> + return xmlrpclib.Server("http://%s:%u/" % (ip, port),
> allow_none=True)
> +
> +
> +def sigint_intercept():
> + """
> + Intercept SIGINT from child (the local ovs-test server process).
> + """
> + signal.signal(signal.SIGINT, signal.SIG_IGN)
> +
> +
> +def start_local_server(port):
> + """
> + This function spawns an ovs-test server that listens on specified port
> + and blocks till the spawned ovs-test server is ready to accept XML RPC
> + connections.
> + """
>
> + p = subprocess.Popen(["ovs-test", "-s", str(port)],
> + stdout=subprocess.PIPE, stderr=subprocess.PIPE,
> + preexec_fn = sigint_intercept)
>
No spaces around = in kwargs
> + fcntl.fcntl( p.stdout.fileno(),fcntl.F_SETFL,
> + fcntl.fcntl(p.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
> +
> + while p.poll() is None:
> + fd = select.select([p.stdout.fileno()], [], [])[0]
> + if fd:
> + out = p.stdout.readline()
> + if out.startswith("Starting RPC server"):
> + break
> + if p.poll() is not None:
> + raise RuntimeError("Couldn't start local instance of ovs-test
> server")
> + return p
> +
> +
> +def get_datagram_sizes(mtu1, mtu2):
> + """
> + This function calculates all the "interesting" datagram sizes so that
> + we test both - receive and send side with different packets sizes.
> + """
> + s1 = set([8, mtu1 - 100, mtu1 - 28, mtu1])
> + s2 = set([8, mtu2 - 100, mtu2 - 28, mtu2])
> + return sorted(s1.union(s2))
> +
> +
> +def ip_from_cidr(string):
> + """
> + This function removes the netmask (if present) from the given string
> and
> + returns the IP address.
> + """
> + token = string.split("/")
> + return token[0]
> +
> +
> +def bandwidth_to_string(bwidth):
> + """Convert bandwidth from long to string and add units."""
> + bwidth = bwidth * 8 # Convert back to bits/second
> + if bwidth >= 10000000:
> + return str(int(bwidth / 1000000)) + "Mbps"
> + elif bwidth > 10000:
> + return str(int(bwidth / 1000)) + "Kbps"
> + else:
> + return str(int(bwidth)) + "bps"
> diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in
> index 54442fb..de22c86 100644
> --- a/rhel/openvswitch.spec.in
> +++ b/rhel/openvswitch.spec.in
> @@ -59,7 +59,9 @@ rm \
> $RPM_BUILD_ROOT/usr/bin/ovs-controller \
> $RPM_BUILD_ROOT/usr/share/man/man8/ovs-controller.8 \
> $RPM_BUILD_ROOT/usr/bin/ovs-test \
> + $RPM_BUILD_ROOT/usr/bin/ovs-l3ping \
> $RPM_BUILD_ROOT/usr/share/man/man8/ovs-test.8 \
> + $RPM_BUILD_ROOT/usr/share/man/man8/ovs-l3ping.8 \
> $RPM_BUILD_ROOT/usr/sbin/ovs-vlan-bug-workaround \
> $RPM_BUILD_ROOT/usr/share/man/man8/ovs-vlan-bug-workaround.8
>
> diff --git a/utilities/.gitignore b/utilities/.gitignore
> index 90f47ff..4f96a4f 100644
> --- a/utilities/.gitignore
> +++ b/utilities/.gitignore
> @@ -13,6 +13,8 @@
> /ovs-ctl
> /ovs-dpctl
> /ovs-dpctl.8
> +/ovs-l3ping
> +/ovs-l3ping.8
> /ovs-lib
> /ovs-ofctl
> /ovs-ofctl.8
> diff --git a/utilities/automake.mk b/utilities/automake.mk
> index f3da1b1..04a7fdc 100644
> --- a/utilities/automake.mk
> +++ b/utilities/automake.mk
> @@ -7,6 +7,7 @@ bin_PROGRAMS += \
> bin_SCRIPTS += utilities/ovs-pki utilities/ovs-vsctl
> utilities/ovs-parse-leaks
> if HAVE_PYTHON
> bin_SCRIPTS += \
> + utilities/ovs-l3ping \
> utilities/ovs-pcap \
> utilities/ovs-tcpundump \
> utilities/ovs-test \
> @@ -22,6 +23,7 @@ scripts_DATA += utilities/ovs-lib
> EXTRA_DIST += \
> utilities/ovs-check-dead-ifs.in \
> utilities/ovs-ctl.in \
> + utilities/ovs-l3ping.in \
> utilities/ovs-lib.in \
> utilities/ovs-parse-leaks.in \
> utilities/ovs-pcap.in \
> @@ -37,6 +39,7 @@ MAN_ROOTS += \
> utilities/ovs-controller.8.in \
> utilities/ovs-ctl.8 \
> utilities/ovs-dpctl.8.in \
> + utilities/ovs-l3ping.8.in \
> utilities/ovs-ofctl.8.in \
> utilities/ovs-parse-leaks.8 \
> utilities/ovs-pcap.1.in \
> @@ -54,6 +57,8 @@ DISTCLEANFILES += \
> utilities/ovs-check-dead-ifs \
> utilities/ovs-controller.8 \
> utilities/ovs-dpctl.8 \
> + utilities/ovs-l3ping \
> + utilities/ovs-l3ping.8 \
> utilities/ovs-lib \
> utilities/ovs-ofctl.8 \
> utilities/ovs-parse-leaks \
> @@ -76,6 +81,7 @@ man_MANS += \
> utilities/ovs-benchmark.1 \
> utilities/ovs-controller.8 \
> utilities/ovs-dpctl.8 \
> + utilities/ovs-l3ping.8 \
> utilities/ovs-ofctl.8 \
> utilities/ovs-parse-leaks.8 \
> utilities/ovs-pcap.1 \
> diff --git a/utilities/ovs-l3ping.8.in b/utilities/ovs-l3ping.8.in
> new file mode 100644
> index 0000000..69da80f
> --- /dev/null
> +++ b/utilities/ovs-l3ping.8.in
> @@ -0,0 +1,108 @@
> +.de IQ
> +. br
> +. ns
> +. IP "\\$1"
> +..
> +.TH ovs\-l3ping 1 "June 2012" "Open vSwitch" "Open vSwitch Manual"
> +.
> +.SH NAME
> +\fBovs\-l3ping\fR \- check network deployment for L3 tunneling
> +problems
> +.
> +.SH SYNOPSIS
> +\fBovs\-l3ping\fR \fB\-s\fR
> \fITunnelRemoteIP,InnerIP[/mask][:ControlPort]\fR
> +.PP
> +\fBovs\-l3ping\fR \fB\-c\fR \fITunnelRemoteIP,InnerIP[/mask][:ControlPort\
> +[:DataPort]],RemoteInnerIP[:ControlPort[:DataPort]]\fR
> +[\fB\-b\fR \fItargetbandwidth\fR] [\fB\-i\fR \fItestinterval\fR]
> +\fB\-t\fR \fItunnelmode\fR
> +.so lib/common-syn.man
> +.
> +.SH DESCRIPTION
> +The \fBovs\-l3ping\fR program may be used to check for problems that could
> +be caused by invalid routing policy, misconfigured firewall in the tunnel
> +path or a bad NIC driver. On one of the nodes, run \fBovs\-l3ping\fR in
> +server mode and on the other node run it in client mode. The client and
> +server will establish L3 tunnel, over which client will give further
> testing
> +instructions. The \fBovs\-l3ping\fR client will perform UDP and TCP tests.
> +This tool is different from \fBovs\-test\fR that it encapsulates XML/RPC
> +control connection over the tunnel, so there is no need to open special
> holes
> +in firewall.
> +.PP
> +UDP tests can report packet loss and achieved bandwidth for various
> +datagram sizes. By default target bandwidth for UDP tests is 1Mbit/s.
> +.PP
> +TCP tests report only achieved bandwidth, because kernel TCP stack
> +takes care of flow control and packet loss.
> +.
> +.SS "Client Mode"
> +An \fBovs\-l3ping\fR client will create a L3 tunnel and connect over it
> to the
> +\fBovs\-l3ping\fR server to schedule the tests. \fITunnelRemoteIP\fR is
> the
> +peer's IP address, where tunnel will be terminated. \fIInnerIP\fR is the
> +address that will be temporarily assigned during testing. All test
> traffic
> +originating from this IP address to the \fIRemoteInnerIP\fR will be
> tunneled.
> +It is possible to override default \fIControlPort\fR and \fIDataPort\fR,
> if
> +there is any other application that already listens on those two ports.
> +.
> +.SS "Server Mode"
> +To conduct tests, \fBovs\-l3ping\fR server must be running. It is
> required
> +that both client and server \fIInnerIP\fR addresses are in the same
> subnet.
> +It is possible to specify \fIInnerIP\fR with netmask in CIDR format.
> +.
> +.SH OPTIONS
> +.
> +.IP "\fB\-s \fITunnelRemoteIP,InnerIP[/mask][:ControlPort]\fR"
> +.IQ "\fB\-\-server\fR \fITunnelRemoteIP,InnerIP[/mask][:ControlPort]\fR"
> +Run in server mode and create L3 tunnel with the client that will be
> +accepting tunnel at \fITunnelRemoteIP\fR address. The socket on
> +\fIInnerIP[:ControlPort]\fR will be used to receive further instructions
> +from the client.
> +.
> +.IP "\fB\-c \fITunnelRemoteIP,InnerIP[/mask][:ControlPort\
> +[:DataPort]],RemoteInnerIP[:ControlPort[:DataPort]]\fR"
> +.IQ "\fB\-\-client \fITunnelRemoteIP,InnerIP[/mask][:ControlPort\
> +[:DataPort]],RemoteInnerIP[:ControlPort[:DataPort]]\fR"
> +Run in client mode and create L3 tunnel with the server on
> +\fITunnelRemoteIP\fR. The client will use \fIInnerIP\fR to generate test
> +traffic with the server's \fIRemoteInnerIP\fR.
> +.
> +.IP "\fB\-b \fItargetbandwidth\fR"
> +.IQ "\fB\-\-bandwidth\fR \fItargetbandwidth\fR"
> +Target bandwidth for UDP tests. The \fItargetbandwidth\fR must be given in
> +bits per second. It is possible to use postfix M or K to alter the target
> +bandwidth magnitude.
> +.
> +.IP "\fB\-i \fItestinterval\fR"
> +.IQ "\fB\-\-interval\fR \fItestinterval\fR"
> +How long each test should run. By default 5 seconds.
> +.
> +.IP "\fB\-t \fItunnelmode\fR"
> +.IQ "\fB\-\-fItunnel\-mode\fR \fItunnelmode\fR"
> +Specify the tunnel type. This option must match on server and client.
> +.
> +.so lib/common.man
> +.
> +.SH EXAMPLES
> +.PP
> +On host 192.168.122.220 start \fBovs\-l3ping\fR in server mode. This
> command
> +will create a temporary GRE tunnel with the host 192.168.122.236 and
> assign
> +10.1.1.1/28 as the inner IP address, where client will have to connect:
> +.IP
> +.B ovs\-l3ping -s 192.168.122.236,10.1.1.1/28 -t gre
> +.
> +.PP
> +On host 192.168.122.236 start \fBovs\-l3ping\fR in client mode. This
> command
> +will use 10.1.1.2/28 as the local inner IP address and will connect over
> the
> +L3 tunnel to the server's inner IP address at 10.1.1.1.
> +.IP
> +.B ovs\-l3ping -c 192.168.122.220,10.1.1.2/28,10.1.1.1 -t gre
> +.
> +.SH SEE ALSO
> +.
> +.BR ovs\-vswitchd (8),
> +.BR ovs\-ofctl (8),
> +.BR ovs\-vsctl (8),
> +.BR ovs\-vlan\-test (8),
> +.BR ovs\-test (8),
> +.BR ethtool (8),
> +.BR uname (1)
> \ No newline at end of file
> diff --git a/utilities/ovs-l3ping.in b/utilities/ovs-l3ping.in
> new file mode 100644
> index 0000000..35e5fdd
> --- /dev/null
> +++ b/utilities/ovs-l3ping.in
> @@ -0,0 +1,76 @@
> +#! @PYTHON@
> +#
> +# 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.
> +
> +"""
> +ovs L3 ping utility allows to do tests between two remote hosts without
> +opening holes in the firewall for the XML RPC control connection. This is
> +achieved by tunneling the control connection inside the tunnel itself.
> +"""
> +
> +import socket
> +import xmlrpclib
> +
> +import ovstest.args as args
> +import ovstest.tests as tests
> +import ovstest.util as util
> +
> +
> +def get_packet_sizes(me, he, remote_ip):
> + """
> + This function retrieves MTUs from both hosts and returns a list of
> + packet sizes, that are more likely to uncover possible configuration
> + issues.
> + """
> + mtu_node1 = 1500
> + mtu_node2 = 1500
> + server1 = util.rpc_client(me[0], me[1])
> + server2 = util.rpc_client(he[0], he[1])
> + iface1 = server2.get_interface(remote_ip)
> + iface2 = server1.get_interface_from_routing_decision(remote_ip)
> + if iface1:
> + mtu_node1 = server2.get_interface_mtu(iface1)
> + if iface2:
> + mtu_node2 = server1.get_interface_mtu(iface2)
> + return util.get_datagram_sizes(mtu_node1, mtu_node2)
> +
> +
> +if __name__ == '__main__':
> + local_server = None
> + try:
> + args = args.l3_initialize_args()
> + tunnel_mode = args.tunnelMode
> + if args.server is not None: # Start in server mode
> + local_server = tests.configure_l3(args.server, tunnel_mode)
> + local_server.wait()
> + elif args.client is not None: # Run in client mode
> + bandwidth = args.targetBandwidth
> + interval = args.testInterval
> + me = (util.ip_from_cidr(args.client[1][0]), args.client[1][1],
> + args.client[1][0], args.client[1][2])
> + he = (args.client[2][0], args.client[2][1],
> + args.client[2][0], args.client[2][2])
> + local_server = tests. configure_l3(args.client, tunnel_mode)
> + ps = get_packet_sizes(me, he, args.client[0])
> + tests.do_direct_tests(me, he, bandwidth, interval, ps)
>
> + except KeyboardInterrupt:
> + pass
>
Might be friendly to add something here to distinguish from normal
termination
> + except xmlrpclib.Fault:
> + print "Couldn't contact peer"
> + except socket.error:
> + print "Couldn't contact peer"
> + except xmlrpclib.ProtocolError:
> + print "XMLRPC control channel was abruptly terminated"
> + finally:
> + if local_server is not None:
> + local_server.terminate()
> diff --git a/utilities/ovs-test.in b/utilities/ovs-test.in
> index b53302f..fb1f9ad 100644
> --- a/utilities/ovs-test.in
> +++ b/utilities/ovs-test.in
> @@ -32,80 +32,18 @@ import twisted
>
> import ovstest.args as args
> import ovstest.rpcserver as rpcserver
> +import ovstest.tests as tests
> +import ovstest.util as util
>
> DEFAULT_TEST_BRIDGE = "ovstestbr0"
> DEFAULT_TEST_PORT = "ovstestport0"
> DEFAULT_TEST_TUN = "ovstestport1"
>
>
> -def rpc_client(ip, port):
> - return xmlrpclib.Server("http://%s:%u/" % (ip, port),
> allow_none=True)
> -
> -
> -def sigint_intercept():
> - """
> - Intercept SIGINT from child (the local ovs-test server process).
> - """
> - signal.signal(signal.SIGINT, signal.SIG_IGN)
> -
> -
> -def start_local_server(port):
> - """
> - This function spawns an ovs-test server that listens on specified port
> - and blocks till the spawned ovs-test server is ready to accept XML RPC
> - connections.
> - """
> - p = subprocess.Popen(["ovs-test", "-s", str(port)],
> - stdout=subprocess.PIPE, stderr=subprocess.PIPE,
> - preexec_fn = sigint_intercept)
> - fcntl.fcntl( p.stdout.fileno(),fcntl.F_SETFL,
> - fcntl.fcntl(p.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
> -
> - while p.poll() is None:
> - fd = select.select([p.stdout.fileno()], [], [])[0]
> - if fd:
> - out = p.stdout.readline()
> - if out.startswith("Starting RPC server"):
> - break
> - if p.poll() is not None:
> - raise RuntimeError("Couldn't start local instance of ovs-test
> server")
> - return p
> -
> -
> -def get_datagram_sizes(mtu1, mtu2):
> - """
> - This function calculates all the "interesting" datagram sizes so that
> - we test both - receive and send side with different packets sizes.
> - """
> - s1 = set([8, mtu1 - 100, mtu1 - 28, mtu1])
> - s2 = set([8, mtu2 - 100, mtu2 - 28, mtu2])
> - return sorted(s1.union(s2))
> -
> -
> -def ip_from_cidr(string):
> - """
> - This function removes the netmask (if present) from the given string
> and
> - returns the IP address.
> - """
> - token = string.split("/")
> - return token[0]
> -
> -
> -def bandwidth_to_string(bwidth):
> - """Convert bandwidth from long to string and add units."""
> - bwidth = bwidth * 8 # Convert back to bits/second
> - if bwidth >= 10000000:
> - return str(int(bwidth / 1000000)) + "Mbps"
> - elif bwidth > 10000:
> - return str(int(bwidth / 1000)) + "Kbps"
> - else:
> - return str(int(bwidth)) + "bps"
> -
> -
> def collect_information(node):
> """Print information about hosts that will do testing"""
> print "Node %s:%u " % (node[0], node[1])
> - server = rpc_client(node[0], node[1])
> + server = util.rpc_client(node[0], node[1])
> interface_name = server.get_interface(node[0])
> phys_iface = None
> uname = server.uname()
> @@ -140,210 +78,6 @@ def collect_information(node):
> return mtu
>
>
> -def do_udp_tests(receiver, sender, tbwidth, duration, port_sizes):
> - """Schedule UDP tests between receiver and sender"""
> - server1 = rpc_client(receiver[0], receiver[1])
> - server2 = rpc_client(sender[0], sender[1])
> -
> - udpformat = '{0:>15} {1:>15} {2:>15} {3:>15} {4:>15}'
> -
> - print ("UDP test from %s:%u to %s:%u with target bandwidth %s" %
> - (sender[0], sender[1], receiver[0],
> receiver[1],
> - bandwidth_to_string(tbwidth)))
> - print udpformat.format("Datagram Size", "Snt Datagrams", "Rcv
> Datagrams",
> - "Datagram Loss", "Bandwidth")
> -
> - for size in port_sizes:
> - listen_handle = -1
> - send_handle = -1
> - try:
> - packetcnt = (tbwidth * duration) / size
> -
> - listen_handle = server1.create_udp_listener(receiver[3])
> - if listen_handle == -1:
> - print ("Server could not open UDP listening socket on
> port"
> - " %u. Try to restart the server.\n" % receiver[3])
> - return
> - send_handle = server2.create_udp_sender(
> - (ip_from_cidr(receiver[2]),
> - receiver[3]), packetcnt,
> size,
> - duration)
> -
> - # Using sleep here because there is no other synchronization
> source
> - # that would notify us when all sent packets were received
> - time.sleep(duration + 1)
> -
> - rcv_packets = server1.get_udp_listener_results(listen_handle)
> - snt_packets = server2.get_udp_sender_results(send_handle)
> -
> - loss = math.ceil(((snt_packets - rcv_packets) * 10000.0) /
> - snt_packets) / 100
> - bwidth = (rcv_packets * size) / duration
> -
> - print udpformat.format(size, snt_packets, rcv_packets,
> - '%.2f%%' % loss,
> bandwidth_to_string(bwidth))
> - finally:
> - if listen_handle != -1:
> - server1.close_udp_listener(listen_handle)
> - if send_handle != -1:
> - server2.close_udp_sender(send_handle)
> - print "\n"
> -
> -
> -def do_tcp_tests(receiver, sender, duration):
> - """Schedule TCP tests between receiver and sender"""
> - server1 = rpc_client(receiver[0], receiver[1])
> - server2 = rpc_client(sender[0], sender[1])
> -
> - tcpformat = '{0:>15} {1:>15} {2:>15}'
> - print "TCP test from %s:%u to %s:%u (full speed)" % (sender[0],
> sender[1],
> - receiver[0],
> receiver[1])
> - print tcpformat.format("Snt Bytes", "Rcv Bytes", "Bandwidth")
> -
> - listen_handle = -1
> - send_handle = -1
> - try:
> - listen_handle = server1.create_tcp_listener(receiver[3])
> - if listen_handle == -1:
> - print ("Server was unable to open TCP listening socket on
> port"
> - " %u. Try to restart the server.\n" % receiver[3])
> - return
> - send_handle = server2.create_tcp_sender(ip_from_cidr(receiver[2]),
> - receiver[3], duration)
> -
> - time.sleep(duration + 1)
> -
> - rcv_bytes = long(server1.get_tcp_listener_results(listen_handle))
> - snt_bytes = long(server2.get_tcp_sender_results(send_handle))
> -
> - bwidth = rcv_bytes / duration
> -
> - print tcpformat.format(snt_bytes, rcv_bytes,
> - bandwidth_to_string(bwidth))
> - finally:
> - if listen_handle != -1:
> - server1.close_tcp_listener(listen_handle)
> - if send_handle != -1:
> - server2.close_tcp_sender(send_handle)
> - print "\n"
> -
> -
> -def do_l3_tests(node1, node2, bandwidth, duration, ps, type):
> - """
> - Do L3 tunneling tests.
> - """
> - server1 = rpc_client(node1[0], node1[1])
> - server2 = rpc_client(node2[0], node2[1])
> - servers_with_bridges = []
> - try:
> - server1.create_bridge(DEFAULT_TEST_BRIDGE)
> - servers_with_bridges.append(server1)
> - server2.create_bridge(DEFAULT_TEST_BRIDGE)
> - servers_with_bridges.append(server2)
> -
> - server1.interface_up(DEFAULT_TEST_BRIDGE)
> - server2.interface_up(DEFAULT_TEST_BRIDGE)
> -
> - server1.interface_assign_ip(DEFAULT_TEST_BRIDGE, node1[2], None)
> - server2.interface_assign_ip(DEFAULT_TEST_BRIDGE, node2[2], None)
> -
> - server1.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_TUN)
> - server2.add_port_to_bridge(DEFAULT_TEST_BRIDGE, DEFAULT_TEST_TUN)
> -
> - server1.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "type",
> - None, type)
> - server2.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "type",
> - None, type)
> - server1.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "options",
> - "remote_ip", node2[0])
> - server2.ovs_vsctl_set("Interface", DEFAULT_TEST_TUN, "options",
> - "remote_ip", node1[0])
> -
> - do_udp_tests(node1, node2, bandwidth, duration, ps)
> - do_udp_tests(node2, node1, bandwidth, duration, ps)
> - do_tcp_tests(node1, node2, duration)
> - do_tcp_tests(node2, node1, duration)
> -
> - finally:
> - for server in servers_with_bridges:
> - server.del_bridge(DEFAULT_TEST_BRIDGE)
> -
> -
> -
> -def do_vlan_tests(node1, node2, bandwidth, duration, ps, tag):
> - """
> - Do VLAN tests between node1 and node2.
> - """
> - server1 = rpc_client(node1[0], node1[1])
> - server2 = rpc_client(node2[0], node2[1])
> -
> - br_name1 = None
> - br_name2 = None
> -
> - servers_with_test_ports = []
> -
> - try:
> - interface_node1 = server1.get_interface(node1[0])
> - interface_node2 = server2.get_interface(node2[0])
> -
> - if server1.is_ovs_bridge(interface_node1):
> - br_name1 = interface_node1
> - else:
> - br_name1 = DEFAULT_TEST_BRIDGE
> - server1.create_test_bridge(br_name1, interface_node1)
> -
> - if server2.is_ovs_bridge(interface_node2):
> - br_name2 = interface_node2
> - else:
> - br_name2 = DEFAULT_TEST_BRIDGE
> - server2.create_test_bridge(br_name2, interface_node2)
> -
> - server1.add_port_to_bridge(br_name1, DEFAULT_TEST_PORT)
> - servers_with_test_ports.append(server1)
> - server2.add_port_to_bridge(br_name2, DEFAULT_TEST_PORT)
> - servers_with_test_ports.append(server2)
> -
> - server1.ovs_vsctl_set("Port", DEFAULT_TEST_PORT, "tag", None, tag)
> - server2.ovs_vsctl_set("Port", DEFAULT_TEST_PORT, "tag", None, tag)
> -
> - server1.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type",
> None,
> - "internal")
> - server2.ovs_vsctl_set("Interface", DEFAULT_TEST_PORT, "type",
> None,
> - "internal")
> -
> - server1.interface_assign_ip(DEFAULT_TEST_PORT, node1[2], None)
> - server2.interface_assign_ip(DEFAULT_TEST_PORT, node2[2], None)
> -
> - server1.interface_up(DEFAULT_TEST_PORT)
> - server2.interface_up(DEFAULT_TEST_PORT)
> -
> - do_udp_tests(node1, node2, bandwidth, duration, ps)
> - do_udp_tests(node2, node1, bandwidth, duration, ps)
> - do_tcp_tests(node1, node2, duration)
> - do_tcp_tests(node2, node1, duration)
> -
> - finally:
> - for server in servers_with_test_ports:
> - server.del_port_from_bridge(DEFAULT_TEST_PORT)
> - if br_name1 == DEFAULT_TEST_BRIDGE:
> - server1.del_test_bridge(br_name1, interface_node1)
> - if br_name2 == DEFAULT_TEST_BRIDGE:
> - server2.del_test_bridge(br_name2, interface_node2)
> -
> -
> -def do_direct_tests(node1, node2, bandwidth, duration, ps):
> - """
> - Do tests between outer IPs without involving Open vSwitch
> - """
> - n1 = (node1[0], node1[1], node1[0], node1[3])
> - n2 = (node2[0], node2[1], node2[0], node2[3])
> -
> - do_udp_tests(n1, n2, bandwidth, duration, ps)
> - do_udp_tests(n2, n1, bandwidth, duration, ps)
> - do_tcp_tests(n1, n2, duration)
> - do_tcp_tests(n2, n1, duration)
> -
> -
> if __name__ == '__main__':
> local_server = None
> try:
> @@ -360,10 +94,10 @@ if __name__ == '__main__':
> # ovs-test server by looking at the first OuterIP. if it is a
> # 127.0.0.1 then spawn local ovs-test server.
> if node1[0] == "127.0.0.1":
> - local_server = start_local_server(node1[1])
> + local_server = util.start_local_server(node1[1])
> # We must determine the IP address that local ovs-test
> server
> # will use:
> - me = rpc_client(node1[0], node1[1])
> + me = util.rpc_client(node1[0], node1[1])
> my_ip = me.get_my_address_from(node2[0], node2[1])
> node1 = (my_ip, node1[1], node1[2], node1[3])
>
> @@ -372,7 +106,7 @@ if __name__ == '__main__':
>
> bandwidth = ovs_args.targetBandwidth
> interval = ovs_args.testInterval
> - ps = get_datagram_sizes(mtu_node1, mtu_node2)
> + ps = util.get_datagram_sizes(mtu_node1, mtu_node2)
>
> direct = ovs_args.direct
> vlan_tag = ovs_args.vlanTag
> @@ -380,15 +114,17 @@ if __name__ == '__main__':
>
> if direct is not None:
> print "Performing direct tests"
> - do_direct_tests(node2, node1, bandwidth, interval, ps)
> + tests.do_direct_tests(node2, node1, bandwidth, interval,
> ps)
>
> if vlan_tag is not None:
> print "Performing VLAN tests"
> - do_vlan_tests(node2, node1, bandwidth, interval, ps,
> vlan_tag)
> + tests.do_vlan_tests(node2, node1, bandwidth, interval, ps,
> + vlan_tag)
>
> for tmode in tunnel_modes:
> print "Performing", tmode, "tests"
> - do_l3_tests(node2, node1, bandwidth, interval, ps, tmode)
> + tests.do_l3_tests(node2, node1, bandwidth, interval, ps,
> + tmode)
>
> except KeyboardInterrupt:
> pass
> diff --git a/xenserver/openvswitch-xen.spec.in b/xenserver/
> openvswitch-xen.spec.in
> index e051b31..3b9582e 100644
> --- a/xenserver/openvswitch-xen.spec.in
> +++ b/xenserver/openvswitch-xen.spec.in
> @@ -125,13 +125,15 @@ rm \
> $RPM_BUILD_ROOT/usr/bin/ovs-benchmark \
> $RPM_BUILD_ROOT/usr/sbin/ovs-bugtool \
> $RPM_BUILD_ROOT/usr/bin/ovs-controller \
> + $RPM_BUILD_ROOT/usr/bin/ovs-l3ping \
> $RPM_BUILD_ROOT/usr/bin/ovs-pki \
> $RPM_BUILD_ROOT/usr/bin/ovs-test \
> - $RPM_BUILD_ROOT/usr/share/man/man8/ovs-test.8 \
> $RPM_BUILD_ROOT/usr/share/man/man1/ovs-benchmark.1 \
> $RPM_BUILD_ROOT/usr/share/man/man8/ovs-bugtool.8 \
> $RPM_BUILD_ROOT/usr/share/man/man8/ovs-controller.8 \
> - $RPM_BUILD_ROOT/usr/share/man/man8/ovs-pki.8
> + $RPM_BUILD_ROOT/usr/share/man/man8/ovs-l3ping.8
> + $RPM_BUILD_ROOT/usr/share/man/man8/ovs-pki.8 \
> + $RPM_BUILD_ROOT/usr/share/man/man8/ovs-test.8
>
> install -d -m 755 $RPM_BUILD_ROOT/var/lib/openvswitch
>
> --
> 1.7.9.5
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openvswitch.org/pipermail/ovs-dev/attachments/20120628/edbe231e/attachment-0003.html>
More information about the dev
mailing list