<html><head></head><body bgcolor="#FFFFFF"><div>That all makes sense, the VLAN vs non-VLAN stuff is going to be an ongoing issue I think.</div><div><br></div><div>On a slightly related note, I've made a tun/tap module for POX that I'll share next week, and the VLAN thing makes a mess of it given the packets need to be straight Ethernet when going into tap0. On my Pronto 3780 I get latency from 1-50ms and about 4Mb/s for extended transfers, but it does mean we can plug a software router directly into the controller instead of using virtual machines like in RouteFlow,</div>
<div><br></div><div>Nice interview for SDN Central btw<br><br>Sent from my iPhone</div><div><br>On Sep 7, 2012, at 4:56 PM, Murphy McCauley <<a href="mailto:murphy.mccauley@gmail.com">murphy.mccauley@gmail.com</a>> wrote:<br>
<br></div><div></div><blockquote type="cite"><div>I agree with you in theory, though I think a design like that is liable to either be somewhat more brittle or somewhat more complex (or both). Issues like making it work well when *building* a chain of packets from scratch may complicate it, for example. And then there's the question of what you really mean... if you have a VLAN in an L2-in-L3 tunnel that's running on a non-VLAN. If you ask for the VLAN header from the "root" packet, what do you get? I argue that using find() or something that works like find() gets you an answer that you may well not want. Actually crawling the structure yourself makes it much clearer, even though it's more of a pain, but hopefully things like the effective_ethertype shortcut can take some of the pain from the common cases.<div>
<br></div><div>There are other things about the packet library that could use improving too... *I* certainly have not been worried enough about the efficiency of this operation to try to optimize it. I'm also not sure the performance improvement is obvious in common cases. Which is more expensive: searching through four nested packet objects looking for a particular one twice, or searching through once so that you can build a hashed map to each header and then doing two hashed lookups? I actually don't know, but I have my suspicions.</div>
<div><br></div><div>The optimization I'm more interested in is parse-on-demand, but I've never thought too hard about how to do it well.</div><div><br></div><div>-- Murphy</div><div><br><div><div><div>On Aug 31, 2012, at 10:08 PM, Sam Russell wrote:</div>
<br class="Apple-interchange-newline"><blockquote type="cite">Sorry for the spam<div><br></div><div>I think I'm trying to say that I want something more deterministic - we should only have to recurse through the packet headers once when we parse the packet, and any references afterwards should just be lookups instead of having to recurse again.</div>
<div><br></div><div>Is this right, or am I going a bit overboard on trying to optimise things?<br><br><div class="gmail_quote">On Sat, Sep 1, 2012 at 4:58 PM, Sam Russell <span dir="ltr"><<a href="mailto:sam.h.russell@gmail.com" target="_blank">sam.h.russell@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The find() function does look good though, I'll try reimplementing using that<div class="HOEnZb"><div class="h5"><br>
<br><div class="gmail_quote">On Sat, Sep 1, 2012 at 4:42 PM, Sam Russell <span dir="ltr"><<a href="mailto:sam.h.russell@gmail.com" target="_blank">sam.h.russell@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Something like that. When the OpenFlow match is created, it recurses through packet.next to find all the details, and checks the instance of each one. Once it's done with this, could we cast (do you cast in Python?) the packet in something else?<div>
<br></div><div>For example, if it's a ping packet, then could you cast it as follows:</div><div><br></div><div>EthernetPacket subclasses Packet</div><div>IPPacket subclasses EthernetPacket</div><div>ICMPPacket subclasses IPPacket</div>
<div>EchoPacket subclasses ICMPPacket</div><div><br></div><div>You could then do tests, to check if it's an instance of IPPacket, then of ICMPPacket, then EchoPacket, and if it's an EchoPacket then you could reference anything from the echo packet, plus anything below (MAC addresses, IP addresses etc)</div>
<div><div>
<div><div><br><div class="gmail_quote">On Sat, Sep 1, 2012 at 4:14 PM, Murphy McCauley <span dir="ltr"><<a href="mailto:murphy.mccauley@gmail.com" target="_blank">murphy.mccauley@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<p>You can do pkt.find('icmp') for example to find a deeper header by name or type. Something like that?</p><p>(Excuse brevity; on phone)</p><div><div>
<div class="gmail_quote">On Aug 31, 2012 7:52 PM, "Sam Russell" <<a href="mailto:sam.h.russell@gmail.com" target="_blank">sam.h.russell@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
That looks useful, I think there could be a better way though - is there any easy way to do a quick parse of a packet and create pointers to useful parts? For example, if I know that a packet is ping (ICMP echo request), is it useful to be able to check if packet.echo exists and then reference that?<br>
<br><div class="gmail_quote">On Fri, Aug 31, 2012 at 12:07 PM, Murphy McCauley <span dir="ltr"><<a href="mailto:murphy.mccauley@gmail.com" target="_blank">murphy.mccauley@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word">I guess I mean effective_ethertype. :) In particular, check out 42cec08c23 on MurphyMc/pox. The commits after that show its usage a bit as they fix similar issues to the one you called out but in l2_multi and discovery. I guess we should be doing this for l2_learning too (and possibly some other things?).<span><font color="#888888"><div>
<br></div></font></span><div><span><font color="#888888"><div>-- Murphy</div></font></span><div><div><div><br><div><div><div>On Aug 30, 2012, at 2:06 PM, Murphy McCauley wrote:</div><br><blockquote type="cite"><p>Check out the "effective_type" attribute in my fork's packet class.</p>
<p>(Excuse brevity -- on my phone)</p>
<div class="gmail_quote">On Aug 30, 2012 1:12 PM, "Sam Russell" <<a href="mailto:sam.h.russell@gmail.com" target="_blank">sam.h.russell@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I've been trying to build some router functionality into POX, and I'm coming across a similar problem to what ofp_match() used to have - here's a snippet from l2_learning:<div><br></div><div># my code</div><div>
<div> if packet.type == packet.ARP_TYPE:</div><div> print "ARP packet"</div><div> else:</div><div><span style="white-space:pre-wrap"> </span> print "Packet type: " + str(packet.type)</div>
<div><br></div><div># next line, what I've based my code on</div><div> if not self.transparent:</div><div> if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered(): # 2</div><div> drop()</div>
<div> return</div></div><div><br></div><div>The problem with the Pronto switches is that they pass all packets up to the controller with VLAN headers, potentially also LLDP packets, meaning the packet.type field is useless.</div>
<div><br></div><div>What is the best plan of attack for this? I'm not sure of the best style-wise for POX or Python, but I'm thinking either a macro/function that checks if it's VLAN tagged and pulls out the inner type (eth_type) where appropriate, or am I best to use the now-fixed ofp_match at the start of _handle_PacketIn() and use the dl_type from there?</div>
</blockquote></div>
</blockquote></div><br></div></div></div></div></div></div></blockquote></div><br>
</blockquote></div>
</div></div></blockquote></div><br></div></div>
</div></div></blockquote></div><br>
</div></div></blockquote></div><br></div>
</blockquote></div><br></div></div></div></blockquote></body></html>