[P4-dev] storing metadata while parsing header stacks

Salvatore Signorello salvatore.signorello at uni.lu
Mon Jul 20 05:42:41 EDT 2015


Hi Antoine,

first, cents are more than welcome, then more in-line.

Best,
Salvatore
On Mon, 2015-07-20 at 00:58 -0700, Antoine Kaufmann wrote:

> I spent a while thinking about similar tricks to play in P4, so let me
> add my 2 cents. Feel free to tear those apart if I overlooked something.
> 
> On Mon, Jul 20 09:11, Salvatore Signorello wrote:
> > Caveat: I think that we cannot use ternary matches on a single table,
> > because the mask we need is defined at run-time by the number of xyz
> > headers parsed. Please point me wrong, if I'm mistaken.
> 
> I think you can use ternary matches if you also match on the valid bits
> of the headers. So if you match on the second header, your matching key
> would also set the correspondign valid bit in the matching key for the
> entry to one (and the later valid bits can be "don't care". If you had a
> large maximal depth it might make sense to create multiple ternary match
> tables (at least 0, at least 32, ...) to reduce the entry size at the
> cost of using multiple stages.

I don't know If I've got it well, so let me write it out the dumb
solution I have in mind, so that I can ask you to further elaborate on
top of that one.
Suppose that the worst case is a chain of three xyz headers and we match
on the xyz.fieldA. So we want to perform an exact match to:
- xyz[0].fieldA, xyz[1].fieldA, xyz[2].fieldA, if there are three
headers
- xyz[0].fieldA , xyz[1].fieldA, if there are two headers (this could be
seen as ternary match to xyz[2].fieldA and exact match to the others)
- xyz[0].fieldA, if there is just one header(this could be seen as
ternary matches to xyz[1].fieldA, xyz[2].fieldA and exact to the first)

I think of counting the number of headers through the trick Mihai
initially suggested, so I have that number stored into a metadata field
"flow_metadata.xyz". Then I have defined the following tables:

table singleFilter{ reads{ xyz[0].fieldA :
exact;}actions{doSomethingA;}}
table doubleFilter{ reads{ xyz[0].fieldA : exact;xyz[1].fieldA :
exact;}actions{doSomethingB;}}
table tripleFilter{ reads{ xyz[0].fieldA : exact; xyz[1].fieldA : exact;
xyz[2].fieldA : exact;}actions{doSomethingC;}}

and my workflow would look like the following:

if ( flow_metadata.xyz == 1 ) apply(singleFilter); else if
( flow_metadata.xyz == 2 ) apply(doubleFilter); else if
( flow_metadata.xyz == 3 ) apply(doubleFilter);

What would you suggest instead? Please keep in mind that
"flow_metadata.xyz" is computed at run-time for each packet. This
metadata contains the value you would need as mask to perform the match
against a table defined like this:

table ternaryFilter{ reads{ xyz[0].fieldA : ternary; xyz[1].fieldA :
ternary; xyz[2].fieldA : ternary;}actions{doSomethingA; doSomethingB;
doSomethingC; doNothing;}}



> 
> Hope this helps!
> 
> > 
> > Thank you in advance,
> > best,
> > Salvatore
> > 
> > 
> > On Fri, 2015-07-17 at 18:16 +0200, Salvatore Signorello wrote:
> > 
> > > Thank you a lot, Mihai,
> > > 
> > > This trick works smoothly for the simple MPLS example I've used to
> > > illustrate the issue. I hope I can exploit such workaround into a
> > > different workflow I'm working on too.
> > > 
> > > Best,
> > > Salvatore
> > > On Fri, 2015-07-17 at 08:24 -0700, Mihai Budiu wrote: 
> > > 
> > > > The valid bits of the header stack can be interpreted as a base 1
> > > > encoding of the number you are looking for. If you want it in base 2
> > > > you can use a table for converting it.
> > > > 
> > > > Mihai
> > > > 
> > > > ____________________________________________________________________
> > > > 
> > > > From: Salvatore Signorello
> > > > Sent: ‎7/‎17/‎2015 0:56
> > > > To: p4-dev at p4.org
> > > > Subject: [P4-dev] storing metadata while parsing header stacks
> > > > 
> > > > 
> > > > Hi all,
> > > > any advice for the following:
> > > > 
> > > > Suppose to have an MPLS stack parsed as follows:
> > > > 
> > > > #define MPLS_DEPTH 5
> > > > header mpls_t mpls[MPLS_DEPTH];
> > > > 
> > > > parser parse_mpls{
> > > >     extract(mpls[next]){
> > > >         return select(latest.bos){
> > > >             0 : parse_mpls;
> > > >             1 : parse_mpls_bos;
> > > >         }
> > > >     }
> > > > }
> > > > 
> > > > and that you would like to know (and to store somewhere, like into a
> > > > metadata block) how many MPLS headers (a number that is likely lower
> > > > than MPLS_DEPTH) have been parsed at the end of the parsing process.
> > > > What to do?
> > > > Could metadata be used like a kind of counter?
> > > > Could register be indexed somehow during the parsing and set through
> > > > the set_metadata?
> > > > 
> > > > Thank you in advance,
> > > > best,
> > > > Salvatore Signorello
> 


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.p4.org/pipermail/p4-dev_lists.p4.org/attachments/20150720/d0db1252/attachment-0001.html>


More information about the P4-dev mailing list