SFC-PY - fix classifier, agent 03/16703/2
authorDusan Madar <[email protected]>
Tue, 17 Mar 2015 14:30:47 +0000 (15:30 +0100)
committerDusan Madar <[email protected]>
Tue, 17 Mar 2015 15:05:16 +0000 (16:05 +0100)
classifier:
- try to import NetfilterQueue only on Linux

sfc_agent:
- fix RSP removal
- update SF and SFF removal

Change-Id: I033e4cea6928cefc7cf11f5c5ee9c0df2966b86d
Signed-off-by: Dusan Madar <[email protected]>
sfc-py/common/classifier.py
sfc-py/sfc_agent.py

index 0c10700775208d14d20d37a081b83844bc3f948c..51b57a9f7689a75d8381abf336354a69bd071fec 100644 (file)
@@ -6,6 +6,7 @@
 # terms of the Eclipse Public License v1.0 which accompanies this distribution,
 # and is available at http://www.eclipse.org/legal/epl-v10.html
 
+import sys
 import json
 import socket
 import logging
@@ -14,11 +15,6 @@ import ipaddress
 import threading
 import subprocess
 
-try:
-    from netfilterqueue import NetfilterQueue
-except ImportError:
-    print("Netfilter not supported or installed")
-
 from nsh.encode import build_packet
 from common.sfc_globals import ODLIP, USERNAME, PASSWORD
 from nsh.common import VXLANGPE, BASEHEADER, CONTEXTHEADER
@@ -59,6 +55,16 @@ requests_logger.setLevel(logging.WARNING)
 IPV4 = 4
 IPv6 = 6
 NFQ_NUMBER = 2
+NFQ_AVAILABLE = False
+
+
+#: NetfilterQueue is available only on Linux as it cooperates with ip(6)tables
+if sys.platform.startswith('linux'):
+    try:
+        from netfilterqueue import NetfilterQueue
+        NFQ_AVAILABLE = True
+    except ImportError:
+        pass
 
 
 #: ACE items to ip(6)tables flags/types mapping
@@ -394,11 +400,18 @@ class NfqClassifier(metaclass=Singleton):
 
     def packet_collector(self):
         """
-        Main NFQ related method. Configure the queue and wait for packets.
+        Main NFQ related method.
+
+        Configure the queue (if available) and wait for packets.
 
         NOTE: NetfilterQueue.run() blocs!
 
         """
+        if not NFQ_AVAILABLE:
+            logger.error('Classifier can\'t start\n\n'
+                         '*** NetfilterQueue not supported or installed ***\n')
+            return
+
         try:
             self.nfq = NetfilterQueue()
 
index 2331cdcddcc5a000ca3cf6bdb0e4266bdd21944a..bf73e7f0c9d9944672b663329c60b4483b484f8b 100644 (file)
@@ -280,7 +280,7 @@ def check_nfq_classifier_state():
     Check if the NFQ classifier is running, log an error and abort otherwise
     """
     if not nfq_classifier.nfq_running():
-        logger.error('Classifier is not running: ignoring ACL')
+        logger.warning('Classifier is not running: ignoring ACL')
         flask.abort(500)
 
 
@@ -311,7 +311,7 @@ def remove_acl(acl_name):
                                  'acl-name': acl_name}]}
 
     nfq_classifier.process_acl(acl_data)
-    return '', 200
+    return '', 204
 
 
 @app.route('/operational/rendered-service-path:rendered-service-paths/'
@@ -361,19 +361,28 @@ def create_path(rsp_name):
 @app.route('/operational/rendered-service-path:rendered-service-paths/'
            'rendered-service-path/<rsp_name>', methods=['DELETE'])
 def delete_path(rsp_name):
-    rsp_removed = nfq_classifier.remove_rsp(rsp_name)
-    if rsp_removed:
-        return '', 204
-    else:
-        logger.error('RSP "%s" not found', rsp_name)
-        return '', 404
+    status_code = 204
+    not_found_msg = 'RSP "%s" not found' % rsp_name
+
+    local_path = sfc_globals.get_path()
+    local_data_plane_path = sfc_globals.get_data_plane_path()
 
-    # TODO: do we still need to keep and update these agent local variables?
-#    local_path = sfc_globals.get_path()
-#    local_data_plane_path = sfc_globals.get_data_plane_path()
-#    rsp_id = local_path[rsp_name]['path-id']
-#    local_data_plane_path.pop(rsp_id, None)
-#    local_path.pop(rsp_name, None)
+    try:
+        sfp_id = local_path[rsp_name]['path-id']
+        local_data_plane_path.pop(sfp_id, None)
+        local_path.pop(rsp_name, None)
+
+        if nfq_classifier.nfq_running():
+            rsp_removed = nfq_classifier.remove_rsp(rsp_name)
+            if not rsp_removed:
+                logger.error(not_found_msg)
+                status_code = 404
+
+    except KeyError:
+        logger.error(not_found_msg)
+        status_code = 404
+
+    return '', status_code
 
 
 @app.route('/operational/rendered-service-path:rendered-service-paths/',
@@ -435,25 +444,22 @@ def create_sf(sfname):
            '<sfname>', methods=['DELETE'])
 def delete_sf(sfname):
     logger.info("Received request for SF deletion: %s", sfname)
-    local_sf_topo = sfc_globals.get_sf_threads()
+
+    status_code = 204
+    local_sf_topo = sfc_globals.get_sf_topo()
     local_sf_threads = sfc_globals.get_sf_threads()
 
     try:
         if sfname in local_sf_threads.keys():
             stop_sf(sfname)
 
-        local_sf_topo.pop(sfname, None)
+        local_sf_topo.pop(sfname)
 
     except KeyError:
-        msg = "SF name {} not found, message".format(sfname)
-        logger.warning(msg)
-        return msg, 404
-
-    except:
-        logger.warning("Unexpected exception, re-raising it")
-        raise
+        logger.warning("SF name %s not found", sfname)
+        status_code = 404
 
-    return '', 204
+    return '', status_code
 
 
 @app.route('/config/service-function-forwarder:service-function-forwarders/'
@@ -494,13 +500,14 @@ def create_sff(sffname):
            'service-function-forwarder/<sffname>', methods=['DELETE'])
 def delete_sff(sffname):
     """
-    Deletes SFF from topology, kills associated thread  and if necessary remove
+    Deletes SFF from topology, kills associated thread and if necessary remove
     all SFPs that depend on it
 
     :param sffname: SFF name
     :type sffname: str
 
     """
+    status_code = 204
     local_sff_topo = sfc_globals.get_sff_topo()
     local_sff_threads = sfc_globals.get_sff_threads()
 
@@ -508,21 +515,17 @@ def delete_sff(sffname):
         if sffname in local_sff_threads.keys():
             stop_sff(sffname)
 
-        local_sff_topo.pop(sffname, None)
         if sffname == sfc_globals.get_my_sff_name():
             sfc_globals.reset_path()
             sfc_globals.reset_data_plane_path()
 
-    except KeyError:
-        msg = "SFF name {} not found, message".format(sffname)
-        logger.warning(msg)
-        return msg, 404
+        local_sff_topo.pop(sffname)
 
-    except:
-        logger.warning("Unexpected exception, re-raising it")
-        raise
+    except KeyError:
+        logger.warning('SFF name %s not found', sffname)
+        status_code = 404
 
-    return '', 204
+    return '', status_code
 
 
 @app.route('/config/service-function-forwarder:service-function-forwarders/',
@@ -751,7 +754,7 @@ def auto_sff_name():
                         sfc_globals.set_my_sff_name(sff_name)
                         sff_name = sfc_globals.get_my_sff_name()
 
-                        logger.info("Auto SFF name is: %s \n", sff_name)
+                        logger.info("Auto SFF name is: %s", sff_name)
                         return 0
     else:
         logger.warn("Could not determine SFF name \n")