# 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
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
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
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()
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)
'acl-name': acl_name}]}
nfq_classifier.process_acl(acl_data)
- return '', 200
+ return '', 204
@app.route('/operational/rendered-service-path:rendered-service-paths/'
@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/',
'<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/'
'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()
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/',
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")