from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController
from mininet.cli import CLI
from mininet.link import TCLink
+from mininet.clean import cleanup
import networkx as nx
from emuvim.dcemulator.monitoring import DCNetworkMonitor
from emuvim.dcemulator.node import Datacenter, EmulatorCompute
:param kwargs: path through for Mininet parameters
:return:
"""
+ # members
self.dcs = {}
+ self.ryu_process = None
+
+ # always cleanup environment before we start the emulator
+ self.killRyu()
+ cleanup()
# call original Docker.__init__ and setup default controller
Containernet.__init__(
self, switch=OVSKernelSwitch, controller=controller, **kwargs)
-
# Ryu management
- self.ryu_process = None
if controller == RemoteController:
# start Ryu controller
self.startRyu(learning_switch=enable_learning)
Containernet.stop(self)
# stop Ryu controller
- self.stopRyu()
+ self.killRyu()
def CLI(self):
def _chainAddFlow(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None, **kwargs):
+ src_sw = None
+ dst_sw = None
+ src_sw_inport_nr = 0
+ dst_sw_outport_nr = 0
+
+ LOG.debug("call chainAddFlow vnf_src_name=%r, vnf_src_interface=%r, vnf_dst_name=%r, vnf_dst_interface=%r",
+ vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface)
+
#check if port is specified (vnf:port)
if vnf_src_interface is None:
# take first interface by default
for connected_sw in self.DCNetwork_graph.neighbors(vnf_src_name):
link_dict = self.DCNetwork_graph[vnf_src_name][connected_sw]
for link in link_dict:
- if link_dict[link]['src_port_id'] == vnf_src_interface:
+ if (link_dict[link]['src_port_id'] == vnf_src_interface or
+ link_dict[link]['src_port_name'] == vnf_src_interface): # Fix: we might also get interface names, e.g, from a son-emu-cli call
# found the right link and connected switch
src_sw = connected_sw
-
src_sw_inport_nr = link_dict[link]['dst_port_nr']
break
for connected_sw in self.DCNetwork_graph.neighbors(vnf_dst_name):
link_dict = self.DCNetwork_graph[connected_sw][vnf_dst_name]
for link in link_dict:
- if link_dict[link]['dst_port_id'] == vnf_dst_interface:
+ if link_dict[link]['dst_port_id'] == vnf_dst_interface or \
+ link_dict[link]['dst_port_name'] == vnf_dst_interface: # Fix: we might also get interface names, e.g, from a son-emu-cli call
# found the right link and connected switch
dst_sw = connected_sw
dst_sw_outport_nr = link_dict[link]['src_port_nr']
# if all shortest paths are wanted, use: all_shortest_paths
path = nx.shortest_path(self.DCNetwork_graph, src_sw, dst_sw, weight=kwargs.get('weight'))
except:
- LOG.exception("No path could be found between {0} and {1}".format(vnf_src_name, vnf_dst_name))
+ LOG.exception("No path could be found between {0} and {1} using src_sw={2} and dst_sw={3}".format(
+ vnf_src_name, vnf_dst_name, src_sw, dst_sw))
LOG.debug("Graph nodes: %r" % self.DCNetwork_graph.nodes())
LOG.debug("Graph edges: %r" % self.DCNetwork_graph.edges())
+ for e, v in self.DCNetwork_graph.edges():
+ LOG.debug("%r" % self.DCNetwork_graph[e][v])
return "No path could be found between {0} and {1}".format(vnf_src_name, vnf_dst_name)
LOG.info("Path between {0} and {1}: {2}".format(vnf_src_name, vnf_dst_name, path))
self.ryu_process = Popen([ryu_cmd, ryu_path2, ryu_option, ryu_of_port], stdout=FNULL, stderr=FNULL)
time.sleep(1)
- def stopRyu(self):
+ def killRyu(self):
+ """
+ Stop the Ryu controller that might be started by son-emu.
+ :return:
+ """
+ # try it nicely
if self.ryu_process is not None:
self.ryu_process.terminate()
self.ryu_process.kill()
+ # ensure its death ;-)
+ Popen(['pkill', '-f', 'ryu-manager'])
def ryu_REST(self, prefix, dpid=None, data=None):
try: