<div dir="ltr">Peter, I'm guessing you're using arrays of header instances and "extract(arr[next]);" calls while parsing, so as not to overwrite outer headers when you recurse on inner headers?<div><br></div><div>If so, this approach is a little dangerous in the following sense:</div><div>Let's say I have N-element arrays of ethernet frames, ipv4 headers, TCP headers, and UDP headers.</div><div>This works fine for a packet that's TCP all the way down:</div><div><br></div><div>eth -> ipv4 -> tcp --(recurse)--> eth -> ipv4 -> tcp --(recurse)--> ...</div><div><br></div><div>In each array, data at index N corresponds to that level of encapsulation in the packet.</div><div>But let's say you mix TCP and UDP:</div><div><br></div><div>eth -> ipv4 -> tcp --(recurse)--> eth -> ipv4 -> udp --(recurse)--> ...</div><div><br></div><div>Now, the UDP header at the first layer of encapsulation will be at array index 0, while the other headers at this level of encapsulation will be at index 1. The above packet will be indistinguishable from:</div><div><br></div><div>eth -> ipv4 -> udp --(recurse)--> eth -> ipv4 -> tcp --(recurse)--> ...<br></div><div><br></div><div>Troublesome!!</div><div>Some targets, depending on how they do packet reassembly, may not even be able to compile a parse graph that allows the above.</div><div><br></div><div>If you're not using arrays, I misunderstood your post and you can probably ignore the above :) .</div><div><br></div><div>Regards,</div><div>~Leo</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 24, 2015 at 12:58 PM, Antonin Bas <span dir="ltr"><<a href="mailto:antonin@barefootnetworks.com" target="_blank">antonin@barefootnetworks.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>Hi Peter,<br><br></div>I am sending your email to the whole mailing list, some people may have a better answer than me.<br><br></div>However in this specific case (tunnelling) I don't think you can get away with using the same header and the same parse state. If you look at our switch.p4 example on p4lang/p4factory, you will notice that we sometimes define inner and outer instances for headers (<a href="https://github.com/p4lang/p4factory/blob/master/targets/switch/p4src/includes/parser.p4#L399" target="_blank">https://github.com/p4lang/p4factory/blob/master/targets/switch/p4src/includes/parser.p4#L399</a>). We also use different parse states for inner instances and outer instances. For example we have a parse_ethernet state and a parse_outer_ethernet state.<br></div>We need 2 different header instances because we can have 2 different instances in the incoming packet and in the outgoing packet. We also need 2 different parse states because extracting to a header instance is done in a static fashion.<br><br></div>Thanks for pointing out the p4_expression irregularity. I will try to look into it when I have time.<br><br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 24, 2015 at 12:47 PM, Peter Newman (petenewm) <span dir="ltr"><<a href="mailto:petenewm@cisco.com" target="_blank">petenewm@cisco.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<div style="word-wrap:break-word">
Antonin,
<div><br>
</div>
<div>In a data center switch pretty much everything you can do in the outer packet can also be done in the inner packet. So when I get to the VXLAN header of the outer packet I just go straight back to the beginning and start all over again with parsing the
 inner ethernet packet. One does needs to maintain some state to prevent infinite recursion but that shouldn’t be a problem.</div>
<div><br>
</div>
<div>I’m up to about 1000 lines of P4 already just on the parser. I’d probably have to get someone’s permission to start sharing source. I’ll look into that.</div>
<div><br>
</div>
<div>I wrote some simple tree walking code to print out the type of each object in the expression tree once the front-end had finished. I found ints and strings. Searching for the strings in the p4_header_instance.fields got me what I needed.</div>
<div><br>
</div>
<div>I guess I really need to update my installation. I’m working with the earliest public version. I’ll go find a local git expert — but if it’s working for me why fix it right now...</div>
<div><br>
</div>
<div>Thanks for your help.</div><span><font color="#888888">
<div><br>
</div>
<div>—Peter</div></font></span><div><div class="h5"><div><div>
<div><br>
</div>
<div><br>
</div>
<div><br>
<div>
<div>On Jun 24, 2015, at 12:21 PM, Antonin Bas <<a href="mailto:antonin@barefootnetworks.com" target="_blank">antonin@barefootnetworks.com</a>> wrote:</div>
<br>
<div>
<div dir="ltr">
<div>Hi Peter,<br>
<br>
</div>
Thanks for your email. Please see comments inline:<br>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Tue, Jun 23, 2015 at 11:53 AM, Peter Newman (petenewm)
<span dir="ltr"><<a href="mailto:petenewm@cisco.com" target="_blank">petenewm@cisco.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I am working on a parser in P4. I noticed the following minor issues with the compiler:<br>
<br>
<br>
Compiler crashes if you have a cycle in the parse graph. It enters an infinite recursion at line 448 in p4_tables.py:<br>
<br>
xconds = exclusive_conditions.Solver(hlir)<br>
<br>
You can prevent this behavior if you set the optimize flag to false in the call to build(). I didn’t look at what optimization it is trying to do but it doesn’t seem to affect my parser.<br>
<br>
I did notice the comment a few lines later: "# I am being lazy, and this is all tentative anyway” so I guess this feature is still under active development. It might be better to check for a cycle before executing the optimization.<br>
</blockquote>
<div><br>
</div>
<div>What kind of cycle do you have in your P4 program? This MPLS parser (<a href="https://github.com/p4lang/p4factory/blob/master/targets/switch/p4src/includes/parser.p4#L147" target="_blank">https://github.com/p4lang/p4factory/blob/master/targets/switch/p4src/includes/parser.p4#L147</a>)
 has a cycle (you can extract up to 3 MPLS headers) and is handled correctly by the compiler. More generally, it is okay to have a cycle so long as you are extracting to a tag stack. I can't think of a use case where this would not be the case, which is why
 I would be interested in seeing your P4 program.<br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
The HLIR spec defines a p4_expression to contain references to objects of type: None, int, p4_header_instance or p4_field. The compiler actually gives type str instead of p4_header_instance or p4_field. The string contains the name of the field.<br>
</blockquote>
<div><br>
</div>
<div>At which stage do you observe strings? The resolve_names function (<a href="https://github.com/p4lang/p4-hlir/blob/master/p4_hlir/hlir/p4_expressions.py#L64" target="_blank">https://github.com/p4lang/p4-hlir/blob/master/p4_hlir/hlir/p4_expressions.py#L64</a>) should have
 been called at some point and take care of this.<br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
In a variable length packet header the compiler checks the max_length field but interprets this field as being specified in bits whereas the HLIR spec defines it to be specified in bytes.<br>
</blockquote>
<div><br>
</div>
<div>Wasn't this be fixed by this commit: <a href="https://github.com/p4lang/p4-hlir/commit/72f20169a25619e6cc318254b952886a26e25972" target="_blank">
https://github.com/p4lang/p4-hlir/commit/72f20169a25619e6cc318254b952886a26e25972</a> ?<br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
Just thought I’d document these observations before I forget them.<br>
<br>
—Peter<br>
<br>
<br>
_______________________________________________<br>
P4-dev mailing list<br>
<a href="mailto:P4-dev@p4.org" target="_blank">P4-dev@p4.org</a><br>
Listinfo - <a href="http://mail.p4.org/mailman/listinfo/p4-dev_p4.org" rel="noreferrer" target="_blank">
http://mail.p4.org/mailman/listinfo/p4-dev_p4.org</a><br>
Archives - <a href="http://mail.p4.org/pipermail/p4-dev_p4.org/" rel="noreferrer" target="_blank">
http://mail.p4.org/pipermail/p4-dev_p4.org/</a><br>
</blockquote>
</div>
<br>
<br clear="all">
<br>
-- <br>
<div>
<div dir="ltr">Antonin<br>
</div>
</div>
</div>
</div>
</div>
</div>
<br>
</div>
</div></div></div></div></div><span class="HOEnZb"><font color="#888888">

</font></span></blockquote></div><span class="HOEnZb"><font color="#888888"><br><br clear="all"><br>-- <br><div><div dir="ltr">Antonin<br></div></div>
</font></span></div>
<br>_______________________________________________<br>
P4-dev mailing list<br>
<a href="mailto:P4-dev@p4.org">P4-dev@p4.org</a><br>
Listinfo - <a href="http://mail.p4.org/mailman/listinfo/p4-dev_p4.org" rel="noreferrer" target="_blank">http://mail.p4.org/mailman/listinfo/p4-dev_p4.org</a><br>
Archives - <a href="http://mail.p4.org/pipermail/p4-dev_p4.org/" rel="noreferrer" target="_blank">http://mail.p4.org/pipermail/p4-dev_p4.org/</a><br></blockquote></div><br></div>