-"""Openstack manage component of PG Sandman.
-
-.. module:: manage
- :synopsis: Module containing the OpenstackManage class.
-.. moduleauthor: PG Sandman
-
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# 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.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
import threading
import uuid
import chain_api
import json
import random
-from emuvim.api.openstack.resources import Net, Port
+from emuvim.api.openstack.resources.net import Net
+from emuvim.api.openstack.resources.port import Port
from mininet.node import OVSSwitch, RemoteController, Node
self.ip = ip
self.port = port
self._net = None
- # to keep track which src_vnf(input port on the switch) handles a load balancer
+ # to keep track which src_vnf(input port on the switch) handles a load
+ # balancer
self.lb_flow_cookies = dict()
self.chain_flow_cookies = dict()
# debug and to maintain
self.flow_groups = dict()
- # we want one global chain api. this should not be datacenter dependent!
+ # we want one global chain api. this should not be datacenter
+ # dependent!
self.chain = chain_api.ChainApi(ip, port, self)
self.thread = threading.Thread(target=self.chain._start_flask, args=())
- self.thread.daemon = True
self.thread.name = self.chain.__class__
self.thread.start()
self.floating_intf = None
self.floating_links = dict()
+ def stop(self):
+ self.chain.stop()
+ self.thread.join()
+
@property
def net(self):
return self._net
def net(self, value):
if self._net is None:
self._net = value
+ # create default networks
self.init_floating_network()
self._net = value
- def init_floating_network(self):
+ def init_floating_network(self, name="default"):
"""
Initialize the floating network component for the emulator.
Will not do anything if already initialized.
"""
if self.net is not None and self.floating_switch is None:
# create a floating network
- fn = self.floating_network = Net("default")
+ fn = self.floating_network = Net(name)
fn.id = str(uuid.uuid4())
fn.set_cidr(self.floating_netmask)
# create a port for the host
port = Port("root-port")
- #port.id = str(uuid.uuid4())
+ # port.id = str(uuid.uuid4())
port.net_name = fn.name
# get next free ip
# floating ip network setup
# wierd way of getting a datacenter object
first_dc = self.net.dcs.values()[0]
- # set a dpid for the switch. for this we have to get the id of the next possible dc
- self.floating_switch = self.net.addSwitch("fs1", dpid=hex(first_dc._get_next_dc_dpid())[2:])
+ # set a dpid for the switch. for this we have to get the id of the
+ # next possible dc
+ self.floating_switch = self.net.addSwitch(
+ "fs1", dpid=hex(first_dc._get_next_dc_dpid())[2:])
# this is the interface appearing on the physical host
self.floating_root = Node('root', inNamespace=False)
self.net.hosts.append(self.floating_root)
self.net.nameToNode['root'] = self.floating_root
- self.floating_intf = self.net.addLink(self.floating_root, self.floating_switch).intf1
+ self.floating_intf = self.net.addLink(
+ self.floating_root, self.floating_switch).intf1
self.floating_root.setIP(root_ip, intf=self.floating_intf)
- self.floating_nodes[(self.floating_root.name, root_ip)] = self.floating_root
-
+ self.floating_nodes[(self.floating_root.name,
+ root_ip)] = self.floating_root
def stop_floating_network(self):
self._net = None
vnf_dst_interface = kwargs.get('vnf_dst_interface')
layer2 = kwargs.get('layer2', True)
match = kwargs.get('match')
- flow = (vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface)
+ flow = (vnf_src_name, vnf_src_interface,
+ vnf_dst_name, vnf_dst_interface)
if flow in self.chain_flow_cookies:
- raise Exception("There is already a chain at the specified src/dst pair!")
- # set up a layer 2 chain, this allows multiple chains for the same interface
+ raise Exception(
+ "There is already a chain at the specified src/dst pair!")
+ # set up a layer 2 chain, this allows multiple chains for the same
+ # interface
src_node = self.net.getNodeByName(vnf_src_name)
dst_node = self.net.getNodeByName(vnf_dst_name)
dst_intf = dst_node.intf(vnf_dst_interface)
if layer2:
- switch, inport = self._get_connected_switch_data(vnf_src_name, vnf_src_interface)
- self.setup_arp_reply_at(switch, inport, dst_intf.IP(), dst_intf.MAC())
+ switch, inport = self._get_connected_switch_data(
+ vnf_src_name, vnf_src_interface)
+ self.setup_arp_reply_at(
+ switch, inport, dst_intf.IP(), dst_intf.MAC())
if isinstance(match, str):
match += ",dl_dst=%s" % dst_intf.MAC()
else:
cookie = kwargs.get('cookie', self.get_cookie())
self.cookies.add(cookie)
- c = self.net.setChain(
+ self.net.setChain(
vnf_src_name, vnf_dst_name,
vnf_src_interface=vnf_src_interface,
vnf_dst_interface=vnf_dst_interface,
cookie=cookie,
path=kwargs.get('path'))
- # to keep this logic seperate of the core son-emu do the housekeeping here
+ # to keep this logic seperate of the core son-emu do the
+ # housekeeping here
data = dict()
data["src_vnf"] = vnf_src_name
data["src_intf"] = vnf_src_interface
vnf_dst_interface)[0]
# add route to dst ip to this interface
- # this might block on containers that are still setting up, so start a new thread
+ # this might block on containers that are still setting up, so
+ # start a new thread
if not kwargs.get('no_route'):
# son_emu does not like concurrent commands for a container so we need to lock this if multiple chains
# on the same interface are created
- src_node.setHostRoute(dst_node.intf(vnf_dst_interface).IP(), vnf_src_interface)
+ src_node.setHostRoute(dst_node.intf(
+ vnf_dst_interface).IP(), vnf_src_interface)
try:
- son_emu_data = json.loads(self.get_son_emu_chain_data(vnf_src_name))
- except:
+ son_emu_data = json.loads(
+ self.get_son_emu_chain_data(vnf_src_name))
+ except BaseException:
son_emu_data = dict()
if "son_emu_data" not in son_emu_data:
son_emu_data["son_emu_data"] = dict()
son_emu_data["son_emu_data"]["interfaces"] = dict()
if vnf_src_interface not in son_emu_data["son_emu_data"]["interfaces"]:
son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface] = list()
- son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface].append(dst_intf.IP())
+ son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface].append(
+ dst_intf.IP())
self.set_son_emu_chain_data(vnf_src_name, son_emu_data)
:param data: Raw data to store on the node.
:type data: ``str``
"""
- self.net.getNodeByName(vnf_name).cmd("echo \'%s\' > /tmp/son_emu_data.json" % json.dumps(data))
+ self.net.getNodeByName(vnf_name).cmd(
+ "echo \'%s\' > /tmp/son_emu_data.json" % json.dumps(data))
ip_list = []
for intf in data['son_emu_data']['interfaces'].values():
ip_list.extend(intf)
- self.net.getNodeByName(vnf_name).cmd("echo \'%s\' > /tmp/son_emu_data" % "\n".join(ip_list))
+ self.net.getNodeByName(vnf_name).cmd(
+ "echo \'%s\' > /tmp/son_emu_data" % "\n".join(ip_list))
def get_son_emu_chain_data(self, vnf_name):
"""
:return: raw data stored on the node
:rtype: ``str``
"""
- return self.net.getNodeByName(vnf_name).cmd("cat /tmp/son_emu_data.json")
+ return self.net.getNodeByName(vnf_name).cmd(
+ "cat /tmp/son_emu_data.json")
def _get_connected_switch_data(self, vnf_name, vnf_interface):
"""
link_dict = self.net.DCNetwork_graph[vnf_name][connected_sw]
for link in link_dict:
if (link_dict[link]['src_port_id'] == vnf_interface or
- link_dict[link][
- 'src_port_name'] == vnf_interface):
+ link_dict[link][
+ 'src_port_name'] == vnf_interface):
# found the right link and connected switch
src_sw = connected_sw
src_sw_inport_nr = link_dict[link]['dst_port_nr']
:return: path, src_sw, dst_sw
:rtype: ``list``, ``str``, ``str``
"""
- # modified version of the _chainAddFlow from emuvim.dcemulator.net._chainAddFlow
+ # modified version of the _chainAddFlow from
+ # emuvim.dcemulator.net._chainAddFlow
src_sw = None
dst_sw = None
logging.debug("Find shortest path from vnf %s to %s",
link_dict = self.net.DCNetwork_graph[src_vnf][connected_sw]
for link in link_dict:
if (link_dict[link]['src_port_id'] == src_vnf_intf or
- link_dict[link][
- 'src_port_name'] == src_vnf_intf):
+ link_dict[link][
+ 'src_port_name'] == src_vnf_intf):
# found the right link and connected switch
src_sw = connected_sw
break
link_dict = self.net.DCNetwork_graph[connected_sw][dst_vnf]
for link in link_dict:
if link_dict[link]['dst_port_id'] == dst_vnf_intf or \
- link_dict[link][
- 'dst_port_name'] == dst_vnf_intf:
+ link_dict[link][
+ 'dst_port_name'] == dst_vnf_intf:
# found the right link and connected
dst_sw = connected_sw
break
# returns the first found shortest path
# if all shortest paths are wanted, use: all_shortest_paths
path = nx.shortest_path(self.net.DCNetwork_graph, src_sw, dst_sw)
- except:
+ except BaseException:
logging.exception("No path could be found between {0} and {1} using src_sw={2} and dst_sw={3}".format(
src_vnf, dst_vnf, src_sw, dst_sw))
logging.debug("Graph nodes: %r" % self.net.DCNetwork_graph.nodes())
logging.debug("Graph edges: %r" % self.net.DCNetwork_graph.edges())
for e, v in self.net.DCNetwork_graph.edges():
logging.debug("%r" % self.net.DCNetwork_graph[e][v])
- return "No path could be found between {0} and {1}".format(src_vnf, dst_vnf)
+ return "No path could be found between {0} and {1}".format(
+ src_vnf, dst_vnf)
- logging.info("Shortest path between {0} and {1}: {2}".format(src_vnf, dst_vnf, path))
+ logging.info("Shortest path between {0} and {1}: {2}".format(
+ src_vnf, dst_vnf, path))
return path, src_sw, dst_sw
def add_loadbalancer(self, src_vnf_name, src_vnf_interface, lb_data):
custom_paths = lb_data.get('path', dict())
dest_vnf_outport_nrs = list()
- logging.debug("Call to add_loadbalancer at %s intfs:%s" % (src_vnf_name, src_vnf_interface))
+ logging.debug("Call to add_loadbalancer at %s intfs:%s" %
+ (src_vnf_name, src_vnf_interface))
if not self.check_vnf_intf_pair(src_vnf_name, src_vnf_interface):
- raise Exception(u"Source VNF %s or intfs %s does not exist" % (src_vnf_name, src_vnf_interface))
+ raise Exception(u"Source VNF %s or intfs %s does not exist" % (
+ src_vnf_name, src_vnf_interface))
- # find the switch belonging to the source interface, as well as the inport nr
+ # find the switch belonging to the source interface, as well as the
+ # inport nr
for connected_sw in net.DCNetwork_graph.neighbors(src_vnf_name):
link_dict = net.DCNetwork_graph[src_vnf_name][connected_sw]
for link in link_dict:
link_dict = net.DCNetwork_graph[vnf_name][connected_sw]
for link in link_dict:
if link_dict[link]['src_port_name'] == dest_intfs_mapping[vnf_name]:
- dest_vnf_outport_nrs.append(int(link_dict[link]['dst_port_nr']))
+ dest_vnf_outport_nrs.append(
+ int(link_dict[link]['dst_port_nr']))
# get first switch
if (src_vnf_name, src_vnf_interface) not in self.lb_flow_cookies:
self.lb_flow_cookies[(src_vnf_name, src_vnf_interface)] = list()
- src_intf = None
src_ip = None
src_mac = None
for intf in net[src_vnf_name].intfs.values():
if intf.name == src_vnf_interface:
src_mac = intf.mac
src_ip = intf.ip
- src_intf = intf
# set up paths for each destination vnf individually
index = 0
data["cookie"] = cookie
# lb mac for src -> target connections
- lb_mac = "31:33:70:%02x:%02x:%02x" % (random.randint(0, 255),random.randint(0, 255),random.randint(0, 255))
+ lb_mac = "31:33:70:%02x:%02x:%02x" % (random.randint(
+ 0, 255), random.randint(0, 255), random.randint(0, 255))
# calculate lb ip as src_intf.ip +1
octets = src_ip.split('.')
plus_one = '.'.join(octets)
# set up arp reply as well as add the route to the interface
- self.setup_arp_reply_at(src_sw, src_sw_inport_nr, plus_one, lb_mac, cookie=cookie)
- net.getNodeByName(src_vnf_name).setHostRoute(plus_one, src_vnf_interface)
+ self.setup_arp_reply_at(src_sw, src_sw_inport_nr,
+ plus_one, lb_mac, cookie=cookie)
+ net.getNodeByName(src_vnf_name).setHostRoute(
+ plus_one, src_vnf_interface)
for dst_vnf_name, dst_vnf_interface in dest_intfs_mapping.items():
path, src_sw, dst_sw = self._get_path(src_vnf_name, dst_vnf_name,
if custom_paths is not None and dst_vnf_name in custom_paths:
if dst_vnf_interface in custom_paths[dst_vnf_name]:
path = custom_paths[dst_vnf_name][dst_vnf_interface]
- logging.debug("Taking custom path from %s to %s: %s" % (src_vnf_name, dst_vnf_name, path))
+ logging.debug("Taking custom path from %s to %s: %s" % (
+ src_vnf_name, dst_vnf_name, path))
if not self.check_vnf_intf_pair(dst_vnf_name, dst_vnf_interface):
self.delete_loadbalancer(src_vnf_name, src_vnf_interface)
- raise Exception(u"VNF %s or intfs %s does not exist" % (dst_vnf_name, dst_vnf_interface))
+ raise Exception(u"VNF %s or intfs %s does not exist" %
+ (dst_vnf_name, dst_vnf_interface))
if isinstance(path, dict):
self.delete_loadbalancer(src_vnf_name, src_vnf_interface)
- raise Exception(u"Can not find a valid path. Are you specifying the right interfaces?.")
+ raise Exception(
+ u"Can not find a valid path. Are you specifying the right interfaces?.")
target_mac = "fa:17:00:03:13:37"
target_ip = "0.0.0.0"
current_hop = src_sw
switch_inport_nr = src_sw_inport_nr
- #self.setup_arp_reply_at(src_sw, src_sw_inport_nr, target_ip, target_mac, cookie=cookie)
- net.getNodeByName(dst_vnf_name).setHostRoute(src_ip, dst_vnf_interface)
+ # self.setup_arp_reply_at(src_sw, src_sw_inport_nr, target_ip, target_mac, cookie=cookie)
+ net.getNodeByName(dst_vnf_name).setHostRoute(
+ src_ip, dst_vnf_interface)
# choose free vlan if path contains more than 1 switch
if len(path) > 1:
switch_outport_nr = dst_sw_outport_nr
logging.info("end node reached: {0}".format(dst_vnf_name))
elif not isinstance(next_node, OVSSwitch):
- logging.info("Next node: {0} is not a switch".format(next_hop))
+ logging.info(
+ "Next node: {0} is not a switch".format(next_hop))
return "Next node: {0} is not a switch".format(next_hop)
else:
# take first link between switches by default
index_edge_out = 0
switch_outport_nr = net.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']
- cmd = 'priority=1,in_port=%s,cookie=%s' % (switch_inport_nr, cookie)
- cmd_back = 'priority=1,in_port=%s,cookie=%s' % (switch_outport_nr, cookie)
- # if a vlan is picked, the connection is routed through multiple switches
+ cmd = 'priority=1,in_port=%s,cookie=%s' % (
+ switch_inport_nr, cookie)
+ cmd_back = 'priority=1,in_port=%s,cookie=%s' % (
+ switch_outport_nr, cookie)
+ # if a vlan is picked, the connection is routed through
+ # multiple switches
if vlan is not None:
if path.index(current_hop) == 0: # first node
# flow #index set up
# remove any vlan tags
cmd += ',dl_vlan=%s' % vlan
cmd += ',actions=pop_vlan,output:%s' % switch_outport_nr
- # set up arp replys at the port so the dst nodes know the src
- self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
+ # set up arp replys at the port so the dst nodes know
+ # the src
+ self.setup_arp_reply_at(
+ current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
# reverse route
cmd_back = 'in_port=%s' % switch_outport_nr
cmd += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
cmd_back += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
else:
- cmd += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_outport_nr)
- cmd_back += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_inport_nr)
+ cmd += ',dl_vlan=%s,actions=output:%s' % (
+ vlan, switch_outport_nr)
+ cmd_back += ',dl_vlan=%s,actions=output:%s' % (
+ vlan, switch_inport_nr)
# output the packet at the correct outport
else:
cmd = 'in_port=%s' % src_sw_inport_nr
cmd_back += ',set_field:%s->ip_src' % plus_one
cmd_back += ',output:%s' % src_sw_inport_nr
- self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
+ self.setup_arp_reply_at(
+ current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
# excecute the command on the target switch
logging.debug(cmd)
# advance to next destination
index += 1
- # set up the actual load balancing rule as a multipath on the very first switch
+ # set up the actual load balancing rule as a multipath on the very
+ # first switch
cmd = '"in_port=%s' % src_sw_inport_nr
cmd += ',cookie=%s' % (cookie)
cmd += ',ip'
# load balance modulo n over all dest interfaces
# TODO: in newer openvswitch implementations this should be changed to symmetric_l3l4+udp
# to balance any kind of traffic
- cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(dest_intfs_mapping)
+ cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(
+ dest_intfs_mapping)
# reuse the cookie as table entry as it will be unique
cmd += ',resubmit(, %s)"' % cookie
link_dict = net.DCNetwork_graph[vnf_name][connected_sw]
for link in link_dict:
if link_dict[link]['src_port_name'] == dest_intfs_mapping[vnf_name]:
- dest_vnf_outport_nrs.append(int(link_dict[link]['dst_port_nr']))
+ dest_vnf_outport_nrs.append(
+ int(link_dict[link]['dst_port_nr']))
if len(dest_vnf_outport_nrs) == 0:
- raise Exception("There are no paths specified for the loadbalancer")
+ raise Exception(
+ "There are no paths specified for the loadbalancer")
src_ip = self.floating_intf.IP()
src_mac = self.floating_intf.MAC()
index = 0
cookie = self.get_cookie()
main_cmd = "add-flow -OOpenFlow13"
- floating_ip = self.floating_network.get_new_ip_address("floating-ip").split("/")[0]
+ floating_ip = self.floating_network.get_new_ip_address(
+ "floating-ip").split("/")[0]
for dst_vnf_name, dst_vnf_interface in dest_intfs_mapping.items():
path = None
if custom_paths is not None and dst_vnf_name in custom_paths:
if dst_vnf_interface in custom_paths[dst_vnf_name]:
path = custom_paths[dst_vnf_name][dst_vnf_interface]
- logging.debug("Taking custom path to %s: %s" % (dst_vnf_name, path))
+ logging.debug("Taking custom path to %s: %s" %
+ (dst_vnf_name, path))
else:
if datacenter not in self.floating_links:
self.floating_links[datacenter] = \
net.addLink(self.floating_switch, datacenter)
path = \
- self._get_path(self.floating_root.name, dst_vnf_name, self.floating_intf.name, dst_vnf_interface)[0]
+ self._get_path(self.floating_root.name, dst_vnf_name,
+ self.floating_intf.name, dst_vnf_interface)[0]
if isinstance(path, dict):
self.delete_flow_by_cookie(cookie)
- raise Exception(u"Can not find a valid path. Are you specifying the right interfaces?.")
+ raise Exception(
+ u"Can not find a valid path. Are you specifying the right interfaces?.")
intf = net[dst_vnf_name].nameToIntf[dst_vnf_interface]
target_mac = str(intf.MAC())
switch_outport_nr = dst_sw_outport_nr
logging.info("end node reached: {0}".format(dst_vnf_name))
elif not isinstance(next_node, OVSSwitch):
- logging.info("Next node: {0} is not a switch".format(next_hop))
+ logging.info(
+ "Next node: {0} is not a switch".format(next_hop))
return "Next node: {0} is not a switch".format(next_hop)
else:
# take first link between switches by default
index_edge_out = 0
switch_outport_nr = net.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']
- # default filters, just overwritten on the first node and last node
- cmd = 'priority=1,in_port=%s,cookie=%s' % (switch_inport_nr, cookie)
- cmd_back = 'priority=1,in_port=%s,cookie=%s' % (switch_outport_nr, cookie)
+ # default filters, just overwritten on the first node and last
+ # node
+ cmd = 'priority=1,in_port=%s,cookie=%s' % (
+ switch_inport_nr, cookie)
+ cmd_back = 'priority=1,in_port=%s,cookie=%s' % (
+ switch_outport_nr, cookie)
if i == 0: # first node
cmd = 'in_port=%s' % src_sw_inport_nr
cmd += ',cookie=%s' % cookie
# remove any vlan tags
cmd_back += ',dl_vlan=%s' % vlan
cmd_back += ',actions=pop_vlan,output:%s' % switch_inport_nr
- self.setup_arp_reply_at(current_hop, src_sw_inport_nr, floating_ip, target_mac, cookie=cookie)
+ self.setup_arp_reply_at(
+ current_hop, src_sw_inport_nr, floating_ip, target_mac, cookie=cookie)
elif next_hop == dst_vnf_name: # last switch
# remove any vlan tags
cmd += ',dl_vlan=%s' % vlan
cmd += ',actions=pop_vlan,output:%s' % switch_outport_nr
- # set up arp replys at the port so the dst nodes know the src
- self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
+ # set up arp replys at the port so the dst nodes know the
+ # src
+ self.setup_arp_reply_at(
+ current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
# reverse route
cmd_back = 'in_port=%s' % switch_outport_nr
cmd_back += ',set_field:%s->eth_src' % src_mac
cmd_back += ',set_field:%s->ip_src' % floating_ip
cmd_back += ',output:%s' % switch_inport_nr
- net.getNodeByName(dst_vnf_name).setHostRoute(src_ip, dst_vnf_interface)
+ net.getNodeByName(dst_vnf_name).setHostRoute(
+ src_ip, dst_vnf_interface)
else: # middle node
# if we have a circle in the path we need to specify this, as openflow will ignore the packet
# if we just output it on the same port as it came in
cmd += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
cmd_back += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
else:
- cmd += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_outport_nr)
- cmd_back += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_inport_nr)
+ cmd += ',dl_vlan=%s,actions=output:%s' % (
+ vlan, switch_outport_nr)
+ cmd_back += ',dl_vlan=%s,actions=output:%s' % (
+ vlan, switch_inport_nr)
# excecute the command on the target switch
logging.debug(cmd)
# advance to next destination
index += 1
- # set up the actual load balancing rule as a multipath on the very first switch
+ # set up the actual load balancing rule as a multipath on the very
+ # first switch
cmd = '"in_port=%s' % src_sw_inport_nr
cmd += ',cookie=%s' % (cookie)
cmd += ',ip'
# load balance modulo n over all dest interfaces
# TODO: in newer openvswitch implementations this should be changed to symmetric_l3l4+udp
# to balance any kind of traffic
- cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(dest_intfs_mapping)
+ cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(
+ dest_intfs_mapping)
# reuse the cookie as table entry as it will be unique
cmd += ',resubmit(, %s)"' % cookie
return cookie, floating_ip
- def setup_arp_reply_at(self, switch, port_nr, target_ip, target_mac, cookie=None):
+ def setup_arp_reply_at(self, switch, port_nr,
+ target_ip, target_mac, cookie=None):
"""
Sets up a custom ARP reply at a switch.
An ARP request coming in on the `port_nr` for `target_ip` will be answered with target IP/MAC.
cookie = self.get_cookie()
main_cmd = "add-flow -OOpenFlow13"
- # first set up ARP requests for the source node, so it will always 'find' a partner
+ # first set up ARP requests for the source node, so it will always
+ # 'find' a partner
cmd = '"in_port=%s' % port_nr
cmd += ',cookie=%s' % cookie
cmd += ',arp'
self.cookies.remove(cookie)
return True
- def delete_chain_by_intf(self, src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf):
+ def delete_chain_by_intf(
+ self, src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf):
"""
Removes a flow identified by the vnf_name/vnf_intf pairs
:return: True if successful, else false
:rtype: ``bool``
"""
- logging.debug("Deleting flow for vnf/intf pair %s %s" % (src_vnf_name, src_vnf_intf))
+ logging.debug("Deleting flow for vnf/intf pair %s %s" %
+ (src_vnf_name, src_vnf_intf))
if not self.check_vnf_intf_pair(src_vnf_name, src_vnf_intf):
return False
if not self.check_vnf_intf_pair(dst_vnf_name, dst_vnf_intf):
return False
target_flow = (src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf)
- if not target_flow in self.chain_flow_cookies:
+ if target_flow not in self.chain_flow_cookies:
return False
- success = self.delete_flow_by_cookie(self.chain_flow_cookies[target_flow])
+ success = self.delete_flow_by_cookie(
+ self.chain_flow_cookies[target_flow])
if success:
del self.chain_flow_cookies[target_flow]
delete_group = list()
group_id = self.get_flow_group(vnf_src_name, vnf_src_interface)
for node in self.net.switches:
- for cookie in self.lb_flow_cookies[(vnf_src_name, vnf_src_interface)]:
+ for cookie in self.lb_flow_cookies[(
+ vnf_src_name, vnf_src_interface)]:
flow = dict()
flow["dpid"] = int(node.dpid, 16)
flow["cookie"] = cookie
logging.debug("Deleting group with id %s" % group_id)
for switch_del_group in delete_group:
if self.net.controller == RemoteController:
- self.net.ryu_REST("stats/groupentry/delete", data=switch_del_group)
+ self.net.ryu_REST("stats/groupentry/delete",
+ data=switch_del_group)
# unmap groupid from the interface
target_pair = (vnf_src_name, vnf_src_interface)
"""
cookie = int(cookie)
if cookie not in self.floating_cookies:
- raise Exception("Can not delete floating loadbalancer as the flowcookie is not known")
+ raise Exception(
+ "Can not delete floating loadbalancer as the flowcookie is not known")
self.delete_flow_by_cookie(cookie)
floating_ip = self.floating_cookies[cookie]