<div dir="ltr">Hi Satyam,<div>It's a design decision you have to make given your program's architecture - I could see arguments either way. Parsing both layers of headers at once allows you to reason about both of them at the same time in one match+action pipeline. Recirculation makes the match+action pipeline and parser cleaner at the expense of decreasing your switch's throughput. Though these things aside, I suspect different targets will work better with different approaches.</div><div><br></div><div>> <span style="font-size:12.8000001907349px">Also, I’d suggest that the language should be elegant, its the compiler’s job to do the right thing on high performance targets.</span></div><div class="" style="font-size:12.8000001907349px"></div><div class="" style="font-size:12.8000001907349px"><br></div><div class="" style="font-size:12.8000001907349px">I think everybody would agree with this sentiment. Reality will dictate what compilers are and aren't able to accomodate for a given target.</div><div class="" style="font-size:12.8000001907349px"><br></div><div class="" style="font-size:12.8000001907349px">~Leo</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 24, 2015 at 8:50 PM, Satyam Sinha <span dir="ltr"><<a href="mailto:satyam@gmail.com" target="_blank">satyam@gmail.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">Hi Folks,<div><br></div><div>As a general philosophy - when do we do stack of headers versus recirc (i2i, e2i) ? Recirc makes it very elegant (no arrays) at the cost of loopback bandwidth. I think stacking headers makes it complex code. </div><div><br></div><div>Also, I’d suggest that the language should be elegant, its the compiler’s job to do the right thing on high performance targets.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Satyam</div></font></span><div><div class="h5"><div><br><div><div>On Jun 24, 2015, at 3:01 PM, Leo Alterman <<a href="mailto:leo@barefootnetworks.com" target="_blank">leo@barefootnetworks.com</a>> wrote:</div><br><blockquote type="cite"><div dir="ltr">I see. In that case, this is an elegant solution!<div><br></div><div>One thing to keep in mind: very high performance P4 targets might be quite limited in the amount of state that can be kept in the parser and how that state can be used. In practice, for instance, you might find it's not possible to index into header arrays with a piece of metadata you control yourself through calls to set_metadata(). Understandably, without such a target it's not clear what these constraints will be.</div><div><br></div><div>I think the take-home message is that elegant solutions in P4 may not actually compile on high performance targets (in the same sense that you're not going to be running Python on an extremely resource-constrained embedded processor), so keep this thought somewhere in the back of your mind and have your elegance hatchet at the ready.</div><div><br></div><div><div style="font-size:12.8000001907349px">> I really, really want to avoid doubling the size of my tcam in all of the pipeline stages of the parser which is what I assume will happen if I follow the <a href="http://p4.org/" target="_blank">p4.org</a> data-center example and define both inner and outer versions for every parse state.</div></div><div style="font-size:12.8000001907349px"><br></div><div style="font-size:12.8000001907349px">This is a very valid concern, but depending on the target you may not have a choice. For the time being I'd probably stick with the most clean solution and be ready to adapt to more constrained platforms as necessary.</div><div><br></div><div>~Leo</div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 24, 2015 at 2:44 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">
Leo,
<div><br>
</div>
<div>Thanks.</div>
<div><br>
</div>
<div>I was thinking of something like this. However, the array is only two deep — inner and outer — and I only change the index when I hit a tunneling header, VXLAN for example. That should avoid the problem you describe.</div>
<div><br>
</div>
<div>I really, really want to avoid doubling the size of my tcam in all of the pipeline stages of the parser which is what I assume will happen if I follow the
<a href="http://p4.org/" target="_blank">p4.org</a> data-center example and define both inner and outer versions for every parse state.</div>
<div><br>
</div>
<div>Given I don’t have a real target to work with I admit that some of the implications have undoubtedly escaped me.</div>
<div><br>
</div>
<div>Regards</div><span><font color="#888888">
<div><br>
</div>
<div>—Peter</div></font></span><div>
<div><br>
</div>
<div><br>
<div>
<div>On Jun 24, 2015, at 2:25 PM, Leo Alterman <<a href="mailto:leo@barefootnetworks.com" target="_blank">leo@barefootnetworks.com</a>> wrote:</div>
<br>
<div>
<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>
<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>
<span><font color="#888888"></font></span></blockquote>
</div>
<span><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" 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>
</div>
</div>
</div>
<br>
</div>
</div></div>

</blockquote></div><br></div></div>
_______________________________________________<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" 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/" target="_blank">http://mail.p4.org/pipermail/p4-dev_p4.org/</a></blockquote></div><br></div></div></div></div></blockquote></div><br></div>