OpenStack API: Replaced Flask with WSGI
[osm/vim-emu.git] / src / emuvim / dcemulator / net.py
index faae0e3..ea9fd1c 100755 (executable)
@@ -14,7 +14,7 @@ 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.
 
 See the License for the specific language governing permissions and
 limitations under the License.
 
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
+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.
 nor the names of its contributors may be used to endorse or promote
 products derived from this software without specific prior written
 permission.
@@ -33,6 +33,7 @@ from subprocess import Popen
 import re
 import requests
 import os
 import re
 import requests
 import os
+import json
 
 from mininet.net import Containernet
 from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController
 
 from mininet.net import Containernet
 from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController
@@ -41,7 +42,7 @@ from mininet.link import TCLink
 from mininet.clean import cleanup
 import networkx as nx
 from emuvim.dcemulator.monitoring import DCNetworkMonitor
 from mininet.clean import cleanup
 import networkx as nx
 from emuvim.dcemulator.monitoring import DCNetworkMonitor
-from emuvim.dcemulator.node import Datacenter, EmulatorCompute
+from emuvim.dcemulator.node import Datacenter, EmulatorCompute, EmulatorExtSAP
 from emuvim.dcemulator.resourcemodel import ResourceModelRegistrar
 
 LOG = logging.getLogger("dcemulator.net")
 from emuvim.dcemulator.resourcemodel import ResourceModelRegistrar
 
 LOG = logging.getLogger("dcemulator.net")
@@ -50,6 +51,11 @@ LOG.setLevel(logging.DEBUG)
 # default CPU period used for cpu percentage-based cfs values (microseconds)
 CPU_PERIOD = 1000000
 
 # default CPU period used for cpu percentage-based cfs values (microseconds)
 CPU_PERIOD = 1000000
 
+# default priority setting for added flow-rules
+DEFAULT_PRIORITY = 1000
+# default cookie number for new flow-rules
+DEFAULT_COOKIE = 10
+
 class DCNetwork(Containernet):
     """
     Wraps the original Mininet/Containernet class and provides
 class DCNetwork(Containernet):
     """
     Wraps the original Mininet/Containernet class and provides
@@ -107,7 +113,7 @@ class DCNetwork(Containernet):
         self.DCNetwork_graph = nx.MultiDiGraph()
 
         # initialize pool of vlan tags to setup the SDN paths
         self.DCNetwork_graph = nx.MultiDiGraph()
 
         # initialize pool of vlan tags to setup the SDN paths
-        self.vlans = range(4096)[::-1]
+        self.vlans = range(1, 4095)[::-1]
 
         # link to Ryu REST_API
         ryu_ip = 'localhost'
 
         # link to Ryu REST_API
         ryu_ip = 'localhost'
@@ -233,8 +239,21 @@ class DCNetwork(Containernet):
         """
         Remove the link from the Containernet and the networkx graph
         """
         """
         Remove the link from the Containernet and the networkx graph
         """
+        if link is not None:
+            node1 = link.intf1.node
+            node2 = link.intf2.node
+        assert node1 is not None
+        assert node2 is not None
         Containernet.removeLink(self, link=link, node1=node1, node2=node2)
         Containernet.removeLink(self, link=link, node1=node1, node2=node2)
-        self.DCNetwork_graph.remove_edge(node2.name, node1.name)
+        # TODO we might decrease the loglevel to debug:
+        try:
+            self.DCNetwork_graph.remove_edge(node2.name, node1.name)
+        except:
+            LOG.warning("%s, %s not found in DCNetwork_graph." % ((node2.name, node1.name)))
+        try:
+            self.DCNetwork_graph.remove_edge(node1.name, node2.name)
+        except:
+            LOG.warning("%s, %s not found in DCNetwork_graph." % ((node1.name, node2.name)))
 
     def addDocker( self, label, **params ):
         """
 
     def addDocker( self, label, **params ):
         """
@@ -257,7 +276,6 @@ class DCNetwork(Containernet):
         # make sure that 'type' is set
         params['type'] = params.get('type','sap_ext')
         self.DCNetwork_graph.add_node(sap_name, type=params['type'])
         # make sure that 'type' is set
         params['type'] = params.get('type','sap_ext')
         self.DCNetwork_graph.add_node(sap_name, type=params['type'])
-        LOG.info('add ext sap: {0}'.format(sap_name))
         return Containernet.addExtSAP(self, sap_name, sap_ip, **params)
 
     def removeExtSAP(self, sap_name, **params):
         return Containernet.addExtSAP(self, sap_name, sap_ip, **params)
 
     def removeExtSAP(self, sap_name, **params):
@@ -275,7 +293,6 @@ class DCNetwork(Containernet):
         # add this switch to the global topology overview
         if add_to_graph:
             self.DCNetwork_graph.add_node(name, type=params.get('type','switch'))
         # add this switch to the global topology overview
         if add_to_graph:
             self.DCNetwork_graph.add_node(name, type=params.get('type','switch'))
-            LOG.info('*** **** *** add switch: {0} type: {1}'.format(name, params.get('type')))
 
         # set the learning switch behavior
         if 'failMode' in params :
 
         # set the learning switch behavior
         if 'failMode' in params :
@@ -551,7 +568,7 @@ class DCNetwork(Containernet):
                 pass
 
 
                 pass
 
 
-        cmd = kwargs.get('cmd')
+        cmd = kwargs.get('cmd', 'add-flow')
         if cmd == 'add-flow' or cmd == 'del-flows':
             ret = self._chainAddFlow(vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface, **kwargs)
             if kwargs.get('bidirectional'):
         if cmd == 'add-flow' or cmd == 'del-flows':
             ret = self._chainAddFlow(vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface, **kwargs)
             if kwargs.get('bidirectional'):
@@ -699,7 +716,15 @@ class DCNetwork(Containernet):
                 switch_inport_nr = self.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
                 current_hop = next_hop
 
                 switch_inport_nr = self.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
                 current_hop = next_hop
 
-        return "path {2} between {0} and {1}".format(vnf_src_name, vnf_dst_name, cmd)
+        flow_options = {
+            'priority':kwargs.get('priority', DEFAULT_PRIORITY),
+            'cookie':kwargs.get('cookie', DEFAULT_COOKIE),
+            'vlan':kwargs['vlan'],
+            'path':kwargs['path'],
+            'match_input':kwargs.get('match')
+        }
+        flow_options_str = json.dumps(flow_options, indent=1)
+        return "success: {2} between {0} and {1} with options: {3}".format(vnf_src_name, vnf_dst_name, cmd, flow_options_str)
 
     def _set_flow_entry_ryu_rest(self, node, switch_inport_nr, switch_outport_nr, **kwargs):
         match = 'in_port=%s' % switch_inport_nr
 
     def _set_flow_entry_ryu_rest(self, node, switch_inport_nr, switch_outport_nr, **kwargs):
         match = 'in_port=%s' % switch_inport_nr
@@ -711,7 +736,7 @@ class DCNetwork(Containernet):
         index = kwargs.get('pathindex')
 
         vlan = kwargs.get('vlan')
         index = kwargs.get('pathindex')
 
         vlan = kwargs.get('vlan')
-        priority = kwargs.get('priority')
+        priority = kwargs.get('priority', DEFAULT_PRIORITY)
         # flag to not set the ovs port vlan tag
         skip_vlan_tag = kwargs.get('skip_vlan_tag')
         # table id to put this flowentry
         # flag to not set the ovs port vlan tag
         skip_vlan_tag = kwargs.get('skip_vlan_tag')
         # table id to put this flowentry
@@ -921,7 +946,14 @@ class DCNetwork(Containernet):
                 dict.update({match[0]:m2})
         return dict
 
                 dict.update({match[0]:m2})
         return dict
 
-    def find_connected_dc_interface(self, vnf_src_name, vnf_src_interface):
+    def find_connected_dc_interface(self, vnf_src_name, vnf_src_interface=None):
+
+        if vnf_src_interface is None:
+            # take first interface by default
+            connected_sw = self.DCNetwork_graph.neighbors(vnf_src_name)[0]
+            link_dict = self.DCNetwork_graph[vnf_src_name][connected_sw]
+            vnf_src_interface = link_dict[0]['src_port_id']
+
         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: