aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/04_vnf.conf28
-rw-r--r--core/traffic_controller_rfc2544.py10
-rw-r--r--core/vnf_controller.py5
-rw-r--r--core/vswitch_controller.py7
-rw-r--r--core/vswitch_controller_p2p.py5
-rw-r--r--core/vswitch_controller_pvp.py5
-rw-r--r--core/vswitch_controller_pvvp.py5
-rw-r--r--docs/to-be-reorganized/NEWS.rst7
-rw-r--r--docs/to-be-reorganized/quickstart.rst38
-rw-r--r--testcases/testcase.py20
-rw-r--r--tools/pkt_gen/ixnet/ixnetrfc2544.tcl18
-rw-r--r--vnfs/qemu/qemu.py14
-rw-r--r--vnfs/qemu/qemu_dpdk.py13
-rw-r--r--vnfs/qemu/qemu_virtio_net.py115
-rw-r--r--vnfs/vnf/vnf.py10
-rw-r--r--vswitches/ovs_dpdk_vhost.py6
-rw-r--r--vswitches/ovs_vanilla.py53
-rw-r--r--vswitches/vswitch.py7
18 files changed, 331 insertions, 35 deletions
diff --git a/conf/04_vnf.conf b/conf/04_vnf.conf
index 034e4108..52cc6ec1 100644
--- a/conf/04_vnf.conf
+++ b/conf/04_vnf.conf
@@ -79,5 +79,33 @@ GUEST_SMP = ['2', '2']
# For 2 VNFs you may use [(4,5), (6, 7)]
GUEST_CORE_BINDING = [(6, 7), (9, 10)]
+GUEST_START_TIMEOUT = 120
GUEST_OVS_DPDK_DIR = '/root/ovs_dpdk'
OVS_DPDK_SHARE = '/mnt/ovs_dpdk_share'
+
+# IP addresses to use for Vanilla OVS PVP testing
+# Consider using RFC 2544/3330 recommended IP addresses for benchmark testing.
+# Network: 198.18.0.0/15
+# Netmask: 255.254.0.0
+# Broadcast: 198.19.255.255
+# First IP: 198.18.0.1
+# Last IP: 198.19.255.254
+# Hosts: 131070
+#
+
+# ARP entries for the IXIA ports and the bridge you are using:
+VANILLA_TGEN_PORT1_IP = '1.1.1.10'
+VANILLA_TGEN_PORT1_MAC = 'AA:BB:CC:DD:EE:FF'
+
+VANILLA_TGEN_PORT2_IP = '1.1.2.10'
+VANILLA_TGEN_PORT2_MAC = 'AA:BB:CC:DD:EE:F0'
+
+VANILLA_BRIDGE_IP = ['1.1.1.5/16', '1.1.1.6/16']
+
+VANILLA_NIC1_NAME = ['eth0', 'eth2']
+VANILLA_NIC2_NAME = ['eth1', 'eth3']
+
+VANILLA_NIC1_IP_CIDR = ['192.168.1.2/24', '192.168.1.4/24']
+VANILLA_NIC2_IP_CIDR = ['192.168.1.3/24', '192.168.1.5/24']
+
+VNF_AFFINITIZATION_ON = True
diff --git a/core/traffic_controller_rfc2544.py b/core/traffic_controller_rfc2544.py
index fa4a9c35..5659569f 100644
--- a/core/traffic_controller_rfc2544.py
+++ b/core/traffic_controller_rfc2544.py
@@ -49,7 +49,7 @@ class TrafficControllerRFC2544(ITrafficController, IResults):
packet_sizes_cli = get_test_param('pkt_sizes')
if packet_sizes_cli:
self._packet_sizes = [int(x.strip())
- for x in packet_sizes_cli.split(',')]
+ for x in packet_sizes_cli.split(',')]
else:
self._packet_sizes = settings.getValue('TRAFFICGEN_PKT_SIZES')
@@ -91,7 +91,13 @@ class TrafficControllerRFC2544(ITrafficController, IResults):
str(self._traffic_gen_class))
for packet_size in self._packet_sizes:
- traffic['l2'] = {'framesize': packet_size}
+ # Merge framesize with the default traffic definition
+ if 'l2' in traffic:
+ traffic['l2'] = dict(traffic['l2'],
+ **{'framesize': packet_size})
+ else:
+ traffic['l2'] = {'framesize': packet_size}
+
if traffic['traffic_type'] == 'back2back':
result = self._traffic_gen_class.send_rfc2544_back2back(
traffic, trials=self._trials,
diff --git a/core/vnf_controller.py b/core/vnf_controller.py
index 3d3be040..3313e9e3 100644
--- a/core/vnf_controller.py
+++ b/core/vnf_controller.py
@@ -15,6 +15,7 @@
"""
import logging
+from vnfs.vnf.vnf import IVnf
class VnfController(object):
"""VNF controller class
@@ -33,6 +34,10 @@ class VnfController(object):
:param vnf_class: The VNF class to be used.
"""
+ # reset VNF ID counter for each testcase
+ IVnf.reset_vnf_counter()
+
+ # setup controller with requested number of VNFs
self._logger = logging.getLogger(__name__)
self._vnf_class = vnf_class
self._deployment_scenario = deployment_scenario.upper()
diff --git a/core/vswitch_controller.py b/core/vswitch_controller.py
index 619e1d8b..855de8b2 100644
--- a/core/vswitch_controller.py
+++ b/core/vswitch_controller.py
@@ -49,3 +49,10 @@ class IVswitchController(object):
raise NotImplementedError(
"The VswitchController does not implement the \"get_ports_info\" "
"function.")
+
+ def dump_vswitch_flows(self):
+ """ Dumps flows from vswitch
+ """
+ raise NotImplementedError(
+ "The VswitchController does not implement the "
+ "\"dump_vswitch_flows\" function.")
diff --git a/core/vswitch_controller_p2p.py b/core/vswitch_controller_p2p.py
index c15f7ef8..35600e1b 100644
--- a/core/vswitch_controller_p2p.py
+++ b/core/vswitch_controller_p2p.py
@@ -114,3 +114,8 @@ class VswitchControllerP2P(IVswitchController):
"""
self._logger.debug('get_ports_info using ' + str(self._vswitch_class))
return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME'))
+
+ def dump_vswitch_flows(self):
+ """See IVswitchController for description
+ """
+ self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME'))
diff --git a/core/vswitch_controller_pvp.py b/core/vswitch_controller_pvp.py
index 80c0fdb2..b2337bd6 100644
--- a/core/vswitch_controller_pvp.py
+++ b/core/vswitch_controller_pvp.py
@@ -104,3 +104,8 @@ class VswitchControllerPVP(IVswitchController):
"""
self._logger.debug('get_ports_info using ' + str(self._vswitch_class))
return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME'))
+
+ def dump_vswitch_flows(self):
+ """See IVswitchController for description
+ """
+ self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME'))
diff --git a/core/vswitch_controller_pvvp.py b/core/vswitch_controller_pvvp.py
index b445f9bd..43cf8a35 100644
--- a/core/vswitch_controller_pvvp.py
+++ b/core/vswitch_controller_pvvp.py
@@ -112,3 +112,8 @@ class VswitchControllerPVVP(IVswitchController):
"""
self._logger.debug('get_ports_info using ' + str(self._vswitch_class))
return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME'))
+
+ def dump_vswitch_flows(self):
+ """See IVswitchController for description
+ """
+ self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME'))
diff --git a/docs/to-be-reorganized/NEWS.rst b/docs/to-be-reorganized/NEWS.rst
index 69df7478..0fe9e22b 100644
--- a/docs/to-be-reorganized/NEWS.rst
+++ b/docs/to-be-reorganized/NEWS.rst
@@ -1,3 +1,9 @@
+October 2015
+==============
+New
+---
+- Support of PVP and PVVP deployment scenarios using Vanilla OVS
+
September 2015
==============
New
@@ -63,4 +69,3 @@ Missing
-------
- xmlunit output is currently disabled
-- VNF support.
diff --git a/docs/to-be-reorganized/quickstart.rst b/docs/to-be-reorganized/quickstart.rst
index 485bf1ae..c575be59 100644
--- a/docs/to-be-reorganized/quickstart.rst
+++ b/docs/to-be-reorganized/quickstart.rst
@@ -203,7 +203,45 @@ To run tests using vhost-cuse as guest access method:
./vsperf --conf-file <path_to_settings_py>
+Executing PVP tests using Vanilla OVS
+-------------------------------------
+To run tests using Vanilla OVS:
+
+1. Set the following variables:
+
+ .. code-block:: console
+
+ VSWITCH = 'OvsVanilla'
+ VNF = 'QemuVirtioNet'
+
+ VANILLA_TGEN_PORT1_IP = n.n.n.n
+ VANILLA_TGEN_PORT1_MAC = nn:nn:nn:nn:nn:nn
+
+ VANILLA_TGEN_PORT2_IP = n.n.n.n
+ VANILLA_TGEN_PORT2_MAC = nn:nn:nn:nn:nn:nn
+
+ VANILLA_BRIDGE_IP = n.n.n.n
+
+ or use --test-param
+
+ ./vsperf --conf-file user_settings.py
+ --test-param "vanilla_tgen_tx_ip=n.n.n.n;
+ vanilla_tgen_tx_mac=nn:nn:nn:nn:nn:nn"
+
+
+2. Recompile src for Vanilla OVS testing
+ .. code-block:: console
+
+ cd src
+ make cleanse
+ make WITH_LINUX=/lib/modules/`uname -r`/build
+
+3. Run test:
+
+ .. code-block:: console
+
+ ./vsperf --conf-file <path_to_settings_py>
GOTCHAs:
--------
diff --git a/testcases/testcase.py b/testcases/testcase.py
index e15572d8..feb264d3 100644
--- a/testcases/testcase.py
+++ b/testcases/testcase.py
@@ -23,7 +23,7 @@ from core.results.results_constants import ResultsConstants
import core.component_factory as component_factory
from core.loader import Loader
from tools.report import report
-from conf import settings
+from conf import settings as S
class TestCase(object):
"""TestCase base class
@@ -92,12 +92,25 @@ class TestCase(object):
'bidir': self._bidir,
'multistream': self._multistream}
+ # OVS Vanilla requires guest VM MAC address and IPs
+ # to work
+ if (self.deployment in ["pvp", "pvvp"] and
+ S.getValue('VSWITCH') == "OvsVanilla"):
+
+ traffic['l2'] = {'srcmac': S.getValue('GUEST_NET2_MAC')[0],
+ 'dstmac': S.getValue('GUEST_NET1_MAC')[0]}
+
+ traffic['l3'] = {'srcip':
+ S.getValue('VANILLA_TGEN_PORT1_IP'),
+ 'dstip':
+ S.getValue('VANILLA_TGEN_PORT2_IP')}
+
vswitch = vswitch_ctl.get_vswitch()
# TODO BOM 15-08-07 the frame mod code assumes that the
# physical ports are ports 1 & 2. The actual numbers
# need to be retrived from the vSwitch and the metadata value
# updated accordingly.
- bridge = settings.getValue('VSWITCH_BRIDGE_NAME')
+ bridge = S.getValue('VSWITCH_BRIDGE_NAME')
if self._frame_mod == "vlan":
# 0x8100 => VLAN ethertype
self._logger.debug(" **** VLAN ***** ")
@@ -178,6 +191,9 @@ class TestCase(object):
with traffic_ctl:
traffic_ctl.send_traffic(traffic)
+ # dump vswitch flows before they are affected by VNF termination
+ vswitch_ctl.dump_vswitch_flows()
+
self._logger.debug("Traffic Results:")
traffic_ctl.print_results()
diff --git a/tools/pkt_gen/ixnet/ixnetrfc2544.tcl b/tools/pkt_gen/ixnet/ixnetrfc2544.tcl
index d5479b25..eda369db 100644
--- a/tools/pkt_gen/ixnet/ixnetrfc2544.tcl
+++ b/tools/pkt_gen/ixnet/ixnetrfc2544.tcl
@@ -702,7 +702,7 @@ proc startRfc2544Test { testSpec trafficSpec } {
-frEncapsulation ::ixNet::OBJ-null \
-incrementPerVcVlanMode noIncrement \
-incrementVlanMode noIncrement \
- -mac "00:00:00:00:00:01" \
+ -mac $srcMac \
-macRangeMode normal \
-numberOfVcs 1 \
-siteId 0 \
@@ -1082,7 +1082,7 @@ proc startRfc2544Test { testSpec trafficSpec } {
-frEncapsulation ::ixNet::OBJ-null \
-incrementPerVcVlanMode noIncrement \
-incrementVlanMode noIncrement \
- -mac "00:01:00:05:08:00" \
+ -mac $dstMac \
-macRangeMode normal \
-numberOfVcs 1 \
-siteId 0 \
@@ -2046,14 +2046,14 @@ proc startRfc2544Test { testSpec trafficSpec } {
#
set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.srcIp-27"
ixNet setMultiAttrs $sg_field \
- -singleValue {1.1.1.1} \
+ -singleValue $srcIp \
-seed {1} \
-optionalEnabled True \
-fullMesh False \
-valueList {{0.0.0.0}} \
-stepValue {0.0.0.0} \
-fixedBits {0.0.0.0} \
- -fieldValue {1.1.1.1} \
+ -fieldValue $srcIp \
-auto False \
-randomMask {0.0.0.0} \
-trackingEnabled False \
@@ -2069,14 +2069,14 @@ proc startRfc2544Test { testSpec trafficSpec } {
#
set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.dstIp-28"
ixNet setMultiAttrs $sg_field \
- -singleValue {90.90.90.90} \
+ -singleValue $dstIp \
-seed {1} \
-optionalEnabled True \
-fullMesh False \
-valueList {{0.0.0.0}} \
-stepValue {0.0.0.0} \
-fixedBits {0.0.0.0} \
- -fieldValue {90.90.90.90} \
+ -fieldValue $dstIp \
-auto False \
-randomMask {0.0.0.0} \
-trackingEnabled False \
@@ -3681,7 +3681,7 @@ proc startRfc2544Test { testSpec trafficSpec } {
#
set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.srcIp-27"
ixNet setMultiAttrs $sg_field \
- -singleValue {1.1.1.1} \
+ -singleValue $srcIp \
-seed {1} \
-optionalEnabled True \
-fullMesh False \
@@ -3704,14 +3704,14 @@ proc startRfc2544Test { testSpec trafficSpec } {
#
set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.dstIp-28"
ixNet setMultiAttrs $sg_field \
- -singleValue {90.90.90.90} \
+ -singleValue $dstIp \
-seed {1} \
-optionalEnabled True \
-fullMesh False \
-valueList {{0.0.0.0}} \
-stepValue {0.0.0.0} \
-fixedBits {0.0.0.0} \
- -fieldValue {90.90.90.90} \
+ -fieldValue $dstIp \
-auto False \
-randomMask {0.0.0.0} \
-trackingEnabled False \
diff --git a/vnfs/qemu/qemu.py b/vnfs/qemu/qemu.py
index 338ca771..2e2c63df 100644
--- a/vnfs/qemu/qemu.py
+++ b/vnfs/qemu/qemu.py
@@ -41,13 +41,7 @@ class IVnfQemu(IVnf):
def __init__(self):
"""
- :param timeout: Time to wait for login prompt. If set to
- 0 do not wait.
- :param number: Number of QEMU instance, used when multiple QEMU
- instances are started at once.
- :param args: Arguments to pass to QEMU.
-
- :returns: None
+ Initialisation function.
"""
super(IVnfQemu, self).__init__()
self._logger = logging.getLogger(__name__)
@@ -67,9 +61,6 @@ class IVnfQemu(IVnf):
'-cpu', 'host',
'-drive', 'if=scsi,file=' +
S.getValue('GUEST_IMAGE')[self._number],
- '-drive',
- 'if=scsi,file=fat:rw:%s,snapshot=off' %
- S.getValue('GUEST_SHARE_DIR')[self._number],
'-boot', 'c', '--enable-kvm',
'-monitor', 'unix:%s,server,nowait' % self._monitor,
'-object',
@@ -104,7 +95,8 @@ class IVnfQemu(IVnf):
Start QEMU instance, login and prepare for commands.
"""
super(IVnfQemu, self).start()
- self._affinitize()
+ if S.getValue('VNF_AFFINITIZATION_ON'):
+ self._affinitize()
if self._timeout:
self._login()
diff --git a/vnfs/qemu/qemu_dpdk.py b/vnfs/qemu/qemu_dpdk.py
index 0b8f90a0..02d720f3 100644
--- a/vnfs/qemu/qemu_dpdk.py
+++ b/vnfs/qemu/qemu_dpdk.py
@@ -25,16 +25,13 @@ class IVnfQemuDpdk(IVnfQemu):
def __init__(self):
"""
- :param timeout: Time to wait for login prompt. If set to
- 0 do not wait.
- :param number: Number of QEMU instance, used when multiple QEMU
- instances are started at once.
- :param args: Arguments to pass to QEMU.
-
- :returns: None
+ Initialisation function.
"""
super(IVnfQemuDpdk, self).__init__()
- self._cmd += []
+ self._cmd += ['-drive',
+ 'if=scsi,file=fat:rw:%s,snapshot=off' %
+ S.getValue('GUEST_SHARE_DIR')[self._number],
+ ]
def _modify_dpdk_makefile(self):
"""
diff --git a/vnfs/qemu/qemu_virtio_net.py b/vnfs/qemu/qemu_virtio_net.py
new file mode 100644
index 00000000..7de5ea1c
--- /dev/null
+++ b/vnfs/qemu/qemu_virtio_net.py
@@ -0,0 +1,115 @@
+# Copyright 2016 Intel Corporation.
+#
+# 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.
+
+"""Automation of QEMU hypervisor for launching virtio-net enabled guests.
+"""
+
+import logging
+from vnfs.qemu.qemu import IVnfQemu
+from conf import settings as S
+from conf import get_test_param
+from tools import tasks
+
+class QemuVirtioNet(IVnfQemu):
+ """
+ Control an instance of QEMU with virtio-net guest communication.
+ """
+
+ def __init__(self):
+ """
+ Initialisation function.
+ """
+ super(QemuVirtioNet, self).__init__()
+ self._logger = logging.getLogger(__name__)
+
+ # insert vanilla ovs specific modules
+ tasks.run_task(['sudo', 'modprobe', 'vhost_net'], self._logger,
+ 'Loading vhost_net module...', True)
+
+ # calculate indexes of guest devices (e.g. charx, dpdkvhostuserx)
+ i = self._number * 2
+ if1 = str(i)
+ if2 = str(i + 1)
+ self._net1 = S.getValue('VANILLA_NIC1_NAME')[self._number]
+ self._net2 = S.getValue('VANILLA_NIC2_NAME')[self._number]
+
+ self._cmd += ['-netdev',
+ 'type=tap,id=' + self._net1 +
+ ',script=no,downscript=no,' +
+ 'ifname=tap' + if1 + ',vhost=on',
+ '-device',
+ 'virtio-net-pci,mac=' +
+ S.getValue('GUEST_NET1_MAC')[self._number] +
+ ',netdev=' + self._net1 + ',csum=off,gso=off,' +
+ 'guest_tso4=off,guest_tso6=off,guest_ecn=off',
+ '-netdev',
+ 'type=tap,id=' + self._net2 +
+ ',script=no,downscript=no,' +
+ 'ifname=tap' + if2 + ',vhost=on',
+ '-device',
+ 'virtio-net-pci,mac=' +
+ S.getValue('GUEST_NET2_MAC')[self._number] +
+ ',netdev=' + self._net2 + ',csum=off,gso=off,' +
+ 'guest_tso4=off,guest_tso6=off,guest_ecn=off',
+ ]
+
+ # helper functions
+
+ def _config_guest_loopback(self):
+ """
+ Configure VM to perform forwarding between NICs
+ """
+
+ # Disable services (F16)
+ self.execute_and_wait('systemctl stop iptables.service')
+ self.execute_and_wait('systemctl stop irqbalance.service')
+
+ nic1_name = get_test_param('vanilla_nic1_name', self._net1)
+ self.execute('ifconfig ' + nic1_name + ' ' +
+ S.getValue('VANILLA_NIC1_IP_CIDR')[self._number])
+
+ nic2_name = get_test_param('vanilla_nic2_name', self._net2)
+ self.execute('ifconfig ' + nic2_name + ' ' +
+ S.getValue('VANILLA_NIC2_IP_CIDR')[self._number])
+
+ # configure linux bridge
+ self.execute('brctl addbr br0')
+ self.execute('brctl addif br0 ' + self._net1 + ' ' + self._net2)
+ self.execute('ifconfig br0 ' +
+ S.getValue('VANILLA_BRIDGE_IP')[self._number])
+
+ # Add the arp entries for the IXIA ports and the bridge you are using.
+ # Use command line values if provided.
+ trafficgen_mac = get_test_param('vanilla_tgen_port1_mac',
+ S.getValue('VANILLA_TGEN_PORT1_MAC'))
+ trafficgen_ip = get_test_param('vanilla_tgen_port1_ip',
+ S.getValue('VANILLA_TGEN_PORT1_IP'))
+
+ self.execute('arp -s ' + trafficgen_ip + ' ' + trafficgen_mac)
+
+ trafficgen_mac = get_test_param('vanilla_tgen_port2_mac',
+ S.getValue('VANILLA_TGEN_PORT2_MAC'))
+ trafficgen_ip = get_test_param('vanilla_tgen_port2_ip',
+ S.getValue('VANILLA_TGEN_PORT2_IP'))
+
+ self.execute('arp -s ' + trafficgen_ip + ' ' + trafficgen_mac)
+
+ # Enable forwarding
+ self.execute('sysctl -w net.ipv4.ip_forward=1')
+
+ # Controls source route verification
+ # 0 means no source validation
+ self.execute('sysctl -w net.ipv4.conf.all.rp_filter=0')
+ self.execute('sysctl -w net.ipv4.conf.' + self._net1 + '.rp_filter=0')
+ self.execute('sysctl -w net.ipv4.conf.' + self._net2 + '.rp_filter=0')
diff --git a/vnfs/vnf/vnf.py b/vnfs/vnf/vnf.py
index f8d2df90..483faf38 100644
--- a/vnfs/vnf/vnf.py
+++ b/vnfs/vnf/vnf.py
@@ -121,3 +121,13 @@ class IVnf(tasks.Process):
"""
self.execute(cmd)
self.wait(prompt=prompt, timeout=timeout)
+
+ @staticmethod
+ def reset_vnf_counter():
+ """
+ Reset internal VNF counters
+
+ This method is static
+ """
+ IVnf._number_vnfs = 0
+
diff --git a/vswitches/ovs_dpdk_vhost.py b/vswitches/ovs_dpdk_vhost.py
index 1a53bd6d..874cc97b 100644
--- a/vswitches/ovs_dpdk_vhost.py
+++ b/vswitches/ovs_dpdk_vhost.py
@@ -158,6 +158,12 @@ class OvsDpdkVhost(IVSwitch):
bridge = self._bridges[switch_name]
bridge.del_flow(flow)
+ def dump_flows(self, switch_name):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ bridge.dump_flows()
+
@staticmethod
def _get_port_count(bridge, param):
"""Returns the number of ports having a certain parameter
diff --git a/vswitches/ovs_vanilla.py b/vswitches/ovs_vanilla.py
index a7d4d206..6716401d 100644
--- a/vswitches/ovs_vanilla.py
+++ b/vswitches/ovs_vanilla.py
@@ -20,7 +20,9 @@ from conf import settings
from vswitches.vswitch import IVSwitch
from src.ovs import VSwitchd, OFBridge
from tools.module_manager import ModuleManager, KernelModuleInsertMode
+from tools import tasks
+_LOGGER = logging.getLogger(__name__)
VSWITCHD_CONST_ARGS = ['--', '--log-file']
class OvsVanilla(IVSwitch):
@@ -36,6 +38,7 @@ class OvsVanilla(IVSwitch):
_logger = logging.getLogger()
_ports = settings.getValue('VSWITCH_VANILLA_PHY_PORT_NAMES')
_current_id = 0
+ _vport_id = 0
def __init__(self):
#vswitchd_args = VSWITCHD_CONST_ARGS
@@ -62,9 +65,18 @@ class OvsVanilla(IVSwitch):
Kills ovsdb and vswitchd and removes kernel modules.
"""
+ # remove all tap interfaces
+ for i in range(self._vport_id):
+ tapx = 'tap' + str(i)
+ tasks.run_task(['sudo', 'ip', 'tuntap', 'del',
+ tapx, 'mode', 'tap'],
+ _LOGGER, 'Deleting ' + tapx, False)
+ self._vport_id = 0
+
self._vswitchd.kill()
self._module_manager.remove_modules()
+
def add_switch(self, switch_name):
"""See IVswitch for general description
"""
@@ -94,16 +106,47 @@ class OvsVanilla(IVSwitch):
"defined in config!")
raise
+ if not self._ports[self._current_id]:
+ self._logger.error("VSWITCH_VANILLA_PHY_PORT_NAMES not set")
+ raise ValueError("Invalid VSWITCH_VANILLA_PHY_PORT_NAMES")
+
bridge = self._bridges[switch_name]
port_name = self._ports[self._current_id]
params = []
+
+ # For PVP only
+ tasks.run_task(['sudo', 'ifconfig', port_name, '0'],
+ _LOGGER, 'Remove IP', False)
+
of_port = bridge.add_port(port_name, params)
self._current_id += 1
return (port_name, of_port)
def add_vport(self, switch_name):
- """See IVswitch for general description"""
- raise NotImplementedError("Not implemented for Vanilla OVS.")
+ """
+ Method adds virtual port into OVS vanilla
+
+ See IVswitch for general description
+ """
+ # Create tap devices for the VM
+ tap_name = 'tap' + str(self._vport_id)
+ self._vport_id += 1
+
+ tasks.run_task(['sudo', 'ip', 'tuntap', 'del',
+ tap_name, 'mode', 'tap'],
+ _LOGGER, 'Creating tap device...', False)
+
+ tasks.run_task(['sudo', 'ip', 'tuntap', 'add',
+ tap_name, 'mode', 'tap'],
+ _LOGGER, 'Creating tap device...', False)
+
+ tasks.run_task(['sudo', 'ifconfig', tap_name, '0'],
+ _LOGGER, 'Bring up ' + tap_name, False)
+
+ bridge = self._bridges[switch_name]
+ of_port = bridge.add_port(tap_name, [])
+ return (tap_name, of_port)
+
def get_ports(self, switch_name):
"""See IVswitch for general description
@@ -130,3 +173,9 @@ class OvsVanilla(IVSwitch):
flow = flow or {}
bridge = self._bridges[switch_name]
bridge.del_flow(flow)
+
+ def dump_flows(self, switch_name):
+ """See IVswitch for general description
+ """
+ bridge = self._bridges[switch_name]
+ bridge.dump_flows()
diff --git a/vswitches/vswitch.py b/vswitches/vswitch.py
index 713974ae..dbf3e7d5 100644
--- a/vswitches/vswitch.py
+++ b/vswitches/vswitch.py
@@ -112,3 +112,10 @@ class IVSwitch(object):
For flow==None, all flows are deleted
"""
raise NotImplementedError()
+
+ def dump_flows(self, switch_name):
+ """Dump flows from the logical switch
+
+ :param switch_name: The switch on which to operate
+ """
+ raise NotImplementedError()