<div dir="ltr">Hello Cristina,<div><br></div><div>You can easily add as many headers as you want per action. </div><div><br></div><div>Therefore, even though it might look a little ugly, one of the solutions would be to create N actions, where the first action will add one header, the second will add two headers, the third will add three headers, etc. and then create a table that will choose one of such actions, depending on the destination IP address or whatever.  </div><div><br></div><div>Another option might be to create another set of N actions, such that the first will add srcRoutes[0], the second will add srcRoute[1], etc. and then have N tables, each of them adding (or not adding) a corresponding header, again, depending on the IP address, nexthopID or whatever. The advantage of that scheme is that the tables can still execute in parallel, while the size of the action data will be kept in check, adding in the real-life table placement (if you ever get to work with a real device). </div><div><br></div><div>Happy hacking,</div><div>Vladimir</div><div><br></div><div><br></div><div><div><div dir="ltr" class="m_-8566283362162191003gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><font size="4"><b>Vladimir Gurevich</b></font></div><div><font size="4"><b><br></b></font></div><div><font size="4"><b>Barefoot Networks</b></font></div><div><b><font size="2">Technical Lead, Customer Engineering</font></b></div><div><font size="2">Email: <a href="mailto:vag@barefootnetworks.com" target="_blank">vag@barefootnetworks.com</a></font></div><div><font size="2">Phone: (408) 833-4505</font></div><div><br></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Sep 20, 2018 at 6:51 PM <<a href="mailto:cristina.dominicini@aluno.ufes.br" target="_blank">cristina.dominicini@aluno.ufes.br</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="font-size:10pt;font-family:Verdana,Geneva,sans-serif">
<p>Hi Vladimir</p>
<p><br></p>
<p>Thank you very much for the quick answer.</p>
<p>This was exactly the solution I tried to implement, using a source routing header and a header stack:</p>
<p>==========</p>
<p>header srcRoute_t {<br>    bit<1>    bos;<br>    bit<15>   port;<br>}<br><br>header dummySrcRoute_t {<br>    bit<1>    bos;<br>    bit<15>   port;<br>}<br><br>struct headers {<br>    ethernet_t              ethernet;<br>    dummySrcRoute_t[MAX_HOPS]    dummySrcRoutes;<br>    srcRoute_t[MAX_HOPS]    srcRoutes;<br>    ipv4_t                  ipv4;<br>}</p>
<p>==========</p>
<div> </div>
<p>But the source routing protocol is transparent to hosts. So, I need to build the complete stack in the first switch (edge ingress switch). </p>
<p>I understood that the way to add a header in P4 is by using a match-action table in the ingress block, as I described in my last e-mail. However, depending on the destination, I may have to add one, two or ten of these srcRoute_t headers. So, how to build this table to cope with this condition? The only solution that worked for me was to consider a fix number of hops, and, then parse only the useful ones using this dummy header to parse the ones I don't need, until I get to the beginning of the IP header.</p>
<p>Is there a better way to add these headers if the stack has variable size (as in the example)?</p>
<p>Thank you for the confirmation that P4 16 language does note support encapsulation of variable-length headers.</p>
<p><br></p>
<p>Best Regards,</p>
<p>Cristina</p>
<p><br></p>
<p>Em 20.09.2018 22:22, Vladimir Gurevich escreveu:</p>
<blockquote type="cite" style="padding:0 0.4em;border-left:#1010ff 2px solid;margin:0">
<div dir="ltr">Hello Cristina,
<div> </div>
<div>First of all, I do not think that your specific use case requires variable length headers. The standard practice is to use a stack of fixed-length headers, each representing the information from one node. Also, unless you really need to look up past those headers, the traditional way of passing this information is by *prepending" the new info in front of the existing stack. </div>
<div> </div>
<div>In other words, your examples should look like this:<br>
<ul>
<li>"switch 1 output port is 3, and switch 2 output port is 1" will be {1} {3}</li>
<li>"switch 1 output port is 3, switch 2 output port is 3, switch 3 output port is 3, and switch 4 output port is 1" will be {1} {3} {3} {3}</li>
</ul>
<div>This allows each node to not even parse the stack of headers created by the previous nodes. All you need to do is to add one header with your info just after the header that precedes the stack. </div>
<div> </div>
<div>If you want a harder solution, you can parse the whole stack, but then you will either have to have "end of stack" indicator (similar to BOS bit in MPLS), or use a counter or do something else. The only advantage is that this would allow you to parse the headers that follow this info, while there will be several serious disadvantages: you will be limited to the maximum number of headers defined at compile time and parsing will take longer.</div>
<div> </div>
<div>So, my hope is that you will be able to solve the problem without using variable-length headers to begin with.</div>
<div> </div>
<div>As for the original question, standard P4_16 (without any vendor-specific externs) only allows one to extract, copy (assign) and deparse variable-length headers. You can't create one "on the fly"</div>
<div> </div>
<div>Happy hacking,</div>
<div>Vladimir </div>
<div> </div>
<div>
<div class="m_-8566283362162191003m_2873213324106198389gmail_signature" dir="ltr">
<div dir="ltr">
<div>
<div dir="ltr">
<div><span style="font-size:large"><strong>Vladimir Gurevich</strong></span></div>
<div><span style="font-size:large"><strong> </strong></span></div>
<div><span style="font-size:large"><strong>Barefoot Networks</strong></span></div>
<div><strong><span style="font-size:small">Director, Customer Training and Education</span></strong></div>
<div><span style="font-size:small">Email: <a href="mailto:vag@barefootnetworks.com" target="_blank">vag@barefootnetworks.com</a></span></div>
<div><span style="font-size:small">Phone: (408) 833-4505</span></div>
<div> </div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr">On Thu, Sep 20, 2018 at 5:48 PM <<a href="mailto:cristina.dominicini@aluno.ufes.br" target="_blank">cristina.dominicini@aluno.ufes.br</a>> wrote:</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="font-size:10pt;font-family:Verdana,Geneva,sans-serif">
<p>Hi all,<br><br>The parsing of variable-length headers is well documented in P4 language. There are examples as the source routing tutorial (<a href="https://github.com/p4lang/tutorials/tree/master/exercises/source_routing" target="_blank">https://github.com/p4lang/tutorials/tree/master/exercises/source_routing</a>) and the implementation of TCP options in the P4 16 manual.<br><br>On the other hand, I could not find a way to add a variable-length header to a packet using P4 16 and v1model. <br><br>My goal was to extend the source routing tutorial in order to answer a question of the "Food for thought" section: "How would you enhance your program to let the first switch add the path, so that source routing would be transparent to end-hosts?" <br><br>Originally, this tutorial depends on a python script to generate the source routing headers, and the p4 program deals only with the source routing operation on headers that were already created by the hosts.<br><br>Imagine two examples of output port list for source routing:<br>{3 1} - which means switch 1 output port is 3, and switch 2 output port is 1<br>{3 3 3 1} - which means switch 1 output port is 3, switch 2 output port is 3, switch 3 output port is 3, and switch 4 output port is 1<br><br>So, depending on the path length, the size of the source routing list changes, and, consequently, the total header length changes.<br><br>My start point was this very good documentation from Andy Fingerhut: <a href="https://github.com/jafingerhut/p4-guide/tree/master/rewrite-examples" target="_blank">https://github.com/jafingerhut/p4-guide/tree/master/rewrite-examples</a><br><br>So, if no source routing header was found in the parsing stage, I can add it in the ingress block by consulting a table, where the match condition is the IP destination address, and the action is the content of my source routing header for reaching that destination. However, to do this I need to store the contents from the table in fixed size variables.<br><br>I was only able to solve this problem if I consider a fixed-length source routing header when reading the action column from the table. Then, in the parsing stage, besides the useful source routing content, I also parse a dummy source routing content for the remaining bits in the header. In addition, I have to keep this dummy header during the routing process. The routing works, but clearly it is not an optimal implementation, since I have a header overhead that was not happening when the headers were created by the python script in the hosts.<br><br>Does someone have a better idea on how to solve this type of problem (encapsulation of variable-length headers)? Does the P4 16 language support encapsulation of variable-length headers? Does the PSA architecture (instead of v1model) offer more flexibility to solve this type of problem? <br><br>Thank you,<br>Cristina</p>
<p><br></p>
</div>
_______________________________________________<br> P4-dev mailing list<br><a href="mailto:P4-dev@lists.p4.org" target="_blank">P4-dev@lists.p4.org</a><br><a href="http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org" target="_blank">http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org</a></blockquote>
</div>
</blockquote>
</div>
</blockquote></div>