[pox-dev] how to specify wildcards in ofp_match.from_packet()?

Murphy McCauley murphy.mccauley at gmail.com
Tue Sep 25 01:24:20 PDT 2012


Hey, thanks for sharing this!

On Sep 25, 2012, at 1:00 AM, William Emmanuel Yu wrote:
> I implemented both a BAD SWITCH (that only does destination MAC mapping)
> and a PAIR-WISE SWITCH (that does both source and destination MAC
> mapping). Mysteriously, both switches work identically. 

I'll offer an explanation.

You do something a bit atypical in _handle_BadSwitch_PacketIn -- you don't install the rule as soon as possible.  It still has the if statement from the pair switch which checks that you know dst_port -- at which point you know both ends.  You don't actually "need" that, since you only need the source port (which you always have) in order to install the problematic "learned" table entry.  So a more straightforward implementation actually looks something like:

def _handle_BadSwitch_PacketIn (event):
  packet = event.parsed

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

  # Learn on switch -- install table entry
  msg = of.ofp_flow_mod()
  msg.idle_timeout = 10
  msg.hard_timeout = 30
  msg.match.dl_dst = packet.src
  msg.actions.append(of.ofp_action_output(port = event.port))
  event.connection.send(msg)

  log.debug("Installing rule for dest %s" % (packet.src,))

  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. :)
    # To send out all ports, we can use either of the special ports
    # OFPP_FLOOD or OFPP_ALL. We'd like to just use OFPP_FLOOD,
    # but it's not clear if all switches support this. :(
    bcast_packet(event)

    log.debug("Broadcasting %s.%i -> %s.%i" %
      (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))
  else:
    po = of.ofp_packet_out(in_port = event.port,
        buffer_id = event.ofp.buffer_id,
        action = of.ofp_action_output(port = dst_port))
    event.connection.send(po)

 Doing it how you have it essentially buys you one "delay slot".  If you had several hosts, you wouldn't learn any more after the first two or something like that.

> Also in my pox repo the following:
> 
>    msg = of.ofp_packet_out(resend = event.ofp)
>    msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
>    msg.send(event.connection)
> 
> does not seem to work as my of.ofp_packet_out() does not support the
> resend attribute. The msg object does not have a send() function. So I
> re-wrote it again what I knew already worked which is in my
> bcast_packet() function.

resend is very new; but is now in the betta branch of the main repository.  It's actually fairly useful, as it handles both cases of resends -- when you have a buffer_id and when you have packet data.  This saves you the trouble of having to figure it out yourself, which you kind of have to do because it's actually hard to tell what the switch might do.  As it is, I think your code is actually dropping packets because you're not using resend or trying to take the buffer_id from the packet_in and put it in the new flow_mods.


-- Murphy


More information about the pox-dev mailing list