Per-flow statistics

Hello,

I am trying to perform some operations on the fist few packets of each flow. So, I need to maintain per-flow recors in the switch. Is there any sample code as a starting point that can help me to continue my work?

BR,
MS

Hello Saqib,

In P4 only 3 kinds of objects can keep their state between packets:

  • Tables
  • Value_sets
  • Externs

Given that you will need to modify the state as well, externs is what you will be using.

Now, the important thing is that the language does not define any specific externs or their functionality – this job is to left to entities, called “architectures”. Do not be surprised, the same thing happens in other languages as well: for example C does not have any built-in facilities to print characters, and this functionality is relegated to printf() and similar functions that are part of various libraries.

The reason I am saying this is that you should probably specify which architecture you plan to write for first, otherwise your question sounds like “How would I write X using Latin alphabet?” (without specifying the actual language)

Many popular architectures do have an extern, called register, which can store arbitrary information between the packets. The actual name of the extern might slightly differ between architectures (e.g. it might be register() or Register()), and the specific capabilities might differ a lot, but, again, many would allow you to increment the value stored in the register by some number (for example) and read it, so that it can be later used in an if()statement to make a decision.

So, on the surface it is pretty easy to do what you want.

The devil is in the details that you did not specify. For example, how do you plan to identify the flows, do you need to automatically learn new flows or they will be explicitly provisioned by the control plane, how do you plan to reset the values, etc, etc. – all these might lead to very different solutions. Not only that, but the more elaborate the requirements are, the more you will see the solutions diverge based on the capabilities of specific architectures (and the underlying targets).

Happy hacking,
Vladimir

Dear Vladimir,

Thank you for the detailed response.

My targeted architecture is v1model. Yes, I am trying to use registers. I am planning to:

  • Automatically identify the flow for each packet, count the number of packet and packet size for each flow
  • Check the incoming packet against already stored flow_id
  • If the flow_id already exist then count the packets and store the new packet size
  • Else create a new flow id and store the packet count and packet size
  • If the count reaches to 5 then create a vector of packet size along with the flow_id

Looking forward for your kind support.

BR,
Saqib

It is far from straightforward guarantee generating a unique flow id for every 5-tuple (i.e. IP source & dest address, protocol, L4 source & dest port), using the capabilities provided by the v1model architecture (possible, but very tricky, and I only know of one way whose details are not public).

It is straightforward to hash some packet header fields to a flow_id value, one that is NOT guaranteed to be unique. This is acceptable, if you are willing to sometimes have multiple flows collide to the same hash value and “share” a packet/byte counter between them.

The PNA architecture is introducing a new ‘add_on_miss’ table property that would make this more straightforward, but this is still new enough that there is not yet an open source implementation of it to try out. I suspect it will be available for the DPDK back end of the p4c compiler some time in 2022, not sure which month. There are some NICs and some switch ASICs that can implement that, or something like it, because they have the necessary hardware support to do so.