summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/component_factory.py3
-rw-r--r--core/vswitch_controller_ptunp.py238
2 files changed, 241 insertions, 0 deletions
diff --git a/core/component_factory.py b/core/component_factory.py
index a91872e2..258b7232 100644
--- a/core/component_factory.py
+++ b/core/component_factory.py
@@ -21,6 +21,7 @@ from core.vswitch_controller_p2p import VswitchControllerP2P
from core.vswitch_controller_pvp import VswitchControllerPVP
from core.vswitch_controller_pvvp import VswitchControllerPVVP
from core.vswitch_controller_op2p import VswitchControllerOP2P
+from core.vswitch_controller_ptunp import VswitchControllerPtunP
from core.vnf_controller import VnfController
from core.pktfwd_controller import PktFwdController
from tools.load_gen.stress.stress import Stress
@@ -73,6 +74,8 @@ def create_vswitch(deployment_scenario, vswitch_class, traffic,
return VswitchControllerPVVP(vswitch_class, traffic)
elif deployment_scenario.find("op2p") >= 0:
return VswitchControllerOP2P(vswitch_class, traffic, tunnel_operation)
+ elif deployment_scenario.find("ptunp") >= 0:
+ return VswitchControllerPtunP(vswitch_class, traffic)
elif deployment_scenario.find("clean") >= 0:
return VswitchControllerClean(vswitch_class, traffic)
diff --git a/core/vswitch_controller_ptunp.py b/core/vswitch_controller_ptunp.py
new file mode 100644
index 00000000..27d26789
--- /dev/null
+++ b/core/vswitch_controller_ptunp.py
@@ -0,0 +1,238 @@
+# Copyright 2015-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.
+
+"""VSwitch controller for Physical to VxLAN Tunnel Endpoint to Physical
+ deployment with mod operation.
+"""
+
+import logging
+from netaddr import EUI, IPNetwork, mac_unix
+
+from core.vswitch_controller import IVswitchController
+from vswitches.utils import add_ports_to_flow
+from conf import settings
+from tools import tasks
+
+_FLOW_TEMPLATE = {
+ 'idle_timeout': '0'
+}
+
+class VswitchControllerPtunP(IVswitchController):
+ """VSwitch controller for VxLAN ptunp deployment scenario.
+ The deployment scenario is to test VxLAN tunneling feature without using an
+ overlay ingress traffic. The VxLAN encap and decap performed in the virtual
+ switch in each direction.
+
+ Attributes:
+ _vswitch_class: The vSwitch class to be used.
+ _vswitch: The vSwitch object controlled by this controller
+ _deployment_scenario: A string describing the scenario to set-up in the
+ constructor.
+ """
+ def __init__(self, vswitch_class, traffic):
+ """Initializes up the prerequisites for the ptunp deployment scenario.
+
+ :vswitch_class: the vSwitch class to be used.
+ """
+ self._logger = logging.getLogger(__name__)
+ self._vswitch_class = vswitch_class
+ self._vswitch = vswitch_class()
+ self._deployment_scenario = "ptunp"
+ self._traffic = traffic.copy()
+ self.bridge_phy1 = settings.getValue('TUNNEL_EXTERNAL_BRIDGE1')
+ self.bridge_phy2 = settings.getValue('TUNNEL_EXTERNAL_BRIDGE2')
+ self.bridge_mod1 = settings.getValue('TUNNEL_MODIFY_BRIDGE1')
+ self.bridge_mod2 = settings.getValue('TUNNEL_MODIFY_BRIDGE2')
+ self.br_mod_mac1 = settings.getValue('TUNNEL_MODIFY_BRIDGE_MAC1')
+ self.br_mod_mac2 = settings.getValue('TUNNEL_MODIFY_BRIDGE_MAC2')
+ self.br_mod_ip1 = settings.getValue('TUNNEL_MODIFY_BRIDGE_IP1')
+ self.br_mod_ip2 = settings.getValue('TUNNEL_MODIFY_BRIDGE_IP2')
+ self.tunnel_type = settings.getValue('TUNNEL_TYPE')
+ self._logger.debug('Creation using ' + str(self._vswitch_class))
+
+ def setup(self):
+ """ Sets up the switch for VxLAN overlay PTUNP (tunnel encap or decap)
+ """
+ self._logger.debug('Setting up phy-tun-phy tunneling scenario')
+ if self.tunnel_type is 'vxlan':
+ self._setup_vxlan_encap_decap()
+ else:
+ self._logger.error("Only VxLAN is supported for now")
+ raise NotImplementedError
+
+ def _setup_vxlan_encap_decap(self):
+ """ Sets up switches for VxLAN overlay P-TUN-P test.
+
+ Create 2 bridges br-phy1 and br-phy2 (The bridge to connect
+ physical ports. Two more bridges br-mod1 and br-mod2 to mangle
+ and redirect the packets from one tunnel port to other.
+ """
+ self._logger.debug('Setup using ' + str(self._vswitch_class))
+ try:
+ self._vswitch.start()
+ self._vswitch.add_switch(self.bridge_phy1)
+ self._vswitch.add_switch(self.bridge_phy2)
+ self._vswitch.add_switch(self.bridge_mod1,
+ params=["other_config:hwaddr=" +
+ self.br_mod_mac1
+ ])
+ self._vswitch.add_switch(self.bridge_mod2,
+ params=["other_config:hwaddr=" +
+ self.br_mod_mac2
+ ])
+
+ tasks.run_task(['sudo', 'iptables', '-F'],
+ self._logger, 'Clean ip tables',
+ False)
+ tasks.run_task(['sudo', 'ip', 'addr', 'add',
+ self.br_mod_ip1, 'dev', self.bridge_mod1],
+ self._logger, 'Assign ' +
+ self.br_mod_ip1 + ' to ' + self.bridge_mod1,
+ False)
+ tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', self.bridge_mod1, 'up'],
+ self._logger, 'Bring up ' + self.bridge_mod1, False)
+
+ tasks.run_task(['sudo', 'ip', 'addr', 'add',
+ self.br_mod_ip2, 'dev', self.bridge_mod2],
+ self._logger, 'Assign ' +
+ self.br_mod_ip2 + ' to ' + self.bridge_mod2,
+ False)
+ tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', self.bridge_mod2, 'up'],
+ self._logger, 'Bring up ' + self.bridge_mod2, False)
+
+ tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', self.bridge_phy1, 'up'],
+ self._logger, 'Bring up ' + self.bridge_phy1, False)
+ tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', self.bridge_phy2, 'up'],
+ self._logger, 'Bring up ' + self.bridge_phy2, False)
+ self._vswitch.add_route(self.bridge_phy1, self.br_mod_ip1, self.bridge_mod1)
+ self._vswitch.add_route(self.bridge_phy2, self.br_mod_ip2, self.bridge_mod2)
+
+ # Create tunnel ip and mac from the bridge ips
+ vxlan_local_ip1 = str(IPNetwork(self.br_mod_ip1).ip)
+ vxlan_local_ip2 = str(IPNetwork(self.br_mod_ip2).ip)
+ vxlan_rem_ip1 = str(IPNetwork(self.br_mod_ip1).ip + 1)
+ vxlan_rem_ip2 = str(IPNetwork(self.br_mod_ip2).ip + 1)
+ vxlan_rem_mac1 = EUI(int(EUI(self.br_mod_mac1)) + 1)
+ vxlan_rem_mac1.dialect = mac_unix
+ vxlan_rem_mac2 = EUI(int(EUI(self.br_mod_mac2)) + 1)
+ vxlan_rem_mac2.dialect = mac_unix
+ self._vswitch.set_tunnel_arp(vxlan_local_ip1, self.br_mod_mac1,
+ self.bridge_phy1)
+ self._vswitch.set_tunnel_arp(vxlan_local_ip2, self.br_mod_mac2,
+ self.bridge_phy2)
+ self._vswitch.set_tunnel_arp(vxlan_rem_ip1, str(vxlan_rem_mac1),
+ self.bridge_mod1)
+ self._vswitch.set_tunnel_arp(vxlan_rem_ip2, str(vxlan_rem_mac2),
+ self.bridge_mod2)
+
+ # Lets add the ports to bridges
+ (_, phy1_number) = self._vswitch.add_phy_port(self.bridge_phy1)
+ (_, phy2_number) = self._vswitch.add_phy_port(self.bridge_phy2)
+ vxlan_vni = 'options:key=' + settings.getValue('VXLAN_VNI')
+ (_, phy3_number) = self._vswitch.add_tunnel_port(self.bridge_phy1,
+ vxlan_rem_ip1,
+ "vxlan",
+ params=[vxlan_vni])
+ (_, phy4_number) = self._vswitch.add_tunnel_port(self.bridge_phy2,
+ vxlan_rem_ip2,
+ "vxlan",
+ params=[vxlan_vni])
+ [(_, phy5_number), (_, phy6_number)] = \
+ self._vswitch.add_veth_pair_port(self.bridge_mod1, self.bridge_mod2)
+
+ # Set up flows for the switches
+ self._vswitch.del_flow(self.bridge_phy1)
+ self._vswitch.del_flow(self.bridge_phy2)
+ self._vswitch.del_flow(self.bridge_mod1)
+ self._vswitch.del_flow(self.bridge_mod2)
+ flow = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number,
+ phy3_number)
+ self._vswitch.add_flow(self.bridge_phy1, flow)
+ flow = add_ports_to_flow(_FLOW_TEMPLATE, phy3_number,
+ phy1_number)
+ self._vswitch.add_flow(self.bridge_phy1, flow)
+
+ flow = add_ports_to_flow(_FLOW_TEMPLATE, phy2_number,
+ phy4_number)
+ self._vswitch.add_flow(self.bridge_phy2, flow)
+ flow = add_ports_to_flow(_FLOW_TEMPLATE, phy4_number,
+ phy2_number)
+ self._vswitch.add_flow(self.bridge_phy2, flow)
+ flow = add_ports_to_flow(_FLOW_TEMPLATE, phy5_number,
+ 'LOCAL')
+ self._vswitch.add_flow(self.bridge_mod1, flow)
+ mod_flow_template = _FLOW_TEMPLATE.copy()
+ mod_flow_template.update({'ip':'',
+ 'actions':
+ ['mod_dl_src:' + str(vxlan_rem_mac2),
+ 'mod_dl_dst:' + self.br_mod_mac2,
+ 'mod_nw_src:' + vxlan_rem_ip2,
+ 'mod_nw_dst:' + vxlan_local_ip2
+ ]
+ })
+ flow = add_ports_to_flow(mod_flow_template, 'LOCAL', phy5_number)
+ self._vswitch.add_flow(self.bridge_mod1, flow)
+ flow = add_ports_to_flow(_FLOW_TEMPLATE, phy6_number,
+ 'LOCAL')
+ self._vswitch.add_flow(self.bridge_mod2, flow)
+ mod_flow_template = _FLOW_TEMPLATE.copy()
+ mod_flow_template.update({'ip':'',
+ 'actions':
+ ['mod_dl_src:' + str(vxlan_rem_mac1),
+ 'mod_dl_dst:' + self.br_mod_mac1,
+ 'mod_nw_src:' + vxlan_rem_ip1,
+ 'mod_nw_dst:' + vxlan_local_ip1]
+ })
+ flow = add_ports_to_flow(mod_flow_template, 'LOCAL', phy6_number)
+ self._vswitch.add_flow(self.bridge_mod2, flow)
+
+ except:
+ self._vswitch.stop()
+ raise
+
+ def stop(self):
+ """Tears down the switch created in setup().
+ """
+ self._logger.debug('Stop using ' + str(self._vswitch_class))
+ self._vswitch.stop()
+
+ def __enter__(self):
+ self.setup()
+
+ def __exit__(self, type_, value, traceback):
+ self.stop()
+
+ def get_vswitch(self):
+ """See IVswitchController for description
+ """
+ return self._vswitch
+
+ def get_ports_info(self):
+ """See IVswitchController for description
+ """
+ self._logger.debug('get_ports_info using ' + str(self._vswitch_class))
+ ports = self._vswitch.get_ports(self.bridge_phy1) +\
+ self._vswitch.get_ports(self.bridge_mod1) +\
+ self._vswitch.get_ports(self.bridge_phy2) +\
+ self._vswitch.get_ports(self.bridge_mod2)
+ return ports
+
+ def dump_vswitch_flows(self):
+ """See IVswitchController for description
+ """
+ self._logger.debug('dump_flows using ' + str(self._vswitch_class))
+ self._vswitch.dump_flows(self.bridge_phy1)
+ self._vswitch.dump_flows(self.bridge_mod1)
+ self._vswitch.dump_flows(self.bridge_phy2)
+ self._vswitch.dump_flows(self.bridge_mod2)