Пример #1
0
def _handle_PacketIn(event):
    packet = event.parsed

    if packet.find("arp"):
        # Reply to ARP
        a = packet.find("arp")
        if a.opcode == a.REQUEST:
            r = pkt.arp()
            r.hwtype = a.hwtype
            r.prototype = a.prototype
            r.hwlen = a.hwlen
            r.protolen = a.protolen
            r.opcode = r.REPLY
            r.hwdst = a.hwsrc
            r.protodst = a.protosrc
            r.protosrc = a.protodst
            r.hwsrc = EthAddr("02:00:DE:AD:BE:EF")
            e = pkt.ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc)
            e.payload = r

            msg = of.ofp_packet_out()
            msg.data = e.pack()
            msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
            msg.in_port = event.port
            event.connection.send(msg)

            log.info("%s ARPed for %s", r.protodst, r.protosrc)

    elif packet.find("icmp"):
        # Reply to pings

        # Make the ping reply
        icmp = pkt.icmp()
        icmp.type = pkt.TYPE_ECHO_REPLY
        icmp.payload = packet.find("icmp").payload

        # Make the IP packet around it
        ipp = pkt.ipv4()
        ipp.protocol = ipp.ICMP_PROTOCOL
        ipp.srcip = packet.find("ipv4").dstip
        ipp.dstip = packet.find("ipv4").srcip

        # Ethernet around that...
        e = pkt.ethernet()
        e.src = packet.dst
        e.dst = packet.src
        e.type = e.IP_TYPE

        # Hook them up...
        ipp.payload = icmp
        e.payload = ipp

        # Send it back to the input port
        msg = of.ofp_packet_out()
        msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
        msg.data = e.pack()
        msg.in_port = event.port
        event.connection.send(msg)

        log.debug("%s pinged %s", ipp.dstip, ipp.srcip)
Пример #2
0
def _handle_PacketIn(event):
    packet = event.parsed

    # Learn the source
    table[(event.connection, packet.src)] = event.port

    dst_port = table.get((event.connection, packet.dst))

    if dst_port is None:
        # We don't know where the destination is yet.  So, we'll just
        # send the packet out all ports (except the one it came in on!)
        # and hope the destination is out there somewhere. :)
        msg = of.ofp_packet_out(data=event.ofp)
        msg.actions.append(of.ofp_action_output(port=all_ports))
        event.connection.send(msg)
    else:
        # Since we know the switch ports for both the source and dest
        # MACs, we can install rules for both directions.
        msg = of.ofp_flow_mod()
        msg.match.dl_dst = packet.src
        msg.match.dl_src = packet.dst
        msg.actions.append(of.ofp_action_output(port=event.port))
        event.connection.send(msg)

        # This is the packet that just came in -- we want to
        # install the rule and also resend the packet.
        msg = of.ofp_flow_mod()
        msg.data = event.ofp  # Forward the incoming packet
        msg.match.dl_src = packet.src
        msg.match.dl_dst = packet.dst
        msg.actions.append(of.ofp_action_output(port=dst_port))
        event.connection.send(msg)

        log.debug("Installing %s <-> %s" % (packet.src, packet.dst))
Пример #3
0
    def _do_probe(self):
        """
    Send an ARP to a server to see if it's still up
    """
        self._do_expire()

        server = self.servers.pop(0)
        self.servers.append(server)

        r = arp()
        r.hwtype = r.HW_TYPE_ETHERNET
        r.prototype = r.PROTO_TYPE_IP
        r.opcode = r.REQUEST
        r.hwdst = ETHER_BROADCAST
        r.protodst = server
        r.hwsrc = self.mac
        r.protosrc = self.service_ip
        e = ethernet(type=ethernet.ARP_TYPE, src=self.mac, dst=ETHER_BROADCAST)
        e.set_payload(r)
        #self.log.debug("ARPing for %s", server)
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
        msg.in_port = of.OFPP_NONE
        self.con.send(msg)

        self.outstanding_probes[server] = time.time() + self.arp_timeout

        core.callDelayed(self._probe_wait_time, self._do_probe)
Пример #4
0
def _handle_ConnectionUp(event):
    # Set up this switch.

    # 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)

    # Learning rule in table 0
    msg = nx.nx_flow_mod()
    msg.table_id = 0

    learn = nx.nx_action_learn(table_id=1, hard_timeout=10)
    learn.spec.chain(field=nx.NXM_OF_VLAN_TCI,
                     n_bits=12).chain(field=nx.NXM_OF_ETH_SRC,
                                      match=nx.NXM_OF_ETH_DST).chain(
                                          field=nx.NXM_OF_IN_PORT, output=True)

    msg.actions.append(learn)
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(1))
    event.connection.send(msg)

    # Fallthrough rule for table 1: flood
    msg = nx.nx_flow_mod()
    msg.table_id = 1
    msg.priority = 1  # Low priority
    msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
    event.connection.send(msg)
Пример #5
0
 def _handle_ConnectionUp (self, event):
   if _install_flow:
     fm = of.ofp_flow_mod()
     fm.priority = 0x7000 # Pretty high
     fm.match.dl_type = ethernet.ARP_TYPE
     fm.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
     event.connection.send(fm)
Пример #6
0
  def create_discovery_packet (self, dpid, port_num, port_addr):
    """
    Build discovery packet
    """

    chassis_id = pkt.chassis_id(subtype=pkt.chassis_id.SUB_LOCAL)
    chassis_id.id = bytes('dpid:' + hex(long(dpid))[2:-1])
    # Maybe this should be a MAC.  But a MAC of what?  Local port, maybe?

    port_id = pkt.port_id(subtype=pkt.port_id.SUB_PORT, id=str(port_num))

    ttl = pkt.ttl(ttl = self._ttl)

    sysdesc = pkt.system_description()
    sysdesc.payload = bytes('dpid:' + hex(long(dpid))[2:-1])

    discovery_packet = pkt.lldp()
    discovery_packet.tlvs.append(chassis_id)
    discovery_packet.tlvs.append(port_id)
    discovery_packet.tlvs.append(ttl)
    discovery_packet.tlvs.append(sysdesc)
    discovery_packet.tlvs.append(pkt.end_tlv())

    eth = pkt.ethernet(type=pkt.ethernet.LLDP_TYPE)
    eth.src = port_addr
    eth.dst = pkt.ETHERNET.NDP_MULTICAST
    eth.payload = discovery_packet

    po = of.ofp_packet_out(action = of.ofp_action_output(port=port_num))
    po.data = eth.pack()
    return po.pack()
Пример #7
0
def send_arp_reply(reply_to, mac, src_mac=None, src_ip=None):
    """
  Send an ARP reply.

  src_mac can be None to use the "DPID MAC" or True to use the port Mac.
    (or it can be an EthAddr)
  """
    # reply_to should be a PacketIn event
    arpp = reply_to.parsed.find('arp')
    mac = EthAddr(mac)
    if src_mac is None:
        #src_mac = mac # Used to be this ???
        src_mac = reply_to.connection.eth_addr
    elif src_mac is True:
        src_mac = reply_to.connection.ports[reply_to.port].hw_addr
    else:
        src_mac = EthAddr(src_mac)
    r = arp()
    r.opcode = r.REPLY
    r.hwdst = arpp.hwsrc
    r.protodst = arpp.protosrc
    r.hwsrc = EthAddr(src_mac)
    r.protosrc = IPAddr("0.0.0.0") if src_ip is None else IPAddr(src_ip)
    e = ethernet(type=ethernet.ARP_TYPE, src=src_mac, dst=r.hwdst)
    e.payload = r
    msg = of.ofp_packet_out()
    msg.data = e.pack()
    msg.actions.append(of.ofp_action_output(port=reply_to.port))
    msg.in_port = of.OFPP_NONE
    reply_to.connection.send(msg)
Пример #8
0
 def sendPing(self, macEntry, ipAddr):
     """
 Builds an ETH/IP any-to-any ARP packet (an "ARP ping")
 """
     r = arp()
     r.opcode = arp.REQUEST
     r.hwdst = macEntry.macaddr
     r.hwsrc = self.ping_src_mac
     r.protodst = ipAddr
     # src is IP_ANY
     e = ethernet(type=ethernet.ARP_TYPE, src=r.hwsrc, dst=r.hwdst)
     e.payload = r
     log.debug("%i %i sending ARP REQ to %s %s", macEntry.dpid,
               macEntry.port, str(r.hwdst), str(r.protodst))
     msg = of.ofp_packet_out(
         data=e.pack(), action=of.ofp_action_output(port=macEntry.port))
     if core.openflow.sendToDPID(macEntry.dpid, msg.pack()):
         ipEntry = macEntry.ipAddrs[ipAddr]
         ipEntry.pings.sent()
     else:
         # macEntry is stale, remove it.
         log.debug("%i %i ERROR sending ARP REQ to %s %s", macEntry.dpid,
                   macEntry.port, str(r.hwdst), str(r.protodst))
         del macEntry.ipAddrs[ipAddr]
     return
Пример #9
0
  def reply (self, event, msg):
    orig = event.parsed.find('dhcp')
    broadcast = (orig.flags & orig.BROADCAST_FLAG) != 0
    msg.op = msg.BOOTREPLY
    msg.chaddr = event.parsed.src
    msg.htype = 1
    msg.hlen = 6
    msg.xid = orig.xid
    msg.add_option(pkt.DHCP.DHCPServerIdentifierOption(self.ip_addr))

    ethp = pkt.ethernet(src=ip_for_event(event),dst=event.parsed.src)
    ethp.type = pkt.ethernet.IP_TYPE
    ipp = pkt.ipv4(srcip = self.ip_addr)
    ipp.dstip = event.parsed.find('ipv4').srcip
    if broadcast:
      ipp.dstip = IP_BROADCAST
      ethp.dst = pkt.ETHERNET.ETHER_BROADCAST
    ipp.protocol = ipp.UDP_PROTOCOL
    udpp = pkt.udp()
    udpp.srcport = pkt.dhcp.SERVER_PORT
    udpp.dstport = pkt.dhcp.CLIENT_PORT
    udpp.payload = msg
    ipp.payload = udpp
    ethp.payload = ipp
    po = of.ofp_packet_out(data=ethp.pack())
    po.actions.append(of.ofp_action_output(port=event.port))
    event.connection.send(po)
Пример #10
0
 def _handle_ConnectionUp (self, event):
   if self._install_flow:
     msg = of.ofp_flow_mod()
     msg.match = of.ofp_match()
     msg.match.dl_type = pkt.ethernet.IP_TYPE
     msg.match.nw_proto = pkt.ipv4.UDP_PROTOCOL
     msg.match.tp_src = 53
     msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
     event.connection.send(msg)
Пример #11
0
 def _install(self, switch, in_port, out_port, match, buf=None):
     msg = of.ofp_flow_mod()
     msg.match = match
     msg.match.in_port = in_port
     msg.idle_timeout = FLOW_IDLE_TIMEOUT
     msg.hard_timeout = FLOW_HARD_TIMEOUT
     msg.actions.append(of.ofp_action_output(port=out_port))
     msg.buffer_id = buf
     switch.connection.send(msg)
Пример #12
0
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed

        a = packet.find('arp')
        if not a: return

        if a.prototype != arp.PROTO_TYPE_IP:
            return

        if a.hwtype != arp.HW_TYPE_ETHERNET:
            return

        if a.opcode == arp.REQUEST:
            log.debug("%s ARP request %s => %s", dpid_to_str(dpid), a.protosrc,
                      a.protodst)

            if self.use_port_mac:
                src_mac = event.connection.ports[inport].hw_addr
            else:
                src_mac = event.connection.eth_addr
            ev = ARPRequest(event.connection, a, src_mac, self.eat_packets,
                            inport)
            self.raiseEvent(ev)
            if ev.reply is not None:
                r = arp()
                r.hwtype = a.hwtype
                r.prototype = a.prototype
                r.hwlen = a.hwlen
                r.protolen = a.protolen
                r.opcode = arp.REPLY
                r.hwdst = a.hwsrc
                r.protodst = a.protosrc
                r.protosrc = a.protodst
                r.hwsrc = EthAddr(ev.reply)
                e = ethernet(type=packet.type, src=ev.reply_from, dst=a.hwsrc)
                e.payload = r
                log.debug("%s answering ARP for %s" %
                          (dpid_to_str(dpid), str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
                msg.in_port = inport
                event.connection.send(msg)
                return EventHalt if ev.eat_packet else None

        elif a.opcode == arp.REPLY:
            log.debug("%s ARP reply %s => %s", dpid_to_str(dpid), a.protosrc,
                      a.hwsrc)

            ev = ARPReply(event.connection, a, self.eat_packets, inport)
            self.raiseEvent(ev)
            return EventHalt if ev.eat_packet else None

        return EventHalt if self.eat_packets else None
Пример #13
0
def _handle_ConnectionUp(event):
    # Set up this switch.
    # After setting up, we send a barrier and wait for the response
    # before starting to listen to packet_ins for this switch -- before
    # the switch is set up, the packet_ins may not be what we expect,
    # and our responses may not work!

    # Turn on Nicira packet_ins
    msg = nx.nx_packet_in_format()
    event.connection.send(msg)

    # 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_output(port=of.OFPP_CONTROLLER))
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    event.connection.send(msg)

    # Fallthrough rule for table 1: flood
    msg = nx.nx_flow_mod()
    msg.table_id = 1
    msg.priority = 1  # Low priority
    msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
    event.connection.send(msg)

    def ready(event):
        if event.ofp.xid != 0x80000000:
            # Not the right barrier
            return
        log.info("%s ready", event.connection)
        event.connection.addListenerByName("PacketIn", _handle_PacketIn)
        return EventRemove

    event.connection.send(of.ofp_barrier_request(xid=0x80000000))
    event.connection.addListenerByName("BarrierIn", ready)
Пример #14
0
 def flood():
     """ Floods the packet """
     if self.is_holding_down:
         log.warning("Not flooding -- holddown active")
     msg = of.ofp_packet_out()
     # OFPP_FLOOD is optional; some switches may need OFPP_ALL
     msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
     msg.buffer_id = event.ofp.buffer_id
     msg.in_port = event.port
     self.connection.send(msg)
Пример #15
0
    def install_path(self, dst_sw, last_port, match, event):
        """
    Attempts to install a path between this switch and some destination
    """
        p = _get_path(self, dst_sw, event.port, last_port)
        if p is None:
            log.warning("Can't get from %s to %s", match.dl_src, match.dl_dst)

            import pox.lib.packet as pkt

            if (match.dl_type == pkt.ethernet.IP_TYPE
                    and event.parsed.find('ipv4')):
                # It's IP -- let's send a destination unreachable
                log.debug("Dest unreachable (%s -> %s)", match.dl_src,
                          match.dl_dst)

                from pox.lib.addresses import EthAddr
                e = pkt.ethernet()
                e.src = EthAddr(dpid_to_str(self.dpid))  #FIXME: Hmm...
                e.dst = match.dl_src
                e.type = e.IP_TYPE
                ipp = pkt.ipv4()
                ipp.protocol = ipp.ICMP_PROTOCOL
                ipp.srcip = match.nw_dst  #FIXME: Ridiculous
                ipp.dstip = match.nw_src
                icmp = pkt.icmp()
                icmp.type = pkt.ICMP.TYPE_DEST_UNREACH
                icmp.code = pkt.ICMP.CODE_UNREACH_HOST
                orig_ip = event.parsed.find('ipv4')

                d = orig_ip.pack()
                d = d[:orig_ip.hl * 4 + 8]
                import struct
                d = struct.pack("!HH", 0, 0) + d  #FIXME: MTU
                icmp.payload = d
                ipp.payload = icmp
                e.payload = ipp
                msg = of.ofp_packet_out()
                msg.actions.append(of.ofp_action_output(port=event.port))
                msg.data = e.pack()
                self.connection.send(msg)

            return

        log.debug("Installing path for %s -> %s %04x (%i hops)", match.dl_src,
                  match.dl_dst, match.dl_type, len(p))

        # We have a path -- install it
        self._install_path(p, match, event.ofp)

        # Now reverse it and install it backwards
        # (we'll just assume that will work)
        p = [(sw, out_port, in_port) for sw, in_port, out_port in p]
        self._install_path(p, match.flip())
Пример #16
0
    def _send_rewrite_rule(self, ip, mac):
        p = ipinfo(ip)[1]

        msg = of.ofp_flow_mod()
        msg.match = of.ofp_match()
        msg.match.dl_type = pkt.ethernet.IP_TYPE
        msg.match.nw_dst = ip
        msg.actions.append(of.ofp_action_dl_addr.set_src(self.mac))
        msg.actions.append(of.ofp_action_dl_addr.set_dst(mac))
        msg.actions.append(of.ofp_action_output(port=p))
        self.connection.send(msg)
Пример #17
0
    def _handle_openflow_ConnectionUp(self, event):
        if not self.install_flow: return

        log.debug("Installing flow for ARP ping responses")

        m = of.ofp_flow_mod()
        m.priority += 1  # Higher than normal
        m.match.dl_type = ethernet.ARP_TYPE
        m.match.dl_dst = self.ping_src_mac

        m.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
        event.connection.send(m)
Пример #18
0
 def _handle_ConnectionUp (self, event):
   if self._install_flow:
     msg = of.ofp_flow_mod()
     msg.match = of.ofp_match()
     msg.match.dl_type = pkt.ethernet.IP_TYPE
     msg.match.nw_proto = pkt.ipv4.UDP_PROTOCOL
     #msg.match.nw_dst = IP_BROADCAST
     msg.match.tp_src = pkt.dhcp.CLIENT_PORT
     msg.match.tp_dst = pkt.dhcp.SERVER_PORT
     msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
     #msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
     event.connection.send(msg)
Пример #19
0
    def notify(self, event):
        """
    Called when a barrier has been received
    """
        self.xids.discard((event.dpid, event.xid))
        if len(self.xids) == 0:
            # Done!
            if self.packet:
                log.debug("Sending delayed packet out %s" %
                          (dpid_to_str(self.first_switch), ))
                msg = of.ofp_packet_out(
                    data=self.packet,
                    action=of.ofp_action_output(port=of.OFPP_TABLE))
                core.openflow.sendToDPID(self.first_switch, msg)

            core.l2_multi.raiseEvent(PathInstalled(self.path))
Пример #20
0
 def _send_lost_buffers (self, dpid, ipaddr, macaddr, port):
   """
   We may have "lost" buffers -- packets we got but didn't know
   where to send at the time.  We may know now.  Try and see.
   """
   if (dpid,ipaddr) in self.lost_buffers:
     # Yup!
     bucket = self.lost_buffers[(dpid,ipaddr)]
     del self.lost_buffers[(dpid,ipaddr)]
     log.debug("Sending %i buffered packets to %s from %s"
               % (len(bucket),ipaddr,dpid_to_str(dpid)))
     for _,buffer_id,in_port in bucket:
       po = of.ofp_packet_out(buffer_id=buffer_id,in_port=in_port)
       po.actions.append(of.ofp_action_dl_addr.set_dst(macaddr))
       po.actions.append(of.ofp_action_output(port = port))
       core.openflow.sendToDPID(dpid, po)
Пример #21
0
 def _send_dhcp(self, msg):
     ethp = pkt.ethernet(src=self.port_eth, dst=pkt.ETHER_BROADCAST)
     ethp.type = pkt.ethernet.IP_TYPE
     ipp = pkt.ipv4()
     ipp.srcip = pkt.IP_ANY  #NOTE: If rebinding, use existing local IP?
     ipp.dstip = pkt.IP_BROADCAST
     ipp.protocol = ipp.UDP_PROTOCOL
     udpp = pkt.udp()
     udpp.srcport = pkt.dhcp.CLIENT_PORT
     udpp.dstport = pkt.dhcp.SERVER_PORT
     udpp.payload = msg
     ipp.payload = udpp
     ethp.payload = ipp
     po = of.ofp_packet_out(data=ethp.pack())
     po.actions.append(of.ofp_action_output(port=self.portno))
     self._con.send(po)
Пример #22
0
    def resend_packet(self, packet_in, out_port):
        """
    Instructs the switch to resend a packet that it had sent to us.
    "packet_in" is the ofp_packet_in object the switch had sent to the
    controller due to a table-miss.
    """
        msg = of.ofp_packet_out()
        msg.data = packet_in

        # Add an action to send to the specified port
        action = of.ofp_action_output(port=out_port)
        msg.actions.append(action)

        log.debug(" OF_TUTORIAL : Message being sent on the connection : %s " %
                  msg)
        # Send message to switch
        self.connection.send(msg)
        log.debug(" OF_TUTORIAL : Message sent to the switch")
        log.debug(" OF_TUTORIAL : --------------------------")
Пример #23
0
def send_arp_request(connection,
                     ip,
                     port=of.OFPP_FLOOD,
                     src_mac=None,
                     src_ip=None):
    """
  Send an ARP request

  src_mac can be None to use the "DPID MAC" or True to use the port Mac.
    (or it can be an EthAddr)
  """
    if src_mac is None:
        src_mac = connection.eth_addr
    elif src_mac is True:
        if port in (of.OFPP_FLOOD, of.OFPP_ALL):
            for p in connection.ports.values():
                if p.config & OFPPC_NO_FLOOD:
                    if port == of.ofPP_FLOOD:
                        continue
                if p.port_no < 0: continue
                if p.port_no > of.OFPP_MAX: continue  # Off by one?
                send_arp_request(connection,
                                 ip,
                                 p.port_no,
                                 src_mac=p.hw_addr,
                                 src_ip=src_ip)
            return
        src_mac = connection.ports[port].hw_addr
    else:
        src_mac = EthAddr(src_mac)
    r = arp()
    r.opcode = r.REQUEST
    r.hwdst = ETHER_BROADCAST
    r.protodst = IPAddr(ip)
    r.hwsrc = src_mac
    r.protosrc = IPAddr("0.0.0.0") if src_ip is None else IPAddr(src_ip)
    e = ethernet(type=ethernet.ARP_TYPE, src=src_mac, dst=r.hwdst)
    e.payload = r
    msg = of.ofp_packet_out()
    msg.data = e.pack()
    msg.actions.append(of.ofp_action_output(port=port))
    msg.in_port = of.OFPP_NONE
    connection.send(msg)
Пример #24
0
  def install_flow (self, con_or_dpid, priority = None):
    if priority is None:
      priority = self._flow_priority
    if isinstance(con_or_dpid, (int,long)):
      con = core.openflow.connections.get(con_or_dpid)
      if con is None:
        log.warn("Can't install flow for %s", dpid_to_str(con_or_dpid))
        return False
    else:
      con = con_or_dpid

    match = of.ofp_match(dl_type = pkt.ethernet.LLDP_TYPE,
                          dl_dst = pkt.ETHERNET.NDP_MULTICAST)
    msg = of.ofp_flow_mod()
    msg.priority = priority
    msg.match = match
    msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
    con.send(msg)
    return True
Пример #25
0
    def _start(self, connection):
        self._connection = connection

        self._outside_portno = connection.ports[self.outside_port].port_no

        fm = of.ofp_flow_mod()
        fm.match.in_port = self._outside_portno
        fm.priority = 1
        connection.send(fm)

        fm = of.ofp_flow_mod()
        fm.match.in_port = self._outside_portno
        fm.match.dl_type = 0x800  # IP
        fm.match.nw_dst = self.outside_ip
        fm.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
        fm.priority = 2
        connection.send(fm)

        connection.addListeners(self)

        # Need to find gateway MAC -- send an ARP
        self._arp_for_gateway()
Пример #26
0
def _handle_PacketIn(event):
    packet = event.parsed

    if event.port > of.OFPP_MAX:
        log.debug("Ignoring special port %s", event.port)
        return

    # Add to source table
    msg = nx.nx_flow_mod()
    msg.match.of_eth_src = packet.src
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    event.connection.send(msg)

    # Add to destination table
    msg = nx.nx_flow_mod()
    msg.table_id = 1
    msg.match.of_eth_dst = packet.src
    msg.actions.append(of.ofp_action_output(port=event.port))
    event.connection.send(msg)

    log.info("Learning %s on port %s of %s" %
             (packet.src, event.port, event.connection))
Пример #27
0
def dict_to_flow_mod(flow):
    match = flow.get('match')
    if match is None:
        match = of.ofp_match()
    else:
        match = dict_to_match(match)

    actions = flow.get('actions', [])
    if not isinstance(actions, list): actions = [actions]
    actions = [dict_to_action(a) for a in actions]
    if 'output' in flow:
        a = of.ofp_action_output(port=_fix_of_int(flow['output']))
        po.actions.append(a)

    fm = of.ofp_flow_mod(match=match)
    fm.actions = actions

    for k in ['cookie', 'idle_timeout', 'hard_timeout', 'priority']:
        if k in flow:
            setattr(fm, k, flow[k])

    return fm
Пример #28
0
def dict_to_packet_out(d):
    """
  Converts dict to packet_out
  Also, special key "output" is an output port.
  """
    po = of.ofp_packet_out()
    po.buffer_id = d.get('buffer_id', -1)
    po.in_port = _fix_of_int(d.get('in_port', of.OFPP_NONE))
    actions = d.get('actions', [])
    actions = [dict_to_action(a) for a in actions]
    po.actions = actions
    if 'output' in d:
        a = of.ofp_action_output(port=_fix_of_int(d['output']))
        po.actions.append(a)

    if 'data' in d:
        data = dict_to_packet(d['data'])
        if hasattr(data, 'pack'):
            data = data.pack()
        po.data = data

    return po
Пример #29
0
        def flood(message=None):
            """ Floods the packet """
            msg = of.ofp_packet_out()
            if time.time() - self.connection.connect_time >= _flood_delay:
                # Only flood if we've been connected for a little while...

                if self.hold_down_expired is False:
                    # Oh yes it is!
                    self.hold_down_expired = True
                    log.info("%s: Flood hold-down expired -- flooding",
                             dpid_to_str(event.dpid))

                if message is not None: log.debug(message)
                #log.debug("%i: flood %s -> %s", event.dpid,packet.src,packet.dst)
                # OFPP_FLOOD is optional; on some switches you may need to change
                # this to OFPP_ALL.
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
            else:
                pass
                #log.info("Holding down flood for %s", dpid_to_str(event.dpid))
            msg.data = event.ofp
            msg.in_port = event.port
            self.connection.send(msg)
Пример #30
0
  def _handle_PacketIn (self, event):
    # Note: arp.hwsrc is not necessarily equal to ethernet.src
    # (one such example are arp replies generated by this module itself
    # as ethernet mac is set to switch dpid) so we should be careful
    # to use only arp addresses in the learning code!
    squelch = False

    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed
    if not packet.parsed:
      log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid))
      return

    a = packet.find('arp')
    if not a: return

    log.debug("%s ARP %s %s => %s", dpid_to_str(dpid),
      {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
      'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst))

    if a.prototype == arp.PROTO_TYPE_IP:
      if a.hwtype == arp.HW_TYPE_ETHERNET:
        if a.protosrc != 0:

          if _learn:
            # Learn or update port/MAC info
            if a.protosrc in _arp_table:
              if _arp_table[a.protosrc] != a.hwsrc:
                log.warn("%s RE-learned %s: %s->%s", dpid_to_str(dpid),
                    a.protosrc, _arp_table[a.protosrc].mac, a.hwsrc)
            else:
              log.info("%s learned %s", dpid_to_str(dpid), a.protosrc)
            _arp_table[a.protosrc] = Entry(a.hwsrc)

          if a.opcode == arp.REQUEST:
            # Maybe we can answer

            if a.protodst in _arp_table:
              # We have an answer...

              r = arp()
              r.hwtype = a.hwtype
              r.prototype = a.prototype
              r.hwlen = a.hwlen
              r.protolen = a.protolen
              r.opcode = arp.REPLY
              r.hwdst = a.hwsrc
              r.protodst = a.protosrc
              r.protosrc = a.protodst
              mac = _arp_table[a.protodst].mac
              if mac is True:
                # Special case -- use ourself
                mac = _dpid_to_mac(dpid)
              r.hwsrc = mac
              e = ethernet(type=packet.type, src=_dpid_to_mac(dpid),
                            dst=a.hwsrc)
              e.payload = r
              if packet.type == ethernet.VLAN_TYPE:
                v_rcv = packet.find('vlan')
                e.payload = vlan(eth_type = e.type,
                                 payload = e.payload,
                                 id = v_rcv.id,
                                 pcp = v_rcv.pcp)
                e.type = ethernet.VLAN_TYPE
              log.info("%s answering ARP for %s" % (dpid_to_str(dpid),
                str(r.protosrc)))
              msg = of.ofp_packet_out()
              msg.data = e.pack()
              msg.actions.append(of.ofp_action_output(port =
                                                      of.OFPP_IN_PORT))
              msg.in_port = inport
              event.connection.send(msg)
              return EventHalt if _eat_packets else None
            else:
              # Keep track of failed queries
              squelch = a.protodst in _failed_queries
              _failed_queries[a.protodst] = time.time()

    if self._check_for_flood(dpid, a):
      # Didn't know how to handle this ARP, so just flood it
      msg = "%s flooding ARP %s %s => %s" % (dpid_to_str(dpid),
          {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
          'op:%i' % (a.opcode,)), a.protosrc, a.protodst)

      if squelch:
        log.debug(msg)
      else:
        log.info(msg)

      msg = of.ofp_packet_out()
      msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
      msg.data = event.ofp
      event.connection.send(msg.pack())

    return EventHalt if _eat_packets else None