Пример #1
0
Файл: vc.py Проект: cygmris/enos
def vcendpoints(vc):
    """
    Given a Link object representing a virtual circuit, return the parsed endpoints.
    This is roughly analogus to griendpoints for OSCARS.
    :param vc: Link (Resource) object
    :return: array of array of (domain, node name, port name, vlan)
    """
    srcportanchor = vc.properties['SrcPort']
    dstportanchor = vc.properties['DstPort']

    srcport = Container.fromAnchor(srcportanchor)
    dstport = Container.fromAnchor(dstportanchor)

    srcnode = Container.fromAnchor(srcport.properties['Node'])
    dstnode = Container.fromAnchor(dstport.properties['Node'])

    srcendpoint = (str(srcnode.properties['Domain']),
                   str(srcport.properties['Node']['resourceName']),
                   str(srcport.resourceName.split("--")[1]),
                   str(srcport.properties['VLAN']))
    dstendpoint = (str(dstnode.properties['Domain']),
                   str(dstport.properties['Node']['resourceName']),
                   str(dstport.resourceName.split("--")[1]),
                   str(dstport.properties['VLAN']))
    return (srcendpoint, dstendpoint)
Пример #2
0
Файл: vc.py Проект: esnet/enos
def vcendpoints(vc):
    """
    Given a Link object representing a virtual circuit, return the parsed endpoints.
    This is roughly analogus to griendpoints for OSCARS.
    :param vc: Link (Resource) object
    :return: array of array of (domain, node name, port name, vlan)
    """
    srcportanchor = vc.properties['SrcPort']
    dstportanchor = vc.properties['DstPort']

    srcport = Container.fromAnchor(srcportanchor)
    dstport = Container.fromAnchor(dstportanchor)

    srcnode = Container.fromAnchor(srcport.properties['Node'])
    dstnode = Container.fromAnchor(dstport.properties['Node'])

    srcendpoint = (str(srcnode.properties['Domain']),
                   str(srcport.properties['Node']['resourceName']),
                   str(srcport.resourceName.split("--")[1]),
                   str(srcport.properties['VLAN']))
    dstendpoint = (str(dstnode.properties['Domain']),
                   str(dstport.properties['Node']['resourceName']),
                   str(dstport.resourceName.split("--")[1]),
                   str(dstport.properties['VLAN']))
    return (srcendpoint, dstendpoint)
Пример #3
0
def connecthostbroadcast(localpop,
                         hwport_tosite,
                         sitevlan,
                         meter=3,
                         broadcast_rewritemac=None):
    """
    Create entries on the local hardware switch that pass broadcast traffic
    to and from the connected host
    :param localpop: POP object
    :param hwport_tosite: port on hardware switch facing the site (string)
    :param sitevlan: VLAN number of site attachment
    :param meter:
    :param broadcast_rewritemac: Mapped Ethernet broadcast address
    :return:
    """

    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwswitchname = hwswitch.resourceName
    swswitch = Container.fromAnchor(localpop.properties['SwSwitch'])
    swswitchname = swswitch.resourceName
    topology = Container.getContainer(
        localpop.properties['SwSwitch']['containerName'])

    # Find the port on the HwSwitch connected to the software switch
    links = getlinks2(topology, hwswitchname, swswitchname)
    if links == None or len(links) == 0:
        print "No links from", hwswitchname, "to", swswitchname
        return False
    hwport_tosw = None
    for link in links:
        (node, port) = linkednode2(link, swswitchname)
        if port != None:
            # Found the link we're looking for
            hwport_tosw = port
            break

    broadcast = "FF:FF:FF:FF:FF:FF"
    translated_broadcast = broadcast
    if broadcast_rewritemac != None:
        translated_broadcast = broadcast_rewritemac

    fh1 = SCC.SdnInstallForward1(javaByteArray2(hwswitch.properties['DPID']),
                                 1, BigInteger.ZERO, str(hwport_tosw),
                                 int(sitevlan), "00:00:00:00:00:00",
                                 translated_broadcast, str(hwport_tosite),
                                 int(sitevlan), broadcast, 0, 0, meter)
    if fh1 == None:
        return None

    fh2 = SCC.SdnInstallForward1(javaByteArray2(hwswitch.properties['DPID']),
                                 1, BigInteger.ZERO, str(hwport_tosite),
                                 int(sitevlan), "00:00:00:00:00:00", broadcast,
                                 str(hwport_tosw), int(sitevlan),
                                 translated_broadcast, 0, 0, meter)
    if fh2 == None:
        SCC.deleteforward(fh1)
        return None

    return (fh1, fh2)
Пример #4
0
def createlink (topo,srcpop,dstpop,vlanbase,maxiter):
    srcanchor = srcpop.properties[CoreRouter]
    srcnode = Container.fromAnchor(srcanchor)
    dstanchor = dstpop.properties[CoreRouter]
    dstnode = Container.fromAnchor(dstpop.properties[CoreRouter])
    toposrcnode = topo.loadResource(srcnode.getResourceName())
    if toposrcnode == None:
        # Does not exists yet, create it
        toposrcnode = addnode(topo.getResourceName(),srcnode.getResourceName())
        container = Container.getContainer(srcanchor['containerOwner'],srcanchor['containerName'])
        toposrcnode.setParentResourceAnchor(container.getResourceAnchor(srcnode))
        topo.saveResource(toposrcnode)
    topodstnode = topo.loadResource(dstnode.getResourceName())
    if topodstnode == None:
        # Does not exists yet, create it
        topodstnode = addnode(topo.getResourceName(),dstnode.getResourceName())
        container = Container.getContainer(dstanchor['containerOwner'],dstanchor['containerName'])
        topodstnode.setParentResourceAnchor(container.getResourceAnchor(dstnode))
        topo.saveResource(topodstnode)
    srcports = srcnode.properties[PortsKey]
    srcpop.properties['counter'] += 1
    dstpop.properties['counter'] += 1
    srcportindex = srcpop.properties['counter'] % len(srcports)
    dstports = dstnode.properties[PortsKey]
    dstportindex = dstpop.properties['counter'] % len(dstports)
    vlan = vlanbase
    while maxiter > 0:
        if reduce(lambda x,y: x and y,
                  map (lambda x :not vlan in x,
                       [srcpop.properties['vlanmap'],dstpop.properties['vlanmap']])):
            # VLAN is available in both ports
            srcport = srcports.keys()[srcportindex]
            dstport = dstports.keys()[dstportindex]
            srcpop.properties['vlanmap'].append(vlan)
            dstpop.properties['vlanmap'].append(vlan)

            link = addlink(topology=topo.getResourceName(),
                           linkname=srcpop.getResourceName()+"--"+dstpop.getResourceName(),
                           srcnodename=srcnode.getResourceName(),
                           srcportname=srcport,
                           dstnodename=dstnode.getResourceName(),
                           dstportname=dstport,
                           srcvlan=vlan,
                           dstvlan=vlan)
            rlink= addlink(topology=topo.getResourceName(),
                           linkname=dstpop.getResourceName()+"--"+srcpop.getResourceName(),
                           srcnodename=dstnode.getResourceName(),
                           srcportname=dstport,
                           dstnodename=srcnode.getResourceName(),
                           dstportname=srcport,
                           srcvlan=vlan,
                           dstvlan=vlan)

            return (link,rlink)
        vlan += 1
        maxiter -= 1
    return None
Пример #5
0
def connectentryfanoutmac(localpop, hostmac, hostvlan, forwards, meter, mac):
    """
    Create fanout entry on source POP's software switch
    :param localpop:  POP object
    :param hostmac: host MAC address
    :param hostvlan: VLAN number of host attachment
    :param forwards: array of SDNControllerClientL2Forward
    :param meter:
    :param mac:
    :return: SdnControllerClientFlowHandle
    """
    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwswitchname = hwswitch.resourceName
    swswitch = Container.fromAnchor(localpop.properties['SwSwitch'])
    swswitchname = swswitch.resourceName
    topology = Container.getContainer(
        localpop.properties['SwSwitch']['containerName'])

    # print "connectentryfanout localpop", localpop, "host", host, "hostvlan", hostvlan, "mac", mac

    # Find the port on the software switch connected to the hardware switch
    links = getlinks2(topology, swswitchname, hwswitchname)
    if links == None or len(links) == 0:
        print "No links from", swswitchname, "to", hwswitchname
        return None
    hwswitchlink = None
    swport_tohw = None
    for link in links:
        (node, port) = linkednode2(link, hwswitchname)
        if port != None:
            # Found it!
            hwswitchlink = link
            swport_tohw = port
            break
    if swport_tohw == None:
        print "No output port on", swswitchname, "facing", hwswitchname
        return None

    # The fanout flow is "interesting" in that the input plus the multiple outputs
    # all are on the same port (but different VLANs).  Fill in the outputs.
    for f in forwards:
        f.outPort = str(swport_tohw)
        # print "FORW:  outport", f.outPort, "vlan", f.vlan, "dstMac", f.dstMac

    # Convert the list of forwarding destinations to a Java array.
    fwdsarr = jarray.array(forwards, SdnControllerClientL2Forward)

    # print "dpid", swswitch.props['dpid']
    # This flow being installed is unusual in that it does a source MAC address
    # filter as well
    fh = SCC.SdnInstallForward(javaByteArray2(swswitch.properties['DPID']),
                               1, BigInteger.ZERO, str(swport_tohw),
                               int(hostvlan), hostmac, mac, fwdsarr, 0, 0,
                               meter)

    return fh
Пример #6
0
def connectexitfanout(localpop, corevlan, forwards, meter, mac):
    """
    Create exit fanout flow on software switch of a destination POP.
    This handles broadcast traffic before it exits the network
    :param localpop: POP object
    :param corevlan: VLAN number coming from core
    :param forwards: array of SDNControllerClientL2Forward
    :param meter:
    :param mac:
    :return: SDNControllerClientFlowHandle
    """

    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwswitchname = hwswitch.resourceName
    swswitch = Container.fromAnchor(localpop.properties['SwSwitch'])
    swswitchname = swswitch.resourceName
    topology = Container.getContainer(
        localpop.properties['SwSwitch']['containerName'])

    # print "connectexitfanout localpop", localpop, "corevlan", corevlan, "mac", mac

    # Find the port on the software switch connected to the hardware switch
    links = getlinks2(topology, swswitchname, hwswitchname)
    if links == None or len(links) == 0:
        print "No links from", swswitchname, "to", hwswitchname
        return None
    hwswitchlink = None
    swport_tohw = None
    for link in links:
        (node, port) = linkednode2(link, hwswitchname)
        if port != None:
            # Found it!
            hwswitchlink = link
            swport_tohw = port
            break
    if swport_tohw == None:
        print "No output port on", swswitchname, "facing", hwswitchname
        return None

    for f in forwards:
        f.outPort = str(swport_tohw)
        # print "FORW:  outport", f.outPort, "vlan", f.vlan, "dstMac", f.dstMac

    # Convert the list of forwarding destinations to a Java array.
    fwdsarr = jarray.array(forwards, SdnControllerClientL2Forward)

    # print "dpid", swswitch.props['dpid']
    fh = SCC.SdnInstallForward(javaByteArray2(swswitch.properties['DPID']),
                               1, BigInteger.ZERO, str(swport_tohw),
                               int(corevlan), None, mac, fwdsarr, 0, 0, meter)

    return fh
Пример #7
0
    def addpop(self, pop):
        rc = True
        # See if we've already added the POP
        if pop.resourceName in self.pops:
            return False

        with self.lock:

            fhlist = []  # List of FlowHandles for this POP

            # We need to make sure that meter(s) are set correctly on the switches in the POP.
            # In particular we need to do this on Corsas before pushing flows to it that reference
            # any of the meters we use here.  This code is a bit of a hard-coded hack, but it'll
            # have to do until we can figure out what's the desired behavior.  Note that we can
            # set a meter multiple times.  It is however a requirement that the driver needs to
            # have a set a meter before a flow references it; in particular we cannot use an
            # external mechanism (e.g. CLI) to set the meter and then try to have the driver
            # push a flow that references it.
            sw = Container.fromAnchor(pop.properties['HwSwitch'])
            meter = self.meter
            rc = setmeter(sw, meter, 0, 0, 0, 0)
            # if not rc:

            # Iterate over the existing POPs to set up entries to handle broadcast traffic
            # between the POP being added and the existing POPs.  These all go in the
            # hardware switches.
            broadcastmac = "FF:FF:FF:FF:FF:FF"
            broadcastmac_mat = broadcastmac
            if MultiPointVPNServiceFactory.getVpnService().properties['mat']:
                broadcastmac_mat = self.generateBroadcastMAC()
            for (remotepopname, remotepop) in self.pops.items():
                vc = self.interconnectpops(pop.getResourceName(),
                                           remotepop.getResourceName())
                fhs = swconnect(pop, remotepop, broadcastmac_mat, vc,
                                self.meter)
                self.popflows[remotepop.getResourceName()].extend(fhs)
                fhlist.extend(fhs)

            # This POP is now added.
            self.pops[pop.resourceName] = pop
            self.popflows[pop.resourceName] = fhlist

            # Regenerate entry fanout flows for various hosts because they need to learn
            # about a new POP
            for (hostmac, hostsitename) in self.hostsites.items():
                hostsite = self.vpnsites[hostsitename]
                hostvlan = self.vpnsitevlans[hostsitename]
                localpop = self.pops[hostsite['pop']]
                fh = self.makeentryfanoutflows(localpop=localpop,
                                               hostmac=hostmac,
                                               hostvlan=hostvlan,
                                               hostsite=hostsite)
                if fh != None:
                    self.hostflows[hostmac].append(fh)

            # print "addpop ending with pop flow handles", self.popflows[pop.name]

        return rc
Пример #8
0
Файл: vpn.py Проект: esnet/enos
    def addpop(self,pop):
        rc = True
        # See if we've already added the POP
        if pop.resourceName in self.pops:
            return False

        with self.lock:

            fhlist = [] # List of FlowHandles for this POP

            # We need to make sure that meter(s) are set correctly on the switches in the POP.
            # In particular we need to do this on Corsas before pushing flows to it that reference
            # any of the meters we use here.  This code is a bit of a hard-coded hack, but it'll
            # have to do until we can figure out what's the desired behavior.  Note that we can
            # set a meter multiple times.  It is however a requirement that the driver needs to
            # have a set a meter before a flow references it; in particular we cannot use an
            # external mechanism (e.g. CLI) to set the meter and then try to have the driver
            # push a flow that references it.
            sw = Container.fromAnchor(pop.properties['HwSwitch'])
            meter = self.meter
            rc = setmeter(sw, meter, 0, 0, 0, 0)
            # if not rc:

            # Iterate over the existing POPs to set up entries to handle broadcast traffic
            # between the POP being added and the existing POPs.  These all go in the
            # hardware switches.
            broadcastmac = "FF:FF:FF:FF:FF:FF"
            broadcastmac_mat = broadcastmac
            if MultiPointVPNServiceFactory.getVpnService().properties['mat']:
                broadcastmac_mat = self.generateBroadcastMAC()
            for (remotepopname, remotepop) in self.pops.items():
                vc = self.interconnectpops(pop.getResourceName(), remotepop.getResourceName())
                fhs = swconnect(pop, remotepop, broadcastmac_mat, vc, self.meter)
                self.popflows[remotepop.getResourceName()].extend(fhs)
                fhlist.extend(fhs)

            # This POP is now added.
            self.pops[pop.resourceName] = pop
            self.popflows[pop.resourceName] = fhlist

            # Regenerate entry fanout flows for various hosts because they need to learn
            # about a new POP
            for (hostmac, hostsitename) in self.hostsites.items():
                hostsite = self.vpnsites[hostsitename]
                hostvlan = self.vpnsitevlans[hostsitename]
                localpop = self.pops[hostsite['pop']]
                fh = self.makeentryfanoutflows(localpop= localpop, hostmac= hostmac, hostvlan= hostvlan, hostsite= hostsite)
                if fh != None:
                    self.hostflows[hostmac].append(fh)

            # print "addpop ending with pop flow handles", self.popflows[pop.name]

        return rc
Пример #9
0
    def makeentryfanoutflows(self, localpop, hostmac, hostvlan, hostsite):
        # Create entry fanout flow on the software switch.  This flow fans out traffic
        # from the host/site to other hosts/sites on the same POP, as well as to all the
        # other POPs.
        # XXX need to re-run this part if we add another host/site to this POP or add
        # another POP
        forwards = []

        broadcast_mat = "FF:FF:FF:FF:FF:FF"
        if MultiPointVPNServiceFactory.getVpnService().properties['mat']:
            broadcast_mat = self.generateBroadcastMAC()

        # Locate all other sites on this POP.  For each of these, make a forwarding entry to it.
        for (othersitename, othersite) in self.vpnsites.items():
            if othersite[
                    'pop'] == localpop.resourceName and othersitename != hostsite[
                        'name']:
                fwd = SdnControllerClientL2Forward()
                fwd.outPort = "0"  # to be filled in by connectentryfanout
                fwd.vlan = int(self.vpnsitevlans[othersitename])
                fwd.dstMac = broadcast_mat
                forwards.append(fwd)

        # Locate other POPs
        for (otherpopname, otherpop) in self.pops.items():
            if otherpopname != localpop.resourceName:
                vc = self.interconnectpops(localpop.resourceName, otherpopname)
                core = Container.fromAnchor(localpop.properties['CoreRouter'])
                coreresname = core.resourceName
                (corename, coredom, coreport,
                 corevlan) = getvcnode(vc, coreresname)
                fwd = SdnControllerClientL2Forward()
                fwd.outPort = "0"  # to be filled in by connectentryfanout
                fwd.vlan = int(corevlan)
                fwd.dstMac = broadcast_mat
                forwards.append(fwd)

        # If we've already made an entry fanout flow for this host, then delete it.
        if hostmac in self.entryfanoutflows:
            oldfh = self.entryfanoutflows[hostmac]
            if oldfh.isValid():
                deleteforward(oldfh)
                del self.entryfanoutflows[hostmac]
                oldfh.invalidate()
        fh = connectentryfanoutmac(localpop=localpop,
                                   hostmac=hostmac,
                                   hostvlan=hostvlan,
                                   forwards=forwards,
                                   meter=self.meter,
                                   mac=broadcast_mat)
        if fh != None:
            self.entryfanoutflows[hostmac] = fh
        return fh
Пример #10
0
Файл: vpn.py Проект: esnet/enos
    def makeentryfanoutflows(self, localpop, hostmac, hostvlan, hostsite):
        # Create entry fanout flow on the software switch.  This flow fans out traffic
        # from the host/site to other hosts/sites on the same POP, as well as to all the
        # other POPs.
        # XXX need to re-run this part if we add another host/site to this POP or add
        # another POP
        forwards = []

        broadcast_mat = "FF:FF:FF:FF:FF:FF"
        if MultiPointVPNServiceFactory.getVpnService().properties['mat']:
            broadcast_mat = self.generateBroadcastMAC()

        # Locate all other sites on this POP.  For each of these, make a forwarding entry to it.
        for (othersitename, othersite) in self.vpnsites.items():
            if othersite['pop'] == localpop.resourceName and othersitename != hostsite['name']:
                fwd = SdnControllerClientL2Forward()
                fwd.outPort = "0" # to be filled in by connectentryfanout
                fwd.vlan = int(self.vpnsitevlans[othersitename])
                fwd.dstMac =  broadcast_mat
                forwards.append(fwd)

        # Locate other POPs
        for (otherpopname, otherpop) in self.pops.items():
            if otherpopname != localpop.resourceName:
                vc = self.interconnectpops(localpop.resourceName, otherpopname)
                core = Container.fromAnchor(localpop.properties['CoreRouter'])
                coreresname = core.resourceName
                (corename, coredom, coreport, corevlan) = getvcnode(vc, coreresname)
                fwd = SdnControllerClientL2Forward()
                fwd.outPort = "0" # to be filled in by connectentryfanout
                fwd.vlan = int(corevlan)
                fwd.dstMac = broadcast_mat
                forwards.append(fwd)

        # If we've already made an entry fanout flow for this host, then delete it.
        if hostmac in self.entryfanoutflows:
            oldfh = self.entryfanoutflows[hostmac]
            if oldfh.isValid():
                deleteforward(oldfh)
                del self.entryfanoutflows[hostmac]
                oldfh.invalidate()
        fh = connectentryfanoutmac(localpop= localpop,
                                   hostmac= hostmac,
                                   hostvlan= hostvlan,
                                   forwards= forwards,
                                   meter= self.meter,
                                   mac= broadcast_mat)
        if fh != None:
            self.entryfanoutflows[hostmac] = fh
        return fh
Пример #11
0
    def packetInCallback(self, dpid, inPort, payload):
        """
        Receive a PACKET_IN callback
        """
        # Decode the callback.  First get the switch
        switch = None
        hexdpid = binascii.hexlify(dpid)
        if hexdpid in self.switchIndex.keys():
            switch = self.switchIndex[hexdpid]
        if switch == None:
            self.logger.error("Can't find switch " + str(dpid))
            return

        # Now find the port
        if inPort not in switch.properties['Ports'].keys():
            self.logger.error("Can't find port " + inPort + " on switch " +
                              switch.resourceName)
            return
        port = Container.fromAnchor(switch.properties['Ports'][inPort])

        frame = EthernetFrame.packetToFrame(payload)
        if frame == None:
            self.logger.error("Cannot parse Ethernet frame")
            return

        switchpopname = switch.properties['Pop']

        # Log the packet we got
        self.logger.info("VpnCallback decode switch " + switch.resourceName +
                         " (" + switchpopname + ") " + " port " + inPort +
                         " vlan " + str(frame.getVid()) + " src " +
                         EthernetFrame.byteString(frame.getSrcMac()) +
                         " dst " +
                         EthernetFrame.byteString(frame.getDstMac()) +
                         " etherType " + hex(frame.getEtherType()))

        # Ignore some packets
        if frame.getEtherType() == EthernetFrame.ETHERTYPE_LLDP:
            self.logger.debug("LLDP frame ignored")
            return

        # Figure out the slice/service ID.  This comes from the mapped destination address
        # (going to be a broadcast address).  If it doesn't match our slice ID then drop.
        # XXX need to check this, not clear if the MACAddress constructor will DTRT.
        mac = MACAddress(frame.getDstMac())
        if (mac.getSid() != self.vpnService.sid):
            self.logger.debug("Destination address doesn't match, ignored")
            return

        # Figure out which VPN (if any) this belongs to
        vpn = None
        vpnsite = None

        # Iterate over all VPNs then all site attachments.
        # If we can match the POP and VLAN, then we've got a match for the site attachments
        # XXX There is probably a more efficient way to do this.
        # XXX Note we can't do any port-based matching because all of the traffic from the
        # hardware switch to the software switch shows up on the same port on the software
        # switch, which is the one generating the PACKET_IN message.

        for (x, v
             ) in MultiPointVPNServiceFactory.getVpnService().vpnIndex.items():
            for (sitename, site) in v.vpnsites.items():
                if site['pop'] == switchpopname and int(
                        v.vpnsitevlans[sitename]) == frame.getVid():
                    vpn = v
                    vpnsite = site
        if vpn == None:
            self.logger.error("Unable to find VPN or site for inbound packet")
            return

        # MAC layer address.  For some reason we don't understand, this needs to be converted from
        # unicode (?!?) to ASCII before we can really use it despite the fact these are all ASCII
        # characters.
        mac = EthernetFrame.byteString(frame.getSrcMac()).encode(
            'ascii', 'ignore')

        self.logger.info("  Source vpn " + vpn.name + " site " +
                         vpnsite['name'] + " src " + mac)
        if vpn.addhostbymac(vpnsite, mac):
            self.logger.info("Added host successfully")
        else:
            self.logger.error("Adding host failed")
        return
Пример #12
0
Файл: vpn.py Проект: esnet/enos
    def addsite(self,site,vlan):

        # If we've already added this site, don't do it again.
        # Note this is actually not a real requirement.  In theory it should be possible
        # to put multiple attachments to a single site, on different VLANs.  However
        # our implementation doesn't support that at this point, primarily because
        # we have some assumptions that each site only attaches once to a VPN.  This check
        # here is mostly to avoid violating these assumptions and getting us in trouble.
        if site['name'] in self.vpnsites:
            return False

        # Make sure the pop to which the site is attached is already a part of the VPN.
        # In theory we could implicitly add a POP whenever we add a site that needs it.
        if site['pop'].lower() not in self.pops:
            return False

        self.vpnsites[site['name']] = site
        self.vpnsitevlans[site['name']] = vlan
        self.siteflows[site['name']] = []

        broadcast_mat = "FF:FF:FF:FF:FF:FF"
        if MultiPointVPNServiceFactory.getVpnService().properties['mat']:
            broadcast_mat = self.generateBroadcastMAC()

        # Add flows to get broadcast traffic between the site and the software switch.
        pop = self.pops[site['pop']]
        fhs = connecthostbroadcast(localpop= pop,
                                   hwport_tosite= site['hwport'],
                                   sitevlan= vlan,
                                   meter= self.meter,
                                   broadcast_rewritemac= broadcast_mat)
        if fhs == None:
            return False
        self.siteflows[site['name']].extend(fhs)

        # Create exit fanout flows on the software switch.  This flow fans out traffic
        # from other POPs, to hosts/sites on this POP.
        # XXX need to re-run this part if we add another host/site to this POP or
        # add another POP
        # XXX Note that for a given port, the exit fanout flows are all identical,
        # except that their match VLAN numbers are different, corresponding to the VLAN
        # of the core OSCARS circuits.  We might possibly be able to collapse these down
        # to a single flow rule if we don't try to match on the VLAN tag.  It's not clear
        # if we want to do this or not, there might be some security and/or reliability
        # implications to doing this change.
        localpop = pop
        localpopname = localpop.resourceName

        forwards = []
        if localpopname in self.exitfanoutflows:
            exitfanoutflows = self.exitfanoutflows[localpopname]
        else:
            exitfanoutflows = {}
            self.exitfanoutflows[localpopname] = exitfanoutflows
        # Locate all sites on this POP, including the one we're adding now.
        # Be ready to forward to their
        for (site2name, site2) in self.vpnsites.items():
            if (site2['pop'] == site['pop']):
                fwd = SdnControllerClientL2Forward()
                fwd.outPort = "0" # to be filled in by connectexitfanout
                fwd.vlan = int(self.vpnsitevlans[site2name])
                fwd.dstMac = broadcast_mat
                forwards.append(fwd)

        # Iterate over source POPs
        for (srcpopname, srcpop) in self.pops.items():
            if srcpopname != localpopname:
                # Get the VLAN coming from the core for this source POP
                vc = self.interconnectpops(localpopname, srcpopname)
                core = Container.fromAnchor(localpop.properties['CoreRouter'])
                coreresname = core.resourceName
                (corename, coredom, coreport, corevlan) = getvcnode(vc, coreresname)

                # If we already made an exit fanout flow for this source POP, delete it
                if srcpopname in exitfanoutflows:
                    oldfh = exitfanoutflows[srcpopname]
                    if oldfh.isValid():
                        deleteforward(oldfh)
                        del exitfanoutflows[srcpopname]
                        oldfh.invalidate()
                fh = connectexitfanout(localpop= pop,
                                       corevlan= corevlan,
                                       forwards= forwards,
                                       meter= self.meter,
                                       mac= broadcast_mat)
                if fh != None:
                    exitfanoutflows[srcpopname] = fh
                    self.popflows[srcpopname].append(fh)

        # Regenerate entry fanout flows for various hosts on this POP because they just
        # learned a new site.
        for (hostmac, hostsitename) in self.hostsites.items():
            hostsite = self.vpnsites[hostsitename]
            if hostsite['pop'] == localpopname:
                hostvlan = self.vpnsitevlans[hostsitename]
                localpop = self.pops[hostsite['pop']]
                fh = self.makeentryfanoutflows(localpop= localpop, hostmac= hostmac, hostvlan= hostvlan, hostsite= hostsite)
                if fh != None:
                    self.hostflows[hostmac].append(fh)

        return True
Пример #13
0
def connectentryfanoutmac(localpop,
                       hostmac,
                       hostvlan,
                       forwards,
                       meter,
                       mac):
    """
    Create fanout entry on source POP's software switch
    :param localpop:  POP object
    :param hostmac: host MAC address
    :param hostvlan: VLAN number of host attachment
    :param forwards: array of SDNControllerClientL2Forward
    :param meter:
    :param mac:
    :return: SdnControllerClientFlowHandle
    """
    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwswitchname = hwswitch.resourceName
    swswitch = Container.fromAnchor(localpop.properties['SwSwitch'])
    swswitchname = swswitch.resourceName
    topology = Container.getContainer(localpop.properties['SwSwitch']['containerName'])

    # print "connectentryfanout localpop", localpop, "host", host, "hostvlan", hostvlan, "mac", mac

    # Find the port on the software switch connected to the hardware switch
    links = getlinks2(topology, swswitchname, hwswitchname)
    if links == None or len(links) == 0:
        print "No links from", swswitchname, "to", hwswitchname
        return None
    hwswitchlink = None
    swport_tohw = None
    for link in links:
        (node, port) = linkednode2(link, hwswitchname)
        if port != None:
            # Found it!
            hwswitchlink = link
            swport_tohw = port
            break
    if swport_tohw == None:
        print "No output port on", swswitchname, "facing", hwswitchname
        return None

    # The fanout flow is "interesting" in that the input plus the multiple outputs
    # all are on the same port (but different VLANs).  Fill in the outputs.
    for f in forwards:
        f.outPort = str(swport_tohw)
        # print "FORW:  outport", f.outPort, "vlan", f.vlan, "dstMac", f.dstMac

    # Convert the list of forwarding destinations to a Java array.
    fwdsarr = jarray.array(forwards, SdnControllerClientL2Forward)

    # print "dpid", swswitch.props['dpid']
    # This flow being installed is unusual in that it does a source MAC address
    # filter as well
    fh = SCC.SdnInstallForward(javaByteArray2(swswitch.properties['DPID']),
                               1,
                               BigInteger.ZERO,
                               str(swport_tohw),
                               int(hostvlan),
                               hostmac,
                               mac,
                               fwdsarr,
                               0,
                               0,
                               meter)

    return fh
Пример #14
0
def connectmac(localpop,
               remotepop,
               localsiteport,
               localsitevlan,
               remotesiteport,
               remotesitevlan,
               hostmac,
               vc,
               meter=3,
               host_rewritemac=None):
    """
    Given a pair of sites, and a host at one of the sites, set up one-way forwarding to get
    unicast packets to the host.
    This function takes care of finding the hardware switch and inter-POP ports.
    :param localpop:        POP object
    :param remotepop:       POP object
    :param localsitevlan:   VLAN tag
    :param localsiteport:   local hardware switch port for site attachment
    :param remotesitevlan:  VLAN tag
    :param remotesiteport:  remote hardware switch port for site attachment
    :param hostmac:         local host MAC address (string)
    :param vc:
    :param meter:
    :param host_rewritemac: translated local host MAC address
    :return: List of FlowHandles
    """
    core = Container.fromAnchor(localpop.properties['CoreRouter'])
    corename = core.resourceName
    (corename, coredom, coreport, corevlan) = getvcnode(vc, corename)
    remotecore = Container.fromAnchor(remotepop.properties['CoreRouter'])
    remotecorename = remotecore.resourceName
    (remotecorename, remotecoredom, remotecoreport,
     remotecorevlan) = getvcnode(vc, remotecorename)

    # Find hwswitch/port - core/port
    topology = Container.getContainer(
        localpop.properties['HwSwitch']['containerName'])

    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwport_tocore = getgriport(topology, hwswitch, core, coreport)
    # Find remotehwswitch/port - remotecore/port
    remotehwswitch = Container.fromAnchor(remotepop.properties['HwSwitch'])
    remotehwport_tocore = getgriport(topology, remotehwswitch, remotecore,
                                     remotecoreport)

    # Find the port on the HwSwitch that is connected to the host's port
    hwport_tosite = localsiteport

    fh1 = connectdataplanemac(hostmac=hostmac,
                              hostvlan=localsitevlan,
                              sw=hwswitch,
                              tohostport=hwport_tosite,
                              tocoreport=hwport_tocore,
                              tocorevlan=corevlan,
                              vc=vc,
                              meter=meter,
                              host_rewritemac=host_rewritemac)
    if fh1 == None:
        return None

    # Find the port on the remote HwSwitch that is connected to the remote host's port
    remotehwport_tosite = remotesiteport

    fh2 = connectremoteplanemac(remotesw=remotehwswitch,
                                hostmac=hostmac,
                                hostvlan=localsitevlan,
                                remotehost_port=remotehwport_tosite,
                                remotehost_vlan=remotesitevlan,
                                remotehwport_tocore=remotehwport_tocore,
                                corevlan=corevlan,
                                vc=vc,
                                meter=meter,
                                host_rewritemac=host_rewritemac)
    if fh2 == None:
        SCC.deleteforward(fh1)
        return None

    fhs = (fh1, fh2)
    return fhs
Пример #15
0
def main():
    vpnService = MultiPointVPNServiceFactory.getVpnService()

    try:
        command = sys.argv[1].lower()
        if command == 'help':
            usage()
            return

        if command == "startup":
            if vpnService == None:
                print "failed: the VPN service has not been created yet."
                return
        elif command == "init":
            vpnService = createService(int(sys.argv[2]))
            return

        if command == 'create':
            vpnname = sys.argv[2]
            vpn = vpnService.createVPN(vpnname)
            if vpn == None:
                print "vpn %r exists already" % vpnname
            else:
                print "VPN %s is created successfully." % vpn.name
        elif command == 'delete':
            vpnname = sys.argv[2]
            res = vpnService.deleteVPN(vpnname)
            if res:
                print "VPN %s removed successfully." % (vpnname)
            else:
                print "vpn name %s not found" % vpnname
        elif command == 'load':
            vpnService.loadService()
        elif command == "save":
            vpnService.saveService()
        elif command == "mat":
            if 'on' in sys.argv:
                vpnService.properties['mat'] = True
            if 'off' in sys.argv:
                vpnService.properties['mat'] = False
            state = {True: 'on', False: 'off'}
            print "MAC Address Translation feature is", state[
                vpnService.properties['mat']]
        elif command == "shutdown":
            vpnService.shutdown()
        elif command == "logging":
            logname = sys.argv[2]
            logging.basicConfig(
                format='%(asctime)s %(levelname)8s %(message)s',
                filename=logname,
                filemode='a',
                level=logging.INFO)
            logging.info("test")
        elif command == 'settopos':
            popstoponame = sys.argv[2]
            coretoponame = sys.argv[3]
            vpnService.settopos(popstoponame, coretoponame)
        elif command == 'listvpns':
            print "%20s" % ("VPN")
            for name in vpnService.vpnIndex:
                print "%20s" % name
        else:
            vpn = vpnService.getVPN(sys.argv[1])
            command = sys.argv[2].lower()
            if command == 'getprio':
                prio = vpn.getpriority()
                print prio
            elif command == 'setprio':
                vpn.setpriority(sys.argv[3])
            elif command == 'addpop':
                pop = vpnService.topology.loadResource(sys.argv[3])
                if pop == None:
                    print "unknown SDN POP"
                    return
                res = vpnService.addPOP(vpn, pop)
                if res:
                    print "POP %s has been added into VPN %s successfully." % (
                        pop.resourceName, vpn.name)
                else:
                    print "Error while adding pop."

            elif command == 'delpop':
                pop = vpnService.topology.loadResource(sys.argv[3])
                if pop == None:
                    print "unknown SDN POP"
                    return
                res = vpnService.deletePOP(vpn, pop)
                if res:
                    print "POP %s has been removed from VPN %s successfully." % (
                        pop.resourceName, vpn.name)
                else:
                    print "Error while deleting pop."
            elif command == 'addsite':
                site = vpnService.getSite(sys.argv[3])
                if site == None:
                    print "unknown site"
                    return
                vlan = sys.argv[5]
                res = vpnService.addSite(vpn, site, vlan)
                if res:
                    print "Site %s has been added into VPN %s successfully." % (
                        site['name'], vpn.name)
                else:
                    print "Error while adding site %s to VPN %s ." % (
                        site['name'], vpn.name)
            elif command == 'delsite':
                site = vpnService.getSite(sys.argv[3])
                if site == None:
                    print "unknown site"
                    return
                res = vpnService.deleteSite(vpn, site)
                if res:
                    print "Site %s has been removed from VPN %s successfully." % (
                        site['name'], vpn.name)
                else:
                    print "could not delete site"

            elif command == 'addhostbymac':
                sitename = sys.argv[3]
                if sitename not in vpn.vpnsites:
                    print "unknown site"
                    return
                site = vpn.vpnsites[sitename]
                mac = sys.argv[5]
                vpnService.addhostbymac(vpn, site, mac)
            elif command == 'delhostbymac':
                mac = sys.argv[3]
                vpnService.delhostbymac(vpn, mac)
            elif command == 'listhosts':
                print "%17s  %17s  %s" % ("MAC", "Translated MAC", "Site")
                for (hostmac, hostsite) in vpn.hostsites.items():
                    hostmacmat = hostmac
                    if vpnService.properties['mat']:
                        hostmacmat = vpn.generateMAC2(hostmac)
                    print "%17s  %17s  %s" % (hostmac, hostmacmat, hostsite)
            elif command == 'listsites':
                print "%6s  %6s  %20s  %8s  %4s" % ("Site", "POP", "Switch",
                                                    "Port", "VLAN")
                for (sitename, site) in vpn.vpnsites.items():
                    popname = site['pop']  # string
                    pop = Container.fromAnchor(
                        vpnService.topology.properties['Pops'][popname])
                    hwswitch = Container.fromAnchor(pop.properties['HwSwitch'])
                    hwswitchname = hwswitch.resourceName

                    hwport = site['hwport']
                    vlan = vpn.vpnsitevlans[sitename]
                    print "%6s  %6s  %20s  %8s  %4s" % (
                        sitename, site['pop'], hwswitchname, hwport, vlan)
            elif command == 'listpops':
                print "%6s  %20s  %20s  %20s" % (
                    "POP", "Core Router", "Hardware Switch", "Software Switch")
                for (popname, pop) in vpn.pops.items():
                    if BootStrap.getBootStrap().getDataBase() != None:
                        coreRouterName = pop.properties['CoreRouter'][
                            'resourceName']
                        hwSwitchName = pop.properties['HwSwitch'][
                            'resourceName']
                        swSwitchName = pop.properties['SwSwitch'][
                            'resourceName']
                    else:
                        coreRouterName = pop.props['coreRouter']
                        hwSwitchName = pop.props['hwSwitch']
                        swSwitchName = pop.props['swSwitch']
                    print "%6s  %20s  %20s  %20s" % (
                        popname, coreRouterName, hwSwitchName, swSwitchName)
            else:
                print "unknown command"
                usage()
    except:
        #        print "Invalid arguments"
        #        usage()
        raise
Пример #16
0
    def addsite(self, site, vlan):

        # If we've already added this site, don't do it again.
        # Note this is actually not a real requirement.  In theory it should be possible
        # to put multiple attachments to a single site, on different VLANs.  However
        # our implementation doesn't support that at this point, primarily because
        # we have some assumptions that each site only attaches once to a VPN.  This check
        # here is mostly to avoid violating these assumptions and getting us in trouble.
        if site['name'] in self.vpnsites:
            return False

        # Make sure the pop to which the site is attached is already a part of the VPN.
        # In theory we could implicitly add a POP whenever we add a site that needs it.
        if site['pop'].lower() not in self.pops:
            return False

        self.vpnsites[site['name']] = site
        self.vpnsitevlans[site['name']] = vlan
        self.siteflows[site['name']] = []

        broadcast_mat = "FF:FF:FF:FF:FF:FF"
        if MultiPointVPNServiceFactory.getVpnService().properties['mat']:
            broadcast_mat = self.generateBroadcastMAC()

        # Add flows to get broadcast traffic between the site and the software switch.
        pop = self.pops[site['pop']]
        fhs = connecthostbroadcast(localpop=pop,
                                   hwport_tosite=site['hwport'],
                                   sitevlan=vlan,
                                   meter=self.meter,
                                   broadcast_rewritemac=broadcast_mat)
        if fhs == None:
            return False
        self.siteflows[site['name']].extend(fhs)

        # Create exit fanout flows on the software switch.  This flow fans out traffic
        # from other POPs, to hosts/sites on this POP.
        # XXX need to re-run this part if we add another host/site to this POP or
        # add another POP
        # XXX Note that for a given port, the exit fanout flows are all identical,
        # except that their match VLAN numbers are different, corresponding to the VLAN
        # of the core OSCARS circuits.  We might possibly be able to collapse these down
        # to a single flow rule if we don't try to match on the VLAN tag.  It's not clear
        # if we want to do this or not, there might be some security and/or reliability
        # implications to doing this change.
        localpop = pop
        localpopname = localpop.resourceName

        forwards = []
        if localpopname in self.exitfanoutflows:
            exitfanoutflows = self.exitfanoutflows[localpopname]
        else:
            exitfanoutflows = {}
            self.exitfanoutflows[localpopname] = exitfanoutflows
        # Locate all sites on this POP, including the one we're adding now.
        # Be ready to forward to their
        for (site2name, site2) in self.vpnsites.items():
            if (site2['pop'] == site['pop']):
                fwd = SdnControllerClientL2Forward()
                fwd.outPort = "0"  # to be filled in by connectexitfanout
                fwd.vlan = int(self.vpnsitevlans[site2name])
                fwd.dstMac = broadcast_mat
                forwards.append(fwd)

        # Iterate over source POPs
        for (srcpopname, srcpop) in self.pops.items():
            if srcpopname != localpopname:
                # Get the VLAN coming from the core for this source POP
                vc = self.interconnectpops(localpopname, srcpopname)
                core = Container.fromAnchor(localpop.properties['CoreRouter'])
                coreresname = core.resourceName
                (corename, coredom, coreport,
                 corevlan) = getvcnode(vc, coreresname)

                # If we already made an exit fanout flow for this source POP, delete it
                if srcpopname in exitfanoutflows:
                    oldfh = exitfanoutflows[srcpopname]
                    if oldfh.isValid():
                        deleteforward(oldfh)
                        del exitfanoutflows[srcpopname]
                        oldfh.invalidate()
                fh = connectexitfanout(localpop=pop,
                                       corevlan=corevlan,
                                       forwards=forwards,
                                       meter=self.meter,
                                       mac=broadcast_mat)
                if fh != None:
                    exitfanoutflows[srcpopname] = fh
                    self.popflows[srcpopname].append(fh)

        # Regenerate entry fanout flows for various hosts on this POP because they just
        # learned a new site.
        for (hostmac, hostsitename) in self.hostsites.items():
            hostsite = self.vpnsites[hostsitename]
            if hostsite['pop'] == localpopname:
                hostvlan = self.vpnsitevlans[hostsitename]
                localpop = self.pops[hostsite['pop']]
                fh = self.makeentryfanoutflows(localpop=localpop,
                                               hostmac=hostmac,
                                               hostvlan=hostvlan,
                                               hostsite=hostsite)
                if fh != None:
                    self.hostflows[hostmac].append(fh)

        return True
Пример #17
0
Файл: vpn.py Проект: esnet/enos
    def packetInCallback(self, dpid, inPort, payload):
        """
        Receive a PACKET_IN callback
        """
        # Decode the callback.  First get the switch
        switch = None
        hexdpid = binascii.hexlify(dpid)
        if hexdpid in self.switchIndex.keys():
            switch = self.switchIndex[hexdpid]
        if switch == None:
            self.logger.error("Can't find switch " + str(dpid))
            return

        # Now find the port
        if inPort not in switch.properties['Ports'].keys():
            self.logger.error("Can't find port " + inPort + " on switch " + switch.resourceName)
            return
        port = Container.fromAnchor(switch.properties['Ports'][inPort])

        frame = EthernetFrame.packetToFrame(payload)
        if frame == None:
            self.logger.error("Cannot parse Ethernet frame")
            return

        switchpopname = switch.properties['Pop']

        # Log the packet we got
        self.logger.info("VpnCallback decode switch " + switch.resourceName +
                         " (" + switchpopname + ") " +
                         " port " + inPort + " vlan " + str(frame.getVid()) +
                         " src " + EthernetFrame.byteString(frame.getSrcMac()) +
                         " dst " + EthernetFrame.byteString(frame.getDstMac()) +
                         " etherType " + hex(frame.getEtherType()))

        # Ignore some packets
        if frame.getEtherType() == EthernetFrame.ETHERTYPE_LLDP:
            self.logger.debug("LLDP frame ignored")
            return

        # Figure out the slice/service ID.  This comes from the mapped destination address
        # (going to be a broadcast address).  If it doesn't match our slice ID then drop.
        # XXX need to check this, not clear if the MACAddress constructor will DTRT.
        mac = MACAddress(frame.getDstMac())
        if (mac.getSid() != self.vpnService.sid):
            self.logger.debug("Destination address doesn't match, ignored")
            return

        # Figure out which VPN (if any) this belongs to
        vpn = None
        vpnsite = None

        # Iterate over all VPNs then all site attachments.
        # If we can match the POP and VLAN, then we've got a match for the site attachments
        # XXX There is probably a more efficient way to do this.
        # XXX Note we can't do any port-based matching because all of the traffic from the
        # hardware switch to the software switch shows up on the same port on the software
        # switch, which is the one generating the PACKET_IN message.

        for (x,v) in MultiPointVPNServiceFactory.getVpnService().vpnIndex.items():
            for (sitename,site) in v.vpnsites.items():
                if site['pop'] == switchpopname and int(v.vpnsitevlans[sitename]) == frame.getVid():
                    vpn = v
                    vpnsite = site
        if vpn == None:
            self.logger.error("Unable to find VPN or site for inbound packet")
            return

        # MAC layer address.  For some reason we don't understand, this needs to be converted from
        # unicode (?!?) to ASCII before we can really use it despite the fact these are all ASCII
        # characters.
        mac = EthernetFrame.byteString(frame.getSrcMac()).encode('ascii', 'ignore')

        self.logger.info("  Source vpn " + vpn.name + " site " + vpnsite['name'] + " src " + mac)
        if vpn.addhostbymac(vpnsite, mac):
            self.logger.info("Added host successfully")
        else:
            self.logger.error("Adding host failed")
        return
Пример #18
0
def swconnect(localpop, remotepop, mac, vc, meter):
    """ Set up two-way connectivity between ports on the software switches for a given MAC
    :param localpop: POP object (Resource)
    :param remotepop: POP object (Resource)
    :param mac:
    :param vc
    :param meter:
    :return: List of FlowHandles
    """
    core = Container.fromAnchor(localpop.properties['CoreRouter'])
    corename = core.resourceName
    (corename, coredom, coreport, corevlan) = getvcnode(vc, corename)
    remotecore = Container.fromAnchor(remotepop.properties['CoreRouter'])
    remotecorename = remotecore.resourceName
    (remotecorename, remotecoredom, remotecoreport,
     remotecorevlan) = getvcnode(vc, remotecorename)

    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwswitchname = hwswitch.resourceName
    swswitch = Container.fromAnchor(localpop.properties['SwSwitch'])
    swswitchname = swswitch.resourceName

    remotehwswitch = Container.fromAnchor(remotepop.properties['HwSwitch'])
    remotehwswitchname = remotehwswitch.resourceName
    remoteswswitch = Container.fromAnchor(remotepop.properties['SwSwitch'])
    remoteswswitchname = remoteswswitch.resourceName

    topology = Container.getContainer(
        localpop.properties['SwSwitch']['containerName'])

    # Find hwswitch/port - core/port
    hwport_tocore = getgriport(topology, hwswitch, core, coreport)
    # Find remotehwswitch/port - remotecore/port
    remotehwport_tocore = getgriport(topology, remotehwswitch, remotecore,
                                     remotecoreport)

    links = getlinks2(topology, hwswitchname, swswitchname)
    if links == None or len(links) == 0:
        print "No links from ", hwswitchname, " to ", swswitchname
        return None
    hwswlink = None
    for l in links:
        (node, port) = linkednode2(l, swswitchname)
        if port != None:
            # Found the (a) link
            hwswlink = l
            hwport_tosw = port
            break

    remotelinks = getlinks2(topology, remotehwswitchname, remoteswswitchname)
    if remotelinks == None or len(remotelinks) == 0:
        print "No links from ", remotehwswitchname, " to ", remoteswswitchname
        return None
    remotehwswlink = None
    for l in remotelinks:
        (node, port) = linkednode2(l, remoteswswitchname)
        if port != None:
            # Found the (a) link
            remotehwswlink = l
            remotehwport_tosw = port
            break

    # Find the ports on hwswitch and remotehwswitch that go to the corresponding software switches

    # Set up forwarding for broadcast traffic from the new local pop
    # Install outbound flow on hwswitch from swswitch to the GRI
    fh1 = SCC.SdnInstallForward1(
        javaByteArray2(hwswitch.properties['DPID']),
        1,
        BigInteger.ZERO,
        str(hwport_tosw),  # hw port facing software switch
        int(corevlan),
        "00:00:00:00:00:00",
        mac,
        str(hwport_tocore),
        int(corevlan),
        mac,
        0,
        0,
        meter)
    if fh1 == None:
        return None

    # Install inbound flow on remotehwswitch from GRI to remoteswswitch
    fh2 = SCC.SdnInstallForward1(
        javaByteArray2(remotehwswitch.properties['DPID']),
        1,
        BigInteger.ZERO,
        str(remotehwport_tocore),
        int(remotecorevlan),
        "00:00:00:00:00:00",
        mac,
        str(remotehwport_tosw),  # remotehw port facing remote software switch
        int(remotecorevlan),
        mac,
        0,
        0,
        meter)
    if fh2 == None:
        SCC.deleteforward(fh1)
        return None

    # Set up forwarding for broadcast traffic to the new local pop
    # Install inbound flow on hwswitch from GRI to swswitch
    fh3 = SCC.SdnInstallForward1(
        javaByteArray2(hwswitch.properties['DPID']),
        1,
        BigInteger.ZERO,
        str(hwport_tocore),
        int(corevlan),
        "00:00:00:00:00:00",
        mac,
        str(hwport_tosw),  # hw port facing software switch
        int(corevlan),
        mac,
        0,
        0,
        meter)
    if fh3 == None:
        SCC.deleteforward(fh1)
        SCC.deleteforward(fh2)
        return None

    # Install outbound flow on remotehwswitch from remoteswswitch to GRI
    fh4 = SCC.SdnInstallForward1(
        javaByteArray2(remotehwswitch.properties['DPID']),
        1,
        BigInteger.ZERO,
        str(remotehwport_tosw),  # remotehw port facing remote software switch
        int(remotecorevlan),
        "00:00:00:00:00:00",
        mac,
        str(remotehwport_tocore),
        int(remotecorevlan),
        mac,
        0,
        0,
        meter)
    if fh4 == None:
        SCC.deleteforward(fh1)
        SCC.deleteforward(fh2)
        SCC.deleteforward(fh3)
        return None

    # Return something
    return (fh1, fh2, fh3, fh4)
Пример #19
0
def connecthostbroadcast(localpop,
                         hwport_tosite,
                         sitevlan,
                         meter=3,
                         broadcast_rewritemac = None):
    """
    Create entries on the local hardware switch that pass broadcast traffic
    to and from the connected host
    :param localpop: POP object
    :param hwport_tosite: port on hardware switch facing the site (string)
    :param sitevlan: VLAN number of site attachment
    :param meter:
    :param broadcast_rewritemac: Mapped Ethernet broadcast address
    :return:
    """

    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwswitchname = hwswitch.resourceName
    swswitch = Container.fromAnchor(localpop.properties['SwSwitch'])
    swswitchname = swswitch.resourceName
    topology = Container.getContainer(localpop.properties['SwSwitch']['containerName'])

    # Find the port on the HwSwitch connected to the software switch
    links = getlinks2(topology, hwswitchname, swswitchname)
    if links == None or len(links) == 0:
        print "No links from", hwswitchname, "to", swswitchname
        return False
    hwport_tosw = None
    for link in links:
        (node, port) = linkednode2(link, swswitchname)
        if port != None:
            # Found the link we're looking for
            hwport_tosw = port
            break

    broadcast = "FF:FF:FF:FF:FF:FF"
    translated_broadcast = broadcast
    if broadcast_rewritemac != None:
        translated_broadcast = broadcast_rewritemac

    fh1 = SCC.SdnInstallForward1(javaByteArray2(hwswitch.properties['DPID']),
                           1,
                           BigInteger.ZERO,
                           str(hwport_tosw),
                           int(sitevlan),
                           "00:00:00:00:00:00",
                           translated_broadcast,
                           str(hwport_tosite),
                           int(sitevlan),
                           broadcast,
                           0,
                           0,
                           meter)
    if fh1 == None:
        return None

    fh2 = SCC.SdnInstallForward1(javaByteArray2(hwswitch.properties['DPID']),
                           1,
                           BigInteger.ZERO,
                           str(hwport_tosite),
                           int(sitevlan),
                           "00:00:00:00:00:00",
                           broadcast,
                           str(hwport_tosw),
                           int(sitevlan),
                           translated_broadcast,
                           0,
                           0,
                           meter)
    if fh2 == None:
        SCC.deleteforward(fh1)
        return None

    return (fh1, fh2)
Пример #20
0
def connectexitfanout(localpop,
                       corevlan,
                       forwards,
                       meter,
                       mac):
    """
    Create exit fanout flow on software switch of a destination POP.
    This handles broadcast traffic before it exits the network
    :param localpop: POP object
    :param corevlan: VLAN number coming from core
    :param forwards: array of SDNControllerClientL2Forward
    :param meter:
    :param mac:
    :return: SDNControllerClientFlowHandle
    """

    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwswitchname = hwswitch.resourceName
    swswitch = Container.fromAnchor(localpop.properties['SwSwitch'])
    swswitchname = swswitch.resourceName
    topology = Container.getContainer(localpop.properties['SwSwitch']['containerName'])

    # print "connectexitfanout localpop", localpop, "corevlan", corevlan, "mac", mac

    # Find the port on the software switch connected to the hardware switch
    links = getlinks2(topology, swswitchname, hwswitchname)
    if links == None or len(links) == 0:
        print "No links from", swswitchname, "to", hwswitchname
        return None
    hwswitchlink = None
    swport_tohw = None
    for link in links:
        (node, port) = linkednode2(link, hwswitchname)
        if port != None:
            # Found it!
            hwswitchlink = link
            swport_tohw = port
            break
    if swport_tohw == None:
        print "No output port on", swswitchname, "facing", hwswitchname
        return None

    for f in forwards:
        f.outPort = str(swport_tohw)
        # print "FORW:  outport", f.outPort, "vlan", f.vlan, "dstMac", f.dstMac

    # Convert the list of forwarding destinations to a Java array.
    fwdsarr = jarray.array(forwards, SdnControllerClientL2Forward)

    # print "dpid", swswitch.props['dpid']
    fh = SCC.SdnInstallForward(javaByteArray2(swswitch.properties['DPID']),
                               1,
                               BigInteger.ZERO,
                               str(swport_tohw),
                               int(corevlan),
                               None,
                               mac,
                               fwdsarr,
                               0,
                               0,
                               meter)

    return fh
Пример #21
0
Файл: vpn.py Проект: esnet/enos
def main():
    vpnService = MultiPointVPNServiceFactory.getVpnService()

    try:
        command = sys.argv[1].lower()
        if command == 'help':
            usage()
            return

        if command == "startup":
            if vpnService == None:
                print "failed: the VPN service has not been created yet."
                return
        elif command == "init":
                vpnService = createService(int(sys.argv[2]))
                return

        if command == 'create':
            vpnname = sys.argv[2]
            vpn = vpnService.createVPN(vpnname)
            if vpn == None:
                print "vpn %r exists already" % vpnname
            else:
                print "VPN %s is created successfully." % vpn.name
        elif command == 'delete':
            vpnname = sys.argv[2]
            res = vpnService.deleteVPN(vpnname)
            if res:
                print "VPN %s removed successfully." % (vpnname)
            else:
                print "vpn name %s not found" % vpnname
        elif command == 'load':
            vpnService.loadService()
        elif command == "save":
            vpnService.saveService()
        elif command == "mat":
            if 'on' in sys.argv:
                vpnService.properties['mat'] = True
            if 'off' in sys.argv:
                vpnService.properties['mat'] = False
            state = {True:'on',False:'off'}
            print "MAC Address Translation feature is",state[vpnService.properties['mat']]
        elif command == "shutdown":
            vpnService.shutdown()
        elif command == "logging":
            logname = sys.argv[2]
            logging.basicConfig(format='%(asctime)s %(levelname)8s %(message)s', filename=logname, filemode='a', level=logging.INFO)
            logging.info("test")
        elif command == 'settopos':
            popstoponame = sys.argv[2]
            coretoponame = sys.argv[3]
            vpnService.settopos(popstoponame, coretoponame)
        elif command == 'listvpns':
            print "%20s" % ("VPN")
            for name in vpnService.vpnIndex:
                print "%20s" % name
        else:
            vpn = vpnService.getVPN(sys.argv[1])
            command = sys.argv[2].lower()
            if command == 'getprio':
                prio = vpn.getpriority()
                print prio
            elif command == 'setprio':
                vpn.setpriority(sys.argv[3])
            elif command == 'addpop':
                pop = vpnService.topology.loadResource(sys.argv[3])
                if pop == None:
                    print "unknown SDN POP"
                    return
                res = vpnService.addPOP(vpn, pop)
                if res:
                    print "POP %s has been added into VPN %s successfully." % (pop.resourceName, vpn.name)
                else:
                    print "Error while adding pop."

            elif command == 'delpop':
                pop = vpnService.topology.loadResource(sys.argv[3])
                if pop == None:
                    print "unknown SDN POP"
                    return
                res = vpnService.deletePOP(vpn, pop)
                if res:
                    print "POP %s has been removed from VPN %s successfully." % (pop.resourceName, vpn.name)
                else:
                     print "Error while deleting pop."
            elif command == 'addsite':
                site = vpnService.getSite(sys.argv[3])
                if site == None:
                    print "unknown site"
                    return
                vlan = sys.argv[5]
                res = vpnService.addSite(vpn, site, vlan)
                if res:
                    print "Site %s has been added into VPN %s successfully." % (site['name'], vpn.name)
                else:
                    print "Error while adding site %s to VPN %s ." % (site['name'], vpn.name)
            elif command == 'delsite':
                site = vpnService.getSite(sys.argv[3])
                if site == None:
                    print "unknown site"
                    return
                res = vpnService.deleteSite(vpn, site)
                if res:
                    print "Site %s has been removed from VPN %s successfully." % (site['name'], vpn.name)
                else:
                    print "could not delete site"

            elif command == 'addhostbymac':
                sitename = sys.argv[3]
                if sitename not in vpn.vpnsites:
                    print "unknown site"
                    return
                site = vpn.vpnsites[sitename]
                mac = sys.argv[5]
                vpnService.addhostbymac(vpn, site, mac)
            elif command == 'delhostbymac':
                mac = sys.argv[3]
                vpnService.delhostbymac(vpn, mac)
            elif command == 'listhosts':
                print "%17s  %17s  %s" % ("MAC", "Translated MAC", "Site")
                for (hostmac, hostsite) in vpn.hostsites.items():
                    hostmacmat = hostmac
                    if vpnService.properties['mat']:
                        hostmacmat = vpn.generateMAC2(hostmac)
                    print "%17s  %17s  %s" % (hostmac, hostmacmat, hostsite)
            elif command == 'listsites':
                print "%6s  %6s  %20s  %8s  %4s" % ("Site", "POP", "Switch", "Port", "VLAN")
                for (sitename, site) in vpn.vpnsites.items():
                    popname = site['pop'] # string
                    pop = Container.fromAnchor(vpnService.topology.properties['Pops'][popname])
                    hwswitch = Container.fromAnchor(pop.properties['HwSwitch'])
                    hwswitchname = hwswitch.resourceName

                    hwport = site['hwport']
                    vlan = vpn.vpnsitevlans[sitename]
                    print "%6s  %6s  %20s  %8s  %4s" % (sitename, site['pop'], hwswitchname, hwport, vlan)
            elif command == 'listpops':
                print "%6s  %20s  %20s  %20s" % ("POP", "Core Router", "Hardware Switch", "Software Switch")
                for (popname, pop) in vpn.pops.items():
                    if BootStrap.getBootStrap().getDataBase() != None:
                        coreRouterName = pop.properties['CoreRouter']['resourceName']
                        hwSwitchName = pop.properties['HwSwitch']['resourceName']
                        swSwitchName = pop.properties['SwSwitch']['resourceName']
                    else:
                        coreRouterName = pop.props['coreRouter']
                        hwSwitchName = pop.props['hwSwitch']
                        swSwitchName = pop.props['swSwitch']
                    print "%6s  %20s  %20s  %20s" % (popname, coreRouterName, hwSwitchName, swSwitchName)
            else:
                print "unknown command"
                usage()
    except:
        #        print "Invalid arguments"
        #        usage()
        raise
Пример #22
0
def connectmac(localpop,
               remotepop,
               localsiteport,
               localsitevlan,
               remotesiteport,
               remotesitevlan,
               hostmac,
               vc,
               meter=3,
               host_rewritemac = None):
    """
    Given a pair of sites, and a host at one of the sites, set up one-way forwarding to get
    unicast packets to the host.
    This function takes care of finding the hardware switch and inter-POP ports.
    :param localpop:        POP object
    :param remotepop:       POP object
    :param localsitevlan:   VLAN tag
    :param localsiteport:   local hardware switch port for site attachment
    :param remotesitevlan:  VLAN tag
    :param remotesiteport:  remote hardware switch port for site attachment
    :param hostmac:         local host MAC address (string)
    :param vc:
    :param meter:
    :param host_rewritemac: translated local host MAC address
    :return: List of FlowHandles
    """
    core = Container.fromAnchor(localpop.properties['CoreRouter'])
    corename = core.resourceName
    (corename,coredom,coreport,corevlan) = getvcnode(vc,corename)
    remotecore = Container.fromAnchor(remotepop.properties['CoreRouter'])
    remotecorename = remotecore.resourceName
    (remotecorename,remotecoredom,remotecoreport,remotecorevlan) = getvcnode(vc,remotecorename)

    # Find hwswitch/port - core/port
    topology = Container.getContainer(localpop.properties['HwSwitch']['containerName'])

    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwport_tocore = getgriport(topology, hwswitch, core, coreport)
    # Find remotehwswitch/port - remotecore/port
    remotehwswitch = Container.fromAnchor(remotepop.properties['HwSwitch'])
    remotehwport_tocore = getgriport(topology, remotehwswitch, remotecore, remotecoreport)

    # Find the port on the HwSwitch that is connected to the host's port
    hwport_tosite = localsiteport

    fh1 = connectdataplanemac(hostmac= hostmac,
                              hostvlan= localsitevlan,
                              sw= hwswitch,
                              tohostport= hwport_tosite,
                              tocoreport= hwport_tocore,
                              tocorevlan= corevlan,
                              vc= vc,
                              meter= meter,
                              host_rewritemac= host_rewritemac)
    if fh1 == None:
        return None

    # Find the port on the remote HwSwitch that is connected to the remote host's port
    remotehwport_tosite = remotesiteport

    fh2 = connectremoteplanemac(remotesw = remotehwswitch,
                                hostmac= hostmac,
                                hostvlan= localsitevlan,
                                remotehost_port= remotehwport_tosite,
                                remotehost_vlan= remotesitevlan,
                                remotehwport_tocore= remotehwport_tocore,
                                corevlan= corevlan,
                                vc= vc,
                                meter= meter,
                                host_rewritemac= host_rewritemac)
    if fh2 == None:
        SCC.deleteforward(fh1)
        return None

    fhs = (fh1, fh2)
    return fhs
Пример #23
0
def swconnect(localpop, remotepop, mac, vc, meter):
    """ Set up two-way connectivity between ports on the software switches for a given MAC
    :param localpop: POP object (Resource)
    :param remotepop: POP object (Resource)
    :param mac:
    :param vc
    :param meter:
    :return: List of FlowHandles
    """
    core = Container.fromAnchor(localpop.properties['CoreRouter'])
    corename = core.resourceName
    (corename,coredom,coreport,corevlan) = getvcnode(vc, corename)
    remotecore = Container.fromAnchor(remotepop.properties['CoreRouter'])
    remotecorename = remotecore.resourceName
    (remotecorename,remotecoredom,remotecoreport,remotecorevlan) = getvcnode(vc, remotecorename)

    hwswitch = Container.fromAnchor(localpop.properties['HwSwitch'])
    hwswitchname = hwswitch.resourceName
    swswitch = Container.fromAnchor(localpop.properties['SwSwitch'])
    swswitchname = swswitch.resourceName

    remotehwswitch = Container.fromAnchor(remotepop.properties['HwSwitch'])
    remotehwswitchname = remotehwswitch.resourceName
    remoteswswitch = Container.fromAnchor(remotepop.properties['SwSwitch'])
    remoteswswitchname = remoteswswitch.resourceName

    topology = Container.getContainer(localpop.properties['SwSwitch']['containerName'])

    # Find hwswitch/port - core/port
    hwport_tocore = getgriport(topology, hwswitch, core, coreport)
    # Find remotehwswitch/port - remotecore/port
    remotehwport_tocore = getgriport(topology, remotehwswitch, remotecore, remotecoreport)

    links = getlinks2(topology, hwswitchname, swswitchname)
    if links == None or len(links) == 0:
        print "No links from ", hwswitchname, " to ", swswitchname
        return None
    hwswlink = None
    for l in links:
        (node, port) = linkednode2(l, swswitchname)
        if port != None:
            # Found the (a) link
            hwswlink = l
            hwport_tosw = port
            break

    remotelinks = getlinks2(topology, remotehwswitchname, remoteswswitchname)
    if remotelinks == None or len(remotelinks) == 0:
        print "No links from ", remotehwswitchname, " to ", remoteswswitchname
        return None
    remotehwswlink = None
    for l in remotelinks:
        (node, port) = linkednode2(l, remoteswswitchname)
        if port != None:
            # Found the (a) link
            remotehwswlink = l
            remotehwport_tosw = port
            break

    # Find the ports on hwswitch and remotehwswitch that go to the corresponding software switches

    # Set up forwarding for broadcast traffic from the new local pop
    # Install outbound flow on hwswitch from swswitch to the GRI
    fh1 = SCC.SdnInstallForward1(javaByteArray2(hwswitch.properties['DPID']),
                           1,
                           BigInteger.ZERO,
                           str(hwport_tosw), # hw port facing software switch
                           int(corevlan),
                           "00:00:00:00:00:00",
                           mac,
                           str(hwport_tocore),
                           int(corevlan),
                           mac,
                           0,
                           0,
                           meter)
    if fh1 == None:
        return None

    # Install inbound flow on remotehwswitch from GRI to remoteswswitch
    fh2 = SCC.SdnInstallForward1(javaByteArray2(remotehwswitch.properties['DPID']),
                           1,
                           BigInteger.ZERO,
                           str(remotehwport_tocore),
                           int(remotecorevlan),
                           "00:00:00:00:00:00",
                           mac,
                           str(remotehwport_tosw), # remotehw port facing remote software switch
                           int(remotecorevlan),
                           mac,
                           0,
                           0,
                           meter)
    if fh2 == None:
        SCC.deleteforward(fh1)
        return None

    # Set up forwarding for broadcast traffic to the new local pop
    # Install inbound flow on hwswitch from GRI to swswitch
    fh3 = SCC.SdnInstallForward1(javaByteArray2(hwswitch.properties['DPID']),
                           1,
                           BigInteger.ZERO,
                           str(hwport_tocore),
                           int(corevlan),
                           "00:00:00:00:00:00",
                           mac,
                           str(hwport_tosw), # hw port facing software switch
                           int(corevlan),
                           mac,
                           0,
                           0,
                           meter)
    if fh3 == None:
        SCC.deleteforward(fh1)
        SCC.deleteforward(fh2)
        return None

    # Install outbound flow on remotehwswitch from remoteswswitch to GRI
    fh4 = SCC.SdnInstallForward1(javaByteArray2(remotehwswitch.properties['DPID']),
                           1,
                           BigInteger.ZERO,
                           str(remotehwport_tosw), # remotehw port facing remote software switch
                           int(remotecorevlan),
                           "00:00:00:00:00:00",
                           mac,
                           str(remotehwport_tocore),
                           int(remotecorevlan),
                           mac,
                           0,
                           0,
                           meter)
    if fh4 == None:
        SCC.deleteforward(fh1)
        SCC.deleteforward(fh2)
        SCC.deleteforward(fh3)
        return None

    # Return something
    return (fh1, fh2, fh3, fh4)