Example #1
0
def create_sff(sffname):
    """
    This function creates a SFF on-the-fly when it receives a PUT request from
    ODL. The SFF runs on a separate thread. If a SFF thread with same name
    already exist it is killed before a new one is created. This happens when a
    SFF is modified or recreated

    :param sffname: SFF name
    :type sffname: str

    """
    if not flask.request.json:
        flask.abort(400)

    local_sff_threads = sfc_globals.get_sff_threads()
    if sffname in local_sff_threads.keys():
        stop_sff(sffname)

    r_json = flask.request.get_json()
    local_sff_topo = sfc_globals.get_sff_topo()

    local_sff_topo[sffname] = r_json['service-function-forwarder'][0]
    sff_port = (local_sff_topo[sffname]['sff-data-plane-locator'][0]
                ['data-plane-locator']['port'])

    start_sff(sffname, "0.0.0.0", sff_port)

    return flask.jsonify({'sff': sfc_globals.get_sff_topo()}), 201
Example #2
0
def get_sff_sf_locator(odl_ip_port, sff_name, sf_name):
    """
    #TODO: add description
    #TODO: add arguments description and type

    """
    try:
        logger.info("Getting SFF information from ODL ...")
        url = common.sfc_globals.SFF_SF_DATA_PLANE_LOCATOR_URL
        odl_dataplane_url = url.format(odl_ip_port, sff_name, sf_name)

        s = requests.Session()
        r = s.get(odl_dataplane_url,
                  auth=sfc_globals.get_odl_credentials(),
                  stream=False)
    except (requests.exceptions.ConnectionError,
            requests.exceptions.RequestException) as exc:
        logger.exception('Can\'t get SFF {} data plane from ODL. Error: {}',
                         exc)
        return

    if r.ok:
        r_json = r.json()
        sff_json = r_json['service-function-forwarders']

        local_sff_topo = sfc_globals.get_sff_topo()
        for sff in sff_json['service-function-forwarder']:
            local_sff_topo[sff['name']] = sff
    else:
        logger.warning("=>Failed to GET SFF from ODL \n")
Example #3
0
def delete_sff(sffname):
    """
    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()

    try:
        if sffname in local_sff_threads.keys():
            stop_sff(sffname)

        if sffname == sfc_globals.get_my_sff_name():
            sfc_globals.reset_path()
            sfc_globals.reset_data_plane_path()

        local_sff_topo.pop(sffname)

    except KeyError:
        logger.warning('SFF name %s not found', sffname)
        status_code = 404

    return '', status_code
Example #4
0
def delete_sffs():
    """
    Delete all SFFs, SFPs, RSPs
    """
    # We always use accessors
    sfc_globals.reset_sff_topo()
    sfc_globals.reset_path()
    sfc_globals.reset_data_plane_path()

    return flask.jsonify({'sff': sfc_globals.get_sff_topo()}), 201
Example #5
0
def get_sffs_from_odl(odl_ip_port):
    """
    Retrieves the list of configured SFFs from ODL and update global
    dictionary of SFFs

    :param odl_ip_port: ODL IP and port
    :type odl_ip_port: str

    :return Nothing

    """
    try:
        logger.info("Getting SFFs configured in ODL ...")
        url = common.sfc_globals.SFF_PARAMETER_URL
        odl_sff_url = url.format(odl_ip_port)

        s = requests.Session()
        r = s.get(odl_sff_url,
                  auth=sfc_globals.get_odl_credentials(),
                  stream=False)
    except requests.exceptions.ConnectionError as e:
        logger.exception('Can\'t get SFFs from ODL. Error: {}'.format(e))
        return
    except requests.exceptions.RequestException as e:
        logger.exception('Can\'t get SFFs from ODL. Error: {}'.format(e))
        return

    if r.ok:
        r_json = r.json()
        sff_json = r_json['service-function-forwarders']

        sfc_globals.reset_sff_topo()
        local_sff_topo = sfc_globals.get_sff_topo()
        try:
            for sff in sff_json['service-function-forwarder']:
                local_sff_topo[sff['name']] = sff
        except KeyError:
            logger.info("=>No configured SFFs in ODL \n")
    else:
        logger.warning("=>Failed to GET SFFs from ODL \n")
Example #6
0
def find_sff_locator(sff_name):
    """
    For a given SFF name, look into local SFF topology for a match and returns
    the corresponding data plane locator. If SFF is not known tries to retrieve
    it from ODL.

    :param sff_name: SFF name
    :type sff_name: str

    :return sff_locator: A dictionary with keys 'ip' and 'port'

    """
    sff_locator = {}
    local_sff_topo = sfc_globals.get_sff_topo()

    if not _sff_present(sff_name, local_sff_topo):
        return sff_locator

    _sff_locator = local_sff_topo[sff_name]['sff-data-plane-locator'][0]
    sff_locator['ip'] = _sff_locator['data-plane-locator']['ip']
    sff_locator['port'] = _sff_locator['data-plane-locator']['port']

    return sff_locator
Example #7
0
def get_sff_from_odl(odl_ip_port, sff_name):
    """
    Retrieves a single configured SFF from ODL and update global dictionary of
    SFFs

    :param odl_ip_port: ODL IP and port
    :type odl_ip_port: str
    :param sff_name: SFF name
    :type sff_name: str

    :return int or None

    """
    try:
        logger.info('Contacting ODL about information for SFF: %s' % sff_name)
        url = common.sfc_globals.SFF_NAME_PARAMETER_URL
        odl_sff_url = url.format(odl_ip_port, sff_name)

        s = requests.Session()
        r = s.get(odl_sff_url,
                  auth=sfc_globals.get_odl_credentials(),
                  stream=False)
    except (requests.exceptions.ConnectionError,
            requests.exceptions.RequestException) as exc:
        logger.exception('Can\'t get SFF "{}" from ODL. Error: {}', sff_name,
                         exc)
        return -1

    if r.ok:
        r_json = r.json()

        local_sff_topo = sfc_globals.get_sff_topo()
        local_sff_topo[sff_name] = r_json['service-function-forwarder'][0]
        return 0
    else:
        logger.warning("=>Failed to GET SFF {} from ODL \n".format(sff_name))
        return -1
Example #8
0
def find_sf_locator(sf_name, sff_name):
    """
    Looks for the SF name within the service function dictionary of sff_name.
    If SFF is not present in local SFF topology it is requested from ODL.

    Return the corresponding SF data plane locator or None if not found.

    :param sf_name: SF name
    :type sf_name: str
    :param sff_name: SFF name
    :type sff_name: str

    :return sf_locator: A dictionary with keys 'ip' and 'port'

    """
    sf_locator = {}
    local_sff_topo = sfc_globals.get_sff_topo()

    if not _sff_present(sff_name, local_sff_topo):
        return sf_locator

    service_dict = local_sff_topo[sff_name]['service-function-dictionary']
    for service_function in service_dict:
        if sf_name == service_function['name']:
            _sf_locator = service_function['sff-sf-data-plane-locator']

            # A locator might use something other than IP
            if 'ip' in _sf_locator:
                sf_locator['ip'] = _sf_locator['ip']
                sf_locator['port'] = _sf_locator['port']

            return sf_locator

    if not sf_locator:
        logger.error("Failed to find data plane locator for SF: %s", sf_name)

    return sf_locator
Example #9
0
def find_sff_locator_by_ip(addr):
    """
    For a given IP address iterate over all SFFs looking for which one has a
    the same data plane locator IP

    :param addr: IP address
    :type addr: str

    :return str or None

    """
    local_sff_topo = sfc_globals.get_sff_topo()

    for sff_name, sff_value in local_sff_topo.items():
        try:
            for locator_value in sff_value['sff-data-plane-locator']:
                if locator_value['data-plane-locator']['ip'] == addr:
                    return sff_name
                else:
                    continue
        except KeyError:
            continue

    return None
Example #10
0
def get_sffs():
    return flask.jsonify(sfc_globals.get_sff_topo())