Beispiel #1
0
    def convertSDPRouteToLinks(self, source_ep, dest_ep, route):

        nl_route = []
        prev_source_ep = source_ep

        for sdp in route:
            nl_route.append( nsa.Link(prev_source_ep, sdp.stp1) )
            prev_source_ep = sdp.stp2
        # last hop
        nl_route.append( nsa.Link(prev_source_ep, dest_ep) )

        return nl_route
Beispiel #2
0
    def testPruningEnd(self):

        ndn_link = nsa.Link( nsa.STP('nordu.net:2013:topology',     'funet',      nsa.Label('vlan', '2031-2035')),
                             nsa.STP('nordu.net:2013:topology',     'surfnet',    nsa.Label('vlan', '2-4094')) )

        sfn_link = nsa.Link( nsa.STP('surfnet.nl:1990:production7', 'nordunet',   nsa.Label('vlan', '2-4094')),
                             nsa.STP('surfnet.nl:1990:production7', '19523',      nsa.Label('vlan', '2077')) )

        path = [ ndn_link, sfn_link ]
        pruned_path = pruner.pruneLabels(path)

        self.assertEquals(pruned_path[0].dst_stp.label.labelValue(), '2077')
        self.assertEquals(pruned_path[1].src_stp.label.labelValue(), '2077')
Beispiel #3
0
    def findPaths(self, source_stp, dest_stp, bandwidth=None):
        """
        Find possible paths between two endpoints.
        """
        # check that STPs exist
        snw = self.getNetwork(source_stp.network)
        sep = snw.getEndpoint(source_stp.endpoint)

        dnw = self.getNetwork(dest_stp.network)
        dep = dnw.getEndpoint(dest_stp.endpoint)

        # find endpoint pairs
        #print "FIND PATH", source_stp, dest_stp

        if snw == dnw:
            # same network, make direct connection and nothing else
            network_paths = [ [ nsa.Link(sep.network, sep.endpoint, dep.endpoint) ] ]
        else:
            network_paths = self.findPathEndpoints(source_stp, dest_stp)

        if bandwidth is not None:
            network_paths = self.filterBandwidth(network_paths, bandwidth)

        # topology cannot represent vlans properly yet
        # this means that all ports can be matched with all ports internally in a network
        # this is incorrect if the network does not support vlan rewriting
        # currently only netherlight supports vlan rewriting (nov. 2011)
        network_paths = self._pruneMismatchedPorts(network_paths)

        paths = [ nsa.Path(np) for np in network_paths ]

        return paths
Beispiel #4
0
    def testPruningStart(self):

        sfn_link = nsa.Link( nsa.STP('surfnet.nl:1990:production7', 'ps',         nsa.Label('vlan', '1784')),
                             nsa.STP('surfnet.nl:1990:production7', 'sara-ndn1',  nsa.Label('vlan', '1780-1799')) )

        ndn_link = nsa.Link( nsa.STP('nordu.net:2013:topology',     'surfnet',    nsa.Label('vlan', '1784-1789')),
                             nsa.STP('nordu.net:2013:topology',     'deic1',      nsa.Label('vlan', '1784-1789')) )

        dec_link = nsa.Link( nsa.STP('deic.dk:2013:topology',       'ndn1',       nsa.Label('vlan', '1784-1789')),
                             nsa.STP('deic.dk:2013:topology',       'ps',         nsa.Label('vlan', '1784')) )

        path = [ sfn_link, ndn_link, dec_link ]
        pruned_path = pruner.pruneLabels(path)

        self.assertEquals(pruned_path[0].dst_stp.label.labelValue(), '1784')
        self.assertEquals(pruned_path[1].src_stp.label.labelValue(), '1784')
Beispiel #5
0
    def findPathEndpoints(self, source_stp, dest_stp, visited_networks=None):

        #print "FIND PATH EPS", source_stp, visited_networks

        snw = self.getNetwork(source_stp.network)
        routes = []

        for ep in snw.endpoints:

            #print "  Path:", ep, " ", dest_stp

            if ep.dest_stp is None:
                #print "    Rejecting endpoint due to no pairing"
                continue

            if visited_networks is None:
                visited_networks = [ source_stp.network ]

            if ep.dest_stp.network in visited_networks:
                #print "    Rejecting endpoint due to loop"
                continue

            source_ep = self.getEndpoint(source_stp.network, source_stp.endpoint)

            if ep.dest_stp.network == dest_stp.network:
                sp = nsa.Link(ep.network, source_ep.endpoint, ep.endpoint)
                # this means last network, so we add the last hop
                last_source_ep = self.getEndpoint(ep.dest_stp.network, ep.dest_stp.endpoint)
                last_dest_ep   = self.getEndpoint(dest_stp.network, dest_stp.endpoint)
                sp_end = nsa.Link(last_dest_ep.network, last_source_ep.endpoint, last_dest_ep.endpoint)
                routes.append( [ sp, sp_end ] )
            else:
                nvn = visited_networks[:] + [ ep.dest_stp.network ]
                subroutes = self.findPathEndpoints(ep.dest_stp, dest_stp, nvn)
                if subroutes:
                    for sr in subroutes:
                        src = sr[:]
                        sp = nsa.Link(ep.network, source_ep.endpoint, ep.endpoint)
                        src.insert(0, sp)
                        routes.append(  src  )

        return routes
Beispiel #6
0
import StringIO

from twisted.trial import unittest

from opennsa import nsa
from opennsa.topology import gole

from . import topology as testtopology

TEST_PATH_1 = {
    'source_stp':
    nsa.STP('Aruba', 'A2'),
    'dest_stp':
    nsa.STP('Curacao', 'C3'),
    'paths': [[
        nsa.Link('Aruba', 'A2', 'A4'),
        nsa.Link('Bonaire', 'B1', 'B4'),
        nsa.Link('Curacao', 'C1', 'C3')
    ],
              [
                  nsa.Link('Aruba', 'A2', 'A1'),
                  nsa.Link('Dominica', 'D4', 'D1'),
                  nsa.Link('Curacao', 'C4', 'C3')
              ]]
}

TEST_PATH_2 = {
    'source_stp':
    nsa.STP('Aruba', 'A2'),
    'dest_stp':
    nsa.STP('Bonaire', 'B2'),
Beispiel #7
0
    def _findPathsRecurse(self,
                          source_stp,
                          dest_stp,
                          bandwidth,
                          exclude_networks=None):

        source_network = self.getNetwork(source_stp.network)
        dest_network = self.getNetwork(dest_stp.network)
        source_port = source_network.getPort(source_stp.port)
        dest_port = dest_network.getPort(dest_stp.port)

        if not (source_port.canMatchLabel(source_stp.label)
                or dest_port.canMatchLabel(dest_stp.label)):
            return []


#        if not (source_port.canProvideBandwidth(bandwidth) and dest_port.canProvideBandwidth(bandwidth)):
#            return []

        if source_port.isBidirectional() and dest_port.isBidirectional():
            # bidirectional path finding, easy case first
            if source_stp.network == dest_stp.network:
                # while it is possible to cross other network in order to connect to intra-network STPs
                # it is not something we really want to do in the real world, so we don't
                try:
                    if source_network.canSwapLabel(source_stp.label.type_):
                        source_label = source_port.label().intersect(
                            source_stp.label)
                        dest_label = dest_port.label().intersect(
                            dest_stp.label)
                    else:
                        source_label = source_port.label().intersect(
                            dest_port.label()).intersect(
                                source_stp.label).intersect(dest_stp.label)
                        dest_label = source_label
                    link = nsa.Link(source_stp.network, source_stp.port,
                                    dest_stp.port, source_label, dest_label)
                    return [[link]]
                except nsa.EmptyLabelSet:
                    return []  # no path
            else:
                # ok, time for real pathfinding
                link_ports = source_network.findPorts(True, source_stp.label,
                                                      source_stp.port)
                link_ports = [port for port in link_ports if port.hasRemote()
                              ]  # filter out termination ports
                links = []
                for lp in link_ports:
                    demarcation = self.findDemarcationPort(lp)
                    if demarcation is None:
                        continue

                    d_network_id, d_port_id = demarcation

                    if exclude_networks is not None and demarcation[
                            0] in exclude_networks:
                        continue  # don't do loops in path finding

                    demarcation_label = lp.label(
                    ) if source_network.canSwapLabel(
                        source_stp.label.type_
                    ) else source_stp.label.intersect(lp.label())
                    demarcation_stp = nsa.STP(demarcation[0], demarcation[1],
                                              demarcation_label)
                    sub_exclude_networks = [source_network.id_
                                            ] + (exclude_networks or [])
                    sub_links = self._findPathsRecurse(demarcation_stp,
                                                       dest_stp, bandwidth,
                                                       sub_exclude_networks)
                    # if we didn't find any sub paths, just continue
                    if not sub_links:
                        continue

                    for sl in sub_links:
                        # --
                        if source_network.canSwapLabel(source_stp.label.type_):
                            source_label = source_port.label().intersect(
                                source_stp.label)
                            dest_label = lp.label().intersect(
                                sl[0].src_stp.label)
                        else:
                            source_label = source_port.label().intersect(
                                source_stp.label).intersect(
                                    lp.label()).intersect(sl[0].src_stp.label)
                            dest_label = source_label

                        first_link = nsa.Link(source_stp.network,
                                              source_stp.port, lp.id_,
                                              source_label, dest_label)
                        path = [first_link] + sl
                        links.append(path)

                return sorted(links, key=len)  # sort by length, shortest first

        else:
            raise error.TopologyError(
                'Unidirectional path-finding not implemented yet')
Beispiel #8
0
    def reserve(self, requester_nsa, provider_nsa, session_security_attr,
                global_reservation_id, description, connection_id,
                service_parameters, sub):

        # --

        log.msg('', system='opennsa')
        log.msg('Connection %s. Reserve request from %s.' %
                (connection_id, requester_nsa),
                system=LOG_SYSTEM)

        if connection_id in self.connections.get(requester_nsa, {}):
            return defer.fail(
                error.ReserveError('Connection with id %s already exists' %
                                   connection_id))

        source_stp = service_parameters.source_stp
        dest_stp = service_parameters.dest_stp

        if source_stp == dest_stp:
            return defer.fail(
                error.ReserveError('Cannot connect %s to itself.' %
                                   source_stp))

        conn = connection.Connection(self.service_registry, requester_nsa,
                                     connection_id, source_stp, dest_stp,
                                     service_parameters, global_reservation_id,
                                     description)

        self.connections.setdefault(requester_nsa,
                                    {})[conn.connection_id] = conn

        # figure out nature of request

        path_info = (connection_id, source_stp.network, source_stp.endpoint,
                     dest_stp.network, dest_stp.endpoint, self.network)

        if source_stp.network == self.network and dest_stp.network == self.network:
            log.msg(
                'Connection %s: Simple path creation: %s:%s -> %s:%s (%s)' %
                path_info,
                system=LOG_SYSTEM)
            link = nsa.Link(source_stp.network, source_stp.endpoint,
                            dest_stp.endpoint)
            self.setupSubConnection(link, conn, service_parameters)

        # This code is for chaining requests and is currently not used, but might be needed sometime in the future
        # Once we get proper a topology service, some chaining will be necessary.

        #elif source_stp.network == self.network:
        #    # make path and chain on - common chaining
        #    log.msg('Reserve %s: Common chain creation: %s:%s -> %s:%s (%s)' % path_info, system=LOG_SYSTEM)
        #    paths = self.topology.findPaths(source_stp, dest_stp)
        #    # check for no paths
        #    paths.sort(key=lambda e : len(e.endpoint_pairs))
        #    selected_path = paths[0] # shortest path
        #    log.msg('Attempting to create path %s' % selected_path, system=LOG_SYSTEM)
        #    assert selected_path.source_stp.network == self.network
        #   # setup connection data - does this work with more than one hop?
        #    setupSubConnection(selected_path.source_stp, selected_path.endpoint_pairs[0].sourceSTP(), conn)
        #    setupSubConnection(selected_path.endpoint_pairs[0].destSTP(), dest_stp, conn)
        #elif dest_stp.network == self.network:
        #    # make path and chain on - backwards chaining
        #    log.msg('Backwards chain creation %s: %s:%s -> %s:%s (%s)' % path_info, system=LOG_SYSTEM)
        #    paths = self.topology.findPaths(source_stp, dest_stp)
        #    # check for no paths
        #    paths.sort(key=lambda e : len(e.endpoint_pairs))
        #    selected_path = paths[0] # shortest path
        #    log.msg('Attempting to create path %s' % selected_path, system=LOG_SYSTEM)
        #    assert selected_path.dest_stp.network == self.network
        #   # setup connection data
        #    setupSubConnection(selected_path.source_stp, selected_path.endpoint_pairs[0].sourceSTP(), conn)
        #    setupSubConnection(selected_path.endpoint_pairs[0].destSTP(), dest_stp, conn)
        #else:
        #    log.msg('Tree creation %s:  %s:%s -> %s:%s (%s)' % path_info, system=LOG_SYSTEM)

        # create the connection in tree/fanout style
        else:
            # log about creation and the connection type
            log.msg(
                'Connection %s: Aggregate path creation: %s:%s -> %s:%s (%s)' %
                path_info,
                system=LOG_SYSTEM)
            # making the connection is the same for all though :-)
            paths = self.topology.findPaths(source_stp, dest_stp)

            # error out if we could not find a path
            if not paths:
                error_msg = 'Could not find a path for route %s:%s -> %s:%s' % (
                    source_stp.network, source_stp.endpoint, dest_stp.network,
                    dest_stp.endpoint)
                log.msg(error_msg, system=LOG_SYSTEM)
                raise error.TopologyError(error_msg)

            # check for no paths
            paths.sort(key=lambda e: len(e.links()))
            selected_path = paths[0]  # shortest path
            log.msg('Attempting to create path %s' % selected_path,
                    system=LOG_SYSTEM)

            for link in selected_path.links():
                self.setupSubConnection(link, conn, service_parameters)

        # now reserve connections needed to create path
        conn.addSubscription(sub)
        d = task.deferLater(reactor, 0, conn.reserve)
        d.addErrback(log.err)
        return defer.succeed(None)