I want to add a new part (like Ingress match-action or parser) in the V1Model (called X part) and the functionality of this new part is just transferring inputs to outputs. Also, I want to call this new part in p4 code with the input parameter which is input packets and I want to transfer them to the next part in V1Model which. I know this change has a compiler side and an architecture side. Please let me know which changes in compiler and architecture need for this new part. Especially, I want to know how the compiler understands after the parser, whether we have ingress match-action or how the compiler makes the connection between different parts of V1Model.
PS: The reason I want to add the new part to know more about the ability of P4 language and architecture to finally improve them.
Thank you in advance.
I think that it would be helpful if we review basic concepts first.
Let’s start with what P4 architecture actually is and what it is not:
- P4 architecture specifies:
a. A list of P4-programmable blocks that exist in a given processing pipeline
b. The interfaces (intrinsic metadata) between these blocks and the fixed portion of the processing pipeline
c. The set of externs and their interfaces (constructors and methods)
- P4 architecture does not explicitly specify:
a. The set of fixed-function blocks in a given processing pipeline
b. The overall packet flow within the pipeline (which block is executed first, which block is executed second, which metadata is passed where, etc.)
- Things that are listed in (2) are typically documented in the architecture description in plain English (or another natural language) together with the exact semantics of externs, etc.
- Overall, P4 Architectures describe the existing pipelines (and only the things that are needed by the compiler). They do not create or define new pipelines.
a. You can certainly define as many new architectures as you like and it should be possible to implement them in software (it can do anything anyway), but aside from theoretical research they might not be very useful unless they can describe the actual hardware devices that can switch packets a lot faster than the software can. In the latter case, you would, probably, start with the specific HW device you want to describe and not the other way around
Based on this, it is pretty clear that:
- You probably want to create an new architecture (e.g. Mohxen-V1), which is based on V1Model, but is really a different one, since it will have an additional component
- As a result, it is clear that the first step then would be to create a target with that architecture and not to modify the compiler. BMv2 allows you to create a variety of pipelines out of different components, so go to the BMv2 GitHub repository and study how this can be done.
- Based on what I said above, it is that new implementation that you will create (and not the new P4 architecture) that will determine what is passed where, in which order the blocks will be invoked and so on.
- It should also be clear that the picture you drew is extremely simplified and is not quite the right way to understand what architectures really are
Once you do all that you will be ready to do compiler modifications. Again, the best way would be to study the compiler source code and specifically BMv2 backend that supports two different pipelines: simple_switch and PSA.
In fact, I think that a very productive thing to do might be to ask the developers if they need help, since I think that PSA work might not have been 100% completed.
I have not personally done what you are hoping to do, but I can point you at a small part of the BMv2 C++ code that implements the packet processing behavior “before ingress”, “after ingress, before TM”, “after TM, but before egress”, and “after egress”, and if you wanted to add a new P4-programmable control after the end of ingress, it should hopefully be somewhat straightforward by modifying this file. I DO NOT KNOW how straightforward it might be to modify the p4c-bm2-ss back end, though.
This file: behavioral-model/simple_switch.cpp at main · p4lang/behavioral-model · GitHub
See especially the functions in that file named:
Note that the function ingress_thread calls functions to invoke the P4 developer’s parser with this line of code:
ingress_thread also invokes the P4 developer’s ingress control with this line of code:
Also, the compiler was designed carefully so that the front-end does not depend at all on the architecture. The midend and backend can make any assumptions they want, though. That’s why we have many binaries produced by the build system: a different compiler for each target.