Ejemplo n.º 1
0
  def _handle_ARPRequest(self, event):
    """ First check if the host is newly attached to another switch"""
    # Nov.2015
    self.numOfARP_REQUEST = self.numOfARP_REQUEST + 1
    #logging.info("ARP " + str(self.numOfARP_REQUEST) + " " + str(time.time()) + " R")
    

    #log.info("Event.DPID {}".format(event.dpid))
    #log.info("Event.SRC {}".format(event.ip))
    #log.info("Event.MAC {}".format(self.topo.findHostByIp(event.ip).mac))
    #log.info("Event.DST {}".format(event.dst))
    #log.info("Event.PORT {}".format(event.port))

    compareHost = self.topo.findHostByIp(event.ip)
    if compareHost is not None:
      compareSwitch = self.topo.findSwitchByDpid(event.dpid)
      if compareSwitch.vid.sw != compareHost.vid.sw:
        # Delete Original
        oldSwitch = self.topo.findSwitchByVid(VidAddr(compareHost.vid.sw, 0x00))
        self.topo.deleteHost(compareHost)
        oldSwitch.deleteHost(compareHost)

        # Add new
        newVID = VidAddr(compareSwitch.vid.sw, compareSwitch.nextHostId())
        newHost = self.topo.addHost(Host(compareHost.mac, event.ip, newVID, event.port, compareSwitch))
        compareSwitch.addHost(newHost)

        # Notify local controller
        self.numOfVIRO_LOCAL_HOST = self.numOfVIRO_LOCAL_HOST+ 1
        #logging.info("LOCAL_HOST " + str(self.numOfVIRO_LOCAL_HOST) + " " + str(time.time()) + " S")

        self.send_local_host(compareHost.mac, event.ip, newVID, event.port, compareSwitch)


    if event.dst == IPAddr("192.168.0.254"):
      event.reply = EthAddr("11-22-33-44-55-66")
      return

    """ Update the reply field in the ARP request """        
    host = self.topo.findHostByIp(event.dst) # matching on the destination IP Address

     # check if src and dst hosts are attached to the same switch. If so return the "true" MAC address for the dst
    if host:
       if host.vid.sw == compareHost.vid.sw:
          log.debug("Hosts attached to the same switch src-mac=%s dst-mac=%s", host.mac, compareHost.mac)
          event.reply = EthAddr(host.mac.raw)

       else:
           event.reply = EthAddr(host.vid.raw)
    else:
      log.debug("Host not found in _handle_ARPRequest")
Ejemplo n.º 2
0
def _handle_ConnectionUp (event):

  # Turn on ability to specify table in flow_mods
  # msg = nx.nx_flow_mod_table_id()
  # event.connection.send(msg)

  # Clear second table
  # msg = nx.nx_flow_mod(command=of.OFPFC_DELETE, table_id = 1)
  # event.connection.send(msg)

  # Fallthrough rule for table 0: flood and send to controller
  # msg = nx.nx_flow_mod()
  # msg.priority = 1 # Low priority
  # msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr("11-22-33-44-55-66")))
  # msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
  # msg.actions.append(nx.nx_action_resubmit.resubmit_table(table = 1))
  # event.connection.send(msg)

  # src_vid = VidAddr(0x04, 0x01)
  # dst_vid = VidAddr(0x07, 0x01)

  msg = vnx.nx_flow_mod()
  msg.match.in_port = 1
  msg.actions.append(vof.viro_action_push_fd(fd = VidAddr(0x08, 0x0a)))
  msg.actions.append(of.ofp_action_output(port = 2))
  event.connection.send(msg)

  msg = vnx.nx_flow_mod()
  msg.match.in_port = 2
  msg.actions.append(vof.viro_action_pop_fd())
  msg.actions.append(of.ofp_action_output(port = 1))
  event.connection.send(msg)
Ejemplo n.º 3
0
    def _unpack_body(self, raw, offset, avail):
        offset, (self.subtype, host, sw) = of._unpack('!HHI', raw, offset)
        offset = of._skip(raw, offset, 8)

        self.fd = VidAddr(sw, host)

        return offset
Ejemplo n.º 4
0
    def routeViroPacket(self, pkt, inport=None):
        """ Route the viro packet closer to destination """

        dst_pkt = VidAddr(pkt.dst.sw, 0x00)

        if (dst_pkt == self.sw.vid):
            # consume the packet since its sent to me
            self.processViroPacket(pkt, inport)
            return

        if pkt.effective_ethertype == viroctrl.VIRO_CTRL_TYPE:
            op = pkt.payload.op
            nexthop, port = self.routing.getNextHop(dst_pkt, op)
        else:
            nexthop, port = self.routing.getNextHop(dst_pkt)

        if nexthop != None:
            msg = msgFactory.packetOut(pkt, port)
            self.sw.connection.send(msg)
        else:
            log.debug("routeViroPacket nexthop not found")

        # use for handling data packets
        if inport:
            return port
Ejemplo n.º 5
0
  def _handle_ViroSwitchUp(self, event):
    """ Register a viro switch to the remote controller """
    log.debug("Connection %s %s" % (event.connection, dpidToStr(event.dpid)))
    
    # register the viro switch
    vid = VidAddr(event.dpid, 0x00)

    sw = self.topo.addSwitch(Switch(event.dpid, vid, event.connection))
    
    # set the remote controller id at the switch    
    sw.connection.send(msgFactory.ofpControllerId(RemoteViro.CONTROLLER_ID))
    
    # enable the flowMod tableId extension (nicira extensions)
    sw.connection.send(msgFactory.ofpFlowModTableId())
Ejemplo n.º 6
0
    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < rdv_publish.MIN_LEN:
            self.msg(
                '(rdv_publish parse) warning rdv_publish packet data too short to parse header: data len %u'
                % (dlen, ))
            return

        hdr = struct.unpack("!I", raw[:rdv_publish.MIN_LEN])

        self.vid = VidAddr(hdr[0], 0)

        self.parsed = True
Ejemplo n.º 7
0
    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < gw_withdraw.MIN_LEN:
            self.msg(
                '(gw_withdraw parse) warning gw_withdraw packet data too short to parse header: data len %u'
                % (dlen, ))
            return

        hdr = struct.unpack("!I", raw[:gw_withdraw.MIN_LEN])

        self.failed_gw = VidAddr(hdr[0], 0)

        self.parsed = True
Ejemplo n.º 8
0
    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < rdv_reply.MIN_LEN:
            self.msg(
                '(rdv_reply parse) warning rdv_reply packet data too short to parse header: data len %u'
                % (dlen, ))
            return

        hdr = struct.unpack("!II", raw[:rdv_reply.MIN_LEN])

        self.bucket_dist = hdr[0]
        self.gw = VidAddr(hdr[1], 0)

        self.parsed = True
Ejemplo n.º 9
0
    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < controller_echo.MIN_LEN:
            self.msg(
                '(controller_echo parse) warning controller_echo packet data too short to parse header: data len %u'
                % (dlen, ))
            return

        hdr = struct.unpack("!BBIH", raw[:controller_echo.MIN_LEN])

        self.from_controller_id = hdr[0]
        self.to_controller_id = hdr[1]
        self.vid = VidAddr(hdr[2], hdr[3])

        self.parsed = True
Ejemplo n.º 10
0
def pushRoutingTableETH(dst_vid, dst_vid_mask, Outport):
    fake_dst_mac = VidAddr(dst_vid, 0x00)
    fake_dst_mac_mask = VidAddr(dst_vid_mask, 0x00)

    msg = vnx.nx_flow_mod()
    msg.table_id = 1
    msg.priority = 15
    msg.match.eth_type = ethernet.IP_TYPE
    msg.match.eth_dst = fake_dst_mac.to_raw()
    msg.match.eth_dst_mask = fake_dst_mac_mask.to_raw()

    msg.actions.append(of.ofp_action_output(port=Outport))

    return msg
Ejemplo n.º 11
0
    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < local_host.MIN_LEN:
            self.msg(
                '(local_host) warning local_host packet data too short to parse header: data len %u'
                % (dlen, ))
            return

        hdr = struct.unpack("!IIHI", raw[6:local_host.MIN_LEN])
        mac = raw[:6]

        self.mac = EthAddr(mac)
        self.ip = IPAddr(hdr[0])
        self.vid = VidAddr(hdr[1], hdr[2])
        self.port = hdr[3]
        self.host = Host(self.mac, self.ip, self.vid, self.port, None)

        self.parsed = True
Ejemplo n.º 12
0
def encapsulate(src_mac, src_vid, dst_mac, dst_vid):
    msg = vnx.nx_flow_mod()
    msg.table_id = 0
    msg.priority = 15
    msg.match.eth_type = ethernet.IP_TYPE
    msg.match.eth_src = src_mac
    msg.match.eth_dst = dst_mac

    msg.actions.append(vof.viro_action_push_fd(fd=VidAddr(0x08, 0x0a)))
    msg.actions.append(vof.viro_action_vid_sw.set_src(src_vid.sw))
    msg.actions.append(vof.viro_action_vid_host.set_src(src_vid.host))

    msg.actions.append(vof.viro_action_vid_sw.set_dst(dst_vid.sw))
    msg.actions.append(vof.viro_action_vid_host.set_dst(dst_vid.host))

    msg.actions.append(vnx.nx_action_resubmit.resubmit_table(1))

    # msg.actions.append(of.ofp_action_output(port = Outport))

    return msg
Ejemplo n.º 13
0
  def _handle_DHCPLease(self, event):
    """ Register a host """
    # Nov.2015
    self.numOfDHCP_REQUEST = self.numOfDHCP_REQUEST + 1
    #logging.info("DHCP " + str(self.numOfDHCP_REQUEST) + " " + str(time.time()) + " R")

    log.debug("handling dhcp lease event dpid=%s mac=%s ip=%s", dpidToStr(event.dpid), event.host_mac, event.ip)
    
    sw = self.topo.findSwitchByDpid(event.dpid)
    hostMac = event.host_mac
    hostIp = event.ip
    hostPort = event.port
    hostVid = VidAddr(sw.vid.sw, sw.nextHostId())
    host = self.topo.addHost(Host(hostMac, hostIp, hostVid, hostPort, sw))
    sw.addHost(host)
        

    self.numOfVIRO_LOCAL_HOST = self.numOfVIRO_LOCAL_HOST+ 1
    #logging.info("LOCAL_HOST " + str(self.numOfVIRO_LOCAL_HOST) + " " + str(time.time()) + " S")

    # sending host information to the local controller
    self.send_local_host(hostMac, hostIp, hostVid, hostPort, sw)
Ejemplo n.º 14
0
  def _handle_ViroPacketInVIROCtrl(self, event):
    """ VIRO control Vid Request pkts """
    
    viropkt = event.packet
    inport = event.port
   
    log.debug(str(viropkt))

    ctrlpkt = viropkt.payload

    if ctrlpkt.op == viroctrl.VID_REQUEST:
       # local control vid request message
       # assigns the VidAddress the the local host attached to sw
       self.numOfVIRO_VID_REQUEST = self.numOfVIRO_VID_REQUEST + 1
       #logging.info("VIRO_VID_REQUEST " + str(self.numOfVIRO_VID_REQUEST) + " " + str(time.time()) + " R")

       log.debug('Receiving VidRequest pkt from local controller')
       payload = ctrlpkt.payload
       mac  = payload.mac
       ip = payload.ip
       port = payload.port

       sw = self.topo.findSwitchByDpid(event.dpid)
       vid = VidAddr(sw.vid.sw, sw.nextHostId())
       host = self.topo.addHost(Host(mac, ip, vid, port, sw))
       sw.addHost(host)
     
       # sending host information to the local controller
       self.send_local_host(mac, ip, vid, port, sw)

    elif ctrlpkt.op == viroctrl.HOST_WITHDRAW:
      self.numOfVIRO_HOST_WITHDRAW = self.numOfVIRO_HOST_WITHDRAW + 1
      #logging.info("VIRO_HOST_WITHDRAW " + str(self.numOfVIRO_HOST_WITHDRAW) + " " + str(time.time()) + " R")

      log.debug('Receiving a failed host packet')
      host_ip = ctrlpkt.payload.failed_host
       
      log.debug('Updating its global topology table')
      self.topo.deleteHostByIP(host_ip) # remove host
Ejemplo n.º 15
0
from pox.core import core
import struct
from viro.packet.viro import viro
from viro.packet.viro_ctrl import viroctrl
from viro.packet.vid import VidAddr
from viro.packet.ctrl import *
from pox.lib.packet import *

log = core.getLogger()
vidNull = VidAddr(0, 0)


def controlPacket(srcVid, dstVid, fdVid, op, payload):
    """ Create a viro control packet """
    ctrl = viroctrl(op=op)
    ctrl.payload = payload

    packet = viro(src=srcVid, dst=dstVid, fd=fdVid)
    packet.next_eth_type = viroctrl.VIRO_CTRL_TYPE
    packet.payload = ctrl

    return packet


def controllerEcho(fromCtrlId, toCtrlId, vid):
    """ Create a controller-to-controller echo packet """
    payload = controller_echo(from_controller_id=fromCtrlId,
                              to_controller_id=toCtrlId,
                              vid=vid)
    return controlPacket(vidNull, vidNull, vidNull, viroctrl.CONTROLLER_ECHO,
                         payload)
Ejemplo n.º 16
0
    def _handle_ViroPacketInIP(self, event):

        IPv4_frame = event.packet
        inport = event.port
        IPv4pkt = IPv4_frame.payload  # Ip packet payload

        log.debug(
            "IPv4 packet in_port=%d, srcvid=%s, dstvid=%s, type=%#04x",
            inport,
            IPv4_frame.src,
            IPv4_frame.dst,
            IPv4_frame.type,
        )

        # Is it to us? (eg. not a DHCP packet)
        if isinstance(IPv4pkt, pkt.dhcp):
            log.debug("%s: packet is a DHCP: it is not for us",
                      str(event.connection))
            return

        # obtain the frame header info.
        srcMac = IPv4_frame.src
        dstMac = IPv4_frame.dst
        ethtype = IPv4_frame.type
        ipv4 = IPv4pkt.srcip

        log.debug("This is the ipv4 packet: {}".format(ipv4))

        n = dstMac.toRaw()
        dst_sw, dst_host = self.sw.vid.getSWHost(n)
        dst_vid = VidAddr(dst_sw, dst_host)

        # find src and dst host objects
        #dist_host = self.local_topo.findHostByVid(dst_vid)
        dist_host = self.local_topo.findHostByMac(dstMac)
        local_host = self.local_topo.findHostByMac(srcMac)

        # if local host does not exist in our topology
        # send a vid request to the remote controller
        # Drop the IPv4 pkts
        if local_host == None:
            packet = pktFactory.vidRequest(srcMac, ipv4, inport)
            msg = msgFactory.controllerEcho(LocalViro.RemoteViro_CONTROLLER_ID,
                                            packet)
            self.sw.connection.send(msg)

            log.debug("Sending a Vid Request pkt to the remote controller")
            return

        # obtain the src VidAddress
        src_vid = local_host.vid

        if dist_host != None:
            ###### Handling packets to src and dst in the same switch ######
            log.debug("src and dst attached to the same switch!")

            lport = dist_host.port
            #dst_mac = dist_host.mac
            #etherpkt = event.packet

            # set the destination macAddress and the source vid
            #etherpkt.src = src_vid.to_raw()
            #etherpkt.dst = dst_mac

            log.debug("forwarding the packet to the next host")
            msg = msgFactory.packetOut(IPv4_frame, lport)
            self.sw.connection.send(msg)

            #---------------------------------------------
            # Add a rule to the switch for future packets
            #---------------------------------------------
            log.debug("pushing the rules to the switch")
            #msg = msgFactory.rewriteMac(src_vid, dstMac, dst_mac, lport)

            # Pushing the rule in both directons
            # a) src --> dst
            msg = msgFactory.rewriteMac(srcMac, dstMac, lport)
            self.sw.connection.send(msg)

            # b) dst --> src
            msg = msgFactory.rewriteMac(dstMac, srcMac, inport)
            self.sw.connection.send(msg)

            return

        else:

            ###### Handling packets to src and dst in different switch ######
            log.debug("Converting IPv4pkts to Viropkts")

            # Generates a Viropkt frame and route it
            log.debug('VidAddress parameters - Src: {} , Dst: {}'.format(
                src_vid, dst_vid))

            viropkt = pktFactory.ViroPacket(src_vid, dst_vid, None, ethtype,
                                            IPv4pkt)
            self.routeViroPacket(viropkt, True)

            log.debug("routing Viro packets")

            #---------------------------------------------
            # Add a rule to the switch for future packets
            #---------------------------------------------
            # log.debug("Port is {}".format(outport))
            msg = msgFactory.encapsulate(srcMac, src_vid, dstMac, dst_vid)
            self.sw.connection.send(msg)

            return
Ejemplo n.º 17
0
    def processDataPacket(self, viropkt, inport):
        """ Process a VIRO data packet """
        # 1.proces the packet
        # 2. Add a rule to the switch to match future requests
        # 3. Need to check if I am the destination of the packet
        # If so remove the forwarding directive, replace the
        # Vid with the mac address with the client mac address and forward
        # the packet to the host: I need to save to which port the client is
        # connected to

        dst = viropkt.dst
        src = viropkt.src
        dst_pkt = VidAddr(dst.sw, 0x00)

        if dst_pkt == self.sw.vid:

            # I am the destination for the packet:
            # converting a Viropkt frame to ethernet frame

            log.debug("Destination VID: {}   myVid: {}".format(
                dst, self.sw.vid))
            datapkt = viropkt.payload
            local_host = self.local_topo.findHostByVid(dst)

            if local_host == None:
                log.debug(
                    "Unknown destination Vid to hosts attached to this switch!"
                )
                return

            srcMac = src.to_raw()
            dstMac = local_host.mac
            lport = local_host.port
            type = viropkt.effective_ethertype

            # Generates a internet frame and route it
            etherpkt = pktFactory.ethernetPkt(type, srcMac, dstMac, datapkt)
            msg = msgFactory.packetOut(etherpkt, lport)
            self.sw.connection.send(msg)

            log.debug("Sending data packets to local hosts")

            #---------------------------------------------
            # Add a rule to the switch for future packets
            #---------------------------------------------
            msg = msgFactory.decapsulate(dstMac, dst, lport)
            self.sw.connection.send(msg)

            return

        else:

            # Viropkt is not for us then route it!
            port = self.routeViroPacket(viropkt)

            #---------------------------------------------
            # Add a rule to the switch for future packets
            #---------------------------------------------
            level = self.sw.vid.delta(dst_pkt)
            prefix = self.sw.vid.bucketPrefix(level)
            dst_vid = int(prefix.replace("*", "0"), 2)
            dst_vid_mask = int(prefix.replace("0", "1").replace("*", "0"), 2)

            msg = msgFactory.pushRoutingTable(dst_vid, dst_vid_mask, port)
            self.sw.connection.send(msg)

            msg = msgFactory.pushRoutingTableETH(dst_vid, dst_vid_mask, port)
            self.sw.connection.send(msg)

            return