Merge pull request #151 from stevenvanrossem/master
[osm/vim-emu.git] / src / emuvim / dcemulator / net.py
index 51f53a3..bca20b2 100755 (executable)
@@ -39,6 +39,7 @@ from mininet.net import Containernet
 from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController
 from mininet.cli import CLI
 from mininet.link import TCLink
 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
 import networkx as nx
 from emuvim.dcemulator.monitoring import DCNetworkMonitor
 from emuvim.dcemulator.node import Datacenter, EmulatorCompute
@@ -66,15 +67,19 @@ class DCNetwork(Containernet):
         :param kwargs: path through for Mininet parameters
         :return:
         """
         :param kwargs: path through for Mininet parameters
         :return:
         """
+        # members
         self.dcs = {}
         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)
 
 
         # call original Docker.__init__ and setup default controller
         Containernet.__init__(
             self, switch=OVSKernelSwitch, controller=controller, **kwargs)
 
-
         # Ryu management
         # Ryu management
-        self.ryu_process = None
         if controller == RemoteController:
             # start Ryu controller
             self.startRyu(learning_switch=enable_learning)
         if controller == RemoteController:
             # start Ryu controller
             self.startRyu(learning_switch=enable_learning)
@@ -250,7 +255,7 @@ class DCNetwork(Containernet):
         Containernet.stop(self)
 
         # stop Ryu controller
         Containernet.stop(self)
 
         # stop Ryu controller
-        self.stopRyu()
+        self.killRyu()
 
 
     def CLI(self):
 
 
     def CLI(self):
@@ -277,6 +282,14 @@ class DCNetwork(Containernet):
 
     def _chainAddFlow(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None, **kwargs):
 
 
     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
         #check if port is specified (vnf:port)
         if vnf_src_interface is None:
             # take first interface by default
@@ -287,10 +300,10 @@ class DCNetwork(Containernet):
         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:
         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
                     # found the right link and connected switch
                     src_sw = connected_sw
-
                     src_sw_inport_nr = link_dict[link]['dst_port_nr']
                     break
 
                     src_sw_inport_nr = link_dict[link]['dst_port_nr']
                     break
 
@@ -304,7 +317,8 @@ class DCNetwork(Containernet):
         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:
         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']
                     # found the right link and connected switch
                     dst_sw = connected_sw
                     dst_sw_outport_nr = link_dict[link]['src_port_nr']
@@ -317,9 +331,12 @@ class DCNetwork(Containernet):
             # 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:
             # 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())
             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))
             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))
@@ -388,6 +405,7 @@ class DCNetwork(Containernet):
         path = kwargs.get('path')
         current_hop = kwargs.get('current_hop')
         vlan = kwargs.get('vlan')
         path = kwargs.get('path')
         current_hop = kwargs.get('current_hop')
         vlan = kwargs.get('vlan')
+        priority = kwargs.get('priority')
 
         s = ','
         if match_input:
 
         s = ','
         if match_input:
@@ -398,7 +416,8 @@ class DCNetwork(Containernet):
 
         if cookie:
             flow['cookie'] = int(cookie)
 
         if cookie:
             flow['cookie'] = int(cookie)
-
+        if priority:
+            flow['priority'] = int(priority)
 
         flow['actions'] = []
 
 
         flow['actions'] = []
 
@@ -501,10 +520,17 @@ class DCNetwork(Containernet):
             self.ryu_process = Popen([ryu_cmd, ryu_path2, ryu_option, ryu_of_port], stdout=FNULL, stderr=FNULL)
         time.sleep(1)
 
             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()
         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:
 
     def ryu_REST(self, prefix, dpid=None, data=None):
         try: