I’m trying to implement out of band network telemetry using extra UDP packets with small payload. I’m currently trying to achieve this by cloning packets that match my filter in ingress. Then, still in ingress I add a new header to the original packet. This results in deparser emitting 2 packets:
I’m looking to remove
original_payload from packet 2. Is there a simple way to do it? Since I cannot be sure how big the
original_payload will be I wanted to avoid parsing it into a header then setting that header as invalid.
P4 language distinguishes between packet headers that are usually parsed and then can be processed (one can modify existing headers, delete them or add new ones not to mention use their contents in any oprations) and packet payload that is the part of the packet that has not been parsed and cannot be processed using any standard means. This includes the “removal” of the payload.
Having said that, there are a couple of ways to deal with that:
- Since P4 does not specifically dictate what can or cannot be parsed as a header, you can attempt to parse the payload of the packet as a header (or a set of headers). Unfortunately, this is not going to be easy for a variety of reasons:
a. Unless you can determine the length of the payload, it might be very tricky to parse it correctly – any attempt to parse past the end of the packet will result in a parser exception and probably some unparsed garbage (that will remain a payload)
b. Most practical targets do limit the number of bytes one can parse into headers
- Several P4_16 architectures (e.g. TNA or T2NA) provide specialized methods that allow one to truncate either the whole payload or a part of it. Please, refer to the descriptions of those architectures (if that’s what you plan to use).
Hi @JanRepka ,
I think you can always do two things.
- Parse X bytes and just call
payload.setInvalid() at the end. (As you mentioned)
- You can always call
digest and crop Ingress-defined sizes. I mean if you know all the packets follow a similar size then just crop them in that way. Not sure if it works for clones sent to a collector (maybe only ‘batched’ controller messages), b̶u̶t̶ ̶y̶o̶u̶ ̶c̶a̶n̶ ̶t̶r̶y̶ ̶a̶n̶d̶ ̶s̶e̶e̶ (it is not indeed, switch-controller and then controller-collector). Even if the size is different, you might want to define the size via a table, if possible.
If anyone else spots other methods please let us know
* Calling digest causes a message containing the values specified in
* the data parameter to be sent to the control plane software. It is
* similar to sending a clone of the packet to the control plane
* software, except that it can be more efficient because the messages
* are typically smaller than packets, and many such small digest
* messages are typically coalesced together into a larger "batch"
* which the control plane software processes all at once.
* Calling digest is only supported in the ingress control. There is
* no way to undo its effects once it has been called.
extern void digest<T>(in bit<32> receiver, in T data);`
Digest() is a useful mechanism, but based on the stated initial goal (telemetry), it might not be suitable, since it is not a packet interface. It delivers the information to the local driver/control plane, but to deliver it further it will have to be packetized in the software and sent out again anyway.
In addition to that, there might be other “details” there. For example, in case of TNA,
Digest() performs automatic de-duplication of the information, which might or might not be appropriate in the telemetry case. It might also be more restrictive in terms of the amount of data it can carry in the message.
I couldn’t find any way to perform truncating or just not emitting the payload to the cloned packet in TNA. If there is a way that you know. Could you please let me know. My implementation also deals with this difficulty.
If you search this forum for the word “TNA”, this post will pop up first. Please, follow its recommendations.