[pox-dev] how to specify wildcards in ofp_match.from_packet()?
William Emmanuel Yu
wyu at ateneo.edu
Wed Sep 26 02:32:26 PDT 2012
Hi,
I implemented your recommendation the packet_out() bit and created a
version that uses resend (required the betta branch of pox) as well. You
are right. I now have a version that does not drop packets (except for
the new at the start when the switch isn't discovered yet).
https://github.com/hip2b2/poxstuff/blob/master/of_sw_tutorial.py
https://github.com/hip2b2/poxstuff/blob/master/of_sw_tutorial_resend.py
Additional, the new implementation of BAD SWITCH demonstrates the
problem with one sided route adding as it will always trigger a
broadcast thus showing the inefficiency.
Thank you for your help. On to the next project.
On Tue, 2012-09-25 at 02:58 -0700, Murphy McCauley wrote:
> Yeah. What you describe there is more or less how ofp_packet_out handles resend. But there's also resend for flow_mods, which is a little bit of a hack, but useful. For flow_mods, if the buffer_id is available, it puts that in the flow_mod. If there's no buffer_id but there is data, it actually installs the flow and then sends a packet_out with the data to OFPP_TABLE (with the assumption that the packet will hit the new table entry which is not necessarily true, but is hopefully a reasonable assumption).
>
> Another note is that I think you might be better off doing just "if event.ofp.data:" because that will also skip it when it's an empty string.
>
> -- Murphy
>
> On Sep 25, 2012, at 2:51 AM, William Emmanuel Yu wrote:
>
> > You are right! I am dropping packets. But I just though it was because
> > PING timed out while the flow was being registered.
> >
> > Is there a better way of doing this?
> >
> > def send_packet (event, dst_port = of.OFPP_ALL):
> > msg = of.ofp_packet_out(in_port=event.ofp.in_port)
> > if event.ofp.buffer_id != -1 and event.ofp.buffer_id is not None:
> > # We got a buffer ID from the switch; use that
> > msg.buffer_id = event.ofp.buffer_id
> > else:
> > # No buffer ID from switch -- we got the raw data
> > if event.ofp.data is None:
> > # No raw_data specified -- nothing to send!
> > return
> > msg.data = event.ofp.data
> > msg.actions.append(of.ofp_action_output(port = dst_port))
> > event.connection.send(msg)
> >
> > Of course, I will probably use resend but it might be useful how to do
> > it properly with primitives.
> >
> > Thanks.
> >
> > On Tue, 2012-09-25 at 01:24 -0700, Murphy McCauley wrote:
> >> 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
> >
> > --
> > -------------------------------------------------------
> > William Emmanuel S. Yu, Ph.D. (杨怀义)
> > Department of Information Systems and Computer Science
> > Ateneo de Manila University
> > email : wyu at ateneo dot edu
> > blog : http://hip2b2.yutivo.org/
> > web : http://CNG.ateneo.edu/cng/wyu/
> > phone : +63(2)4266001 loc. 4186
> > GPG : http://CNG.ateneo.net/cng/wyu/wyy.pgp
> >
> > Confidentiality Issue: This message is intended only for the use of the
> > addressee and may contain information that is privileged and
> > confidential. If you are not the intended recipient, you are hereby
> > notified that any use or dissemination of this communication is strictly
> > prohibited. If you have received this communication in error, please
> > notify us immediately by reply and delete this message from your system.
> >
>
--
-------------------------------------------------------
William Emmanuel S. Yu, Ph.D. (杨怀义)
Department of Information Systems and Computer Science
Ateneo de Manila University
email : wyu at ateneo dot edu
blog : http://hip2b2.yutivo.org/
web : http://CNG.ateneo.edu/cng/wyu/
phone : +63(2)4266001 loc. 4186
GPG : http://CNG.ateneo.net/cng/wyu/wyy.pgp
Confidentiality Issue: This message is intended only for the use of the
addressee and may contain information that is privileged and
confidential. If you are not the intended recipient, you are hereby
notified that any use or dissemination of this communication is strictly
prohibited. If you have received this communication in error, please
notify us immediately by reply and delete this message from your system.
More information about the pox-dev
mailing list