Ejemplo n.º 1
0
 def deserialize(doc):
     obj = eval(doc)
     mat = MAT(obj['sid'], obj['vid'])
     mat.props['hid'] = obj['hid']
     for (hid, mac) in obj['mac'].items():
         # Note: json file can only use str as key
         # so we need to transfer hid back to int first
         mat.props['mac'][int(hid)] = MACAddress(mac)
     return mat
Ejemplo n.º 2
0
 def __init__(self, sid, vid):
     super(MAT, self).__init__(name='MAT[%d]' % vid)
     self.props['sid'] = sid
     self.props['vid'] = vid
     self.props['hid'] = {}  # [str(mac)] = hid
     self.props['mac'] = {}  # [hid] = mac
     self.props['lock'] = threading.Lock()
     self.props['mac'][0xFFFF] = MACAddress("FF:FF:FF:FF:FF:FF")
     self.props['hid']['FF:FF:FF:FF:FF:FF'] = 0xFFFF
Ejemplo n.º 3
0
 def translate(self, mac):
     if not str(mac) in self.props['hid']:
         with self.props['lock']:
             if not str(mac) in self.props['hid']:
                 hid = random.randint(1, MAT.reserved)
                 while hid in self.props['mac']:
                     hid = random.randint(1, MAT.reserved)
                 self.props['hid'][str(mac)] = hid
                 self.props['mac'][hid] = mac
     trans_mac = MACAddress()
     trans_mac.setSid(self.props['sid'])
     trans_mac.setVid(self.props['vid'])
     hid = self.props['hid'][str(mac)]
     trans_mac.setHid(hid)
     if hid > MAT.reserved:
         # broadcast MAC address
         trans_mac.data[0] = 0xFF
     return trans_mac
Ejemplo n.º 4
0
 def deserialize(obj, net):
     mac = MACAddress(obj['mac'])
     vlan = obj['vlan']
     port = net.builder.portIndex[obj['port']]
     return FlowEntry(mac, vlan, port)
Ejemplo n.º 5
0
Archivo: vpn.py Proyecto: cygmris/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
Ejemplo n.º 6
0
 def reverse(self, hid):
     if not hid in self.props['mac']:
         return None
     return MACAddress(self.props['mac'][hid])