[P4-dev] Encapsulation of variable-length headers

Vladimir Gurevich vladimir.gurevich at barefootnetworks.com
Thu Sep 20 23:17:40 EDT 2018

Hello Cristina,

You can easily add as many headers as you want per action.

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.

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).

Happy hacking,

*Vladimir Gurevich*

*Barefoot Networks*
*Technical Lead, Customer Engineering*
Email: vag at barefootnetworks.com
Phone: (408) 833-4505

On Thu, Sep 20, 2018 at 6:51 PM <cristina.dominicini at aluno.ufes.br> wrote:

> Hi Vladimir
> Thank you very much for the quick answer.
> This was exactly the solution I tried to implement, using a source routing
> header and a header stack:
> ==========
> header srcRoute_t {
>     bit<1>    bos;
>     bit<15>   port;
> }
> header dummySrcRoute_t {
>     bit<1>    bos;
>     bit<15>   port;
> }
> struct headers {
>     ethernet_t              ethernet;
>     dummySrcRoute_t[MAX_HOPS]    dummySrcRoutes;
>     srcRoute_t[MAX_HOPS]    srcRoutes;
>     ipv4_t                  ipv4;
> }
> ==========
> But the source routing protocol is transparent to hosts. So, I need to
> build the complete stack in the first switch (edge ingress switch).
> 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.
> Is there a better way to add these headers if the stack has variable size
> (as in the example)?
> Thank you for the confirmation that P4 16 language does note support
> encapsulation of variable-length headers.
> Best Regards,
> Cristina
> Em 20.09.2018 22:22, Vladimir Gurevich escreveu:
> Hello Cristina,
> 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.
> In other words, your examples should look like this:
>    - "switch 1 output port is 3, and switch 2 output port is 1" will be
>    {1} {3}
>    - "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}
> 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.
> 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.
> So, my hope is that you will be able to solve the problem without using
> variable-length headers to begin with.
> 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"
> Happy hacking,
> Vladimir
> *Vladimir Gurevich*
> *Barefoot Networks*
> *Director, Customer Training and Education*
> Email: vag at barefootnetworks.com
> Phone: (408) 833-4505
> On Thu, Sep 20, 2018 at 5:48 PM <cristina.dominicini at aluno.ufes.br> wrote:
>> Hi all,
>> The parsing of variable-length headers is well documented in P4 language.
>> There are examples as the source routing tutorial (
>> https://github.com/p4lang/tutorials/tree/master/exercises/source_routing)
>> and the implementation of TCP options in the P4 16 manual.
>> On the other hand, I could not find a way to add a variable-length header
>> to a packet using P4 16 and v1model.
>> 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?"
>> 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.
>> Imagine two examples of output port list for source routing:
>> {3 1} - which means switch 1 output port is 3, and switch 2 output port
>> is 1
>> {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
>> So, depending on the path length, the size of the source routing list
>> changes, and, consequently, the total header length changes.
>> My start point was this very good documentation from Andy Fingerhut:
>> https://github.com/jafingerhut/p4-guide/tree/master/rewrite-examples
>> 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.
>> 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.
>> 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?
>> Thank you,
>> Cristina
>> _______________________________________________
>> P4-dev mailing list
>> P4-dev at lists.p4.org
>> http://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20180920/d9ae4bea/attachment.html>

More information about the P4-dev mailing list