Is there a way to compile a program written with p4 into C language?

Hello
First of all, I apologize if my language is not very good.

I want to see if there is a way to compiler a program written in P4 language into c language( Translating P4 to C). And that the compiled program can be run on x86 processors.
The important thing for me is a way to compiler the p4 program in C language.

Thanks for the advice

I am not sure what you are looking for precisely, but the p4c-dpdk back end translate P4 source code into a “spec” file, and then in the open source P4-DPDK back end, it translates that “spec” file into C code that is then compiled and loaded into DPDK. I believe that C code contains some function signatures and uses of library calls that are specific to the DPDK environment.

Similarly there are multiple eBPF back ends for the open source p4c compiler, which produce C code intended to be compiled and loaded into a Linux kernel. The C code thus generated contains some functions signatures, and uses of library calls, that are specific to the eBPF environment.

uBPF back end is similar except it is intended to run the produced C code in a user space process, not in the kernel.

Note: I have not personally used the eBPF or uBPF p4c back ends before, so I do not know first-hand how complete their implementations of the P4 language and/or architecture externs are. I have used the DPDK back end a little bit, and have filed some bugs and enhancement requests for it. It does implement at least a large subset of the language and PSA and PNA architectures today.

1 Like

Thank you Mr @andyfingerhut for your reply

Let me explain my question in more details with an example:
I wrote a simple P4 code to read a switch input packet and change some header parameters of the packet and pass it to the output port.
Because my real switch is not P4 Compatible, I want to convert this P4 program to a C program that run on my x86 machine that controls that incompatible switch.
How do I do this convert from P4 to C?
If you need more explanation, please let me explain

Is your intent to change the behavior of the incompatible switch, so that it behaves like the C program does? Meaning that the switch will process packets like the P4 program specifies?

If so, that is exactly what a “switch [that] is not P4 compatible” cannot do. Unless that switch is able to compile C programs and then start processing packets like that C program specifies, but I am not aware of any such switches. If you are, please let us know which one that is, if you can say.

No, I do not know such a switch
I would like to find a way to compile a program written in p4 to C and run the output without any problems.
I’m sure there is a way to do this, but I don’t know how

There are the ways that I mentioned in my first message above:

(a) use p4c-dpdk, and run the result in the P4-DPDK environment in a user space DPDK process running on a general purpose CPU, e.g. x86_64, amd64, arm64, etc., whatever is supported by DPDK (I do not know the full list, but believe at least those three are supported).

(b) use one of the eBPF or uBPF back end compilers included with p4c and run the result in the Linux kernel (if you use eBPF), or as a user space process (if you use uBPF). Those will execute on a general purpose CPU, as for (a).

“I’m sure there is a way to do this”. To do what? If it is something other than the things I have listed above, then while it is true that perhaps someone could invent a way to do so, then it seems unlikely to me that it has been implemented by anyone yet. Or if they have, let them please announce it.

It was not part of your question, but there is also a published P4 to Rust translator, that can then compile and execute that Rust program on a general purpose CPU. To my knowledge, that is no more likely than translating P4 to a C program to enable running the resulting code on a switch ASIC.

Thank You Mr @andyfingerhut
Rust was interesting, I should spend time and read about it

Regarding the compilation of p4 to c, it is written on github at the address https://github.com/p4lang/p4c/blob/main/backends/ebpf/README.md. To do this, use the following command:
p4c-ebpf PROGRAM.p4 -o out.c
I am doing this on the p4 vm you kindly provided but I am getting an error.

When I run the first program, I encounter this error:

p4@p4:~$ p4c-ubpf basic.p4 -o test.c
basic.p4(46):syntax error, unexpected {, expecting (
control icmp_handler {
^
[–Werror=overlimit] error: 1 errors encountered, aborting compilation

And the second program, which is one of the examples of vm p4, I encounter this error

p4@p4:~/tutorials/exercises/basic$ p4c-ubpf basic.p4 -o test.c
/usr/local/share/p4c/p4include/v1model.p4(760): [–Wwarn=invalid] warning: V1Switch: the main ubpf package should be called ubpf; are you using the wrong architecture?
package V1Switch<H, M>(Parser<H, M> p,
^^^^^^^^
/usr/local/share/p4c/p4include/v1model.p4(760): [–Werror=Target model error] error: Expected toplevel package package V1Switch to have 3 parameters
package V1Switch<H, M>(Parser<H, M> p,
^^^^^^^^

Please advise how and with what order this should be done.

Also, regarding (a) use p4c-dpdk, I don’t understand how it should be done?
I eventually want to run a program compiled in C on x86 processors.

Often different P4 target devices implement different P4 “architectures”.

The architecture implemented by the BMv2 software switch is called v1model, and the P4 program you are trying to compile is written for that architecture, which you can tell because it does #include <v1model.p4> near the beginning.

The architecture implemented by the p4c-ebpf compiler seems to be called something like ebpf_model. If you clone a copy of the repository GitHub - p4lang/p4c: P4_16 reference compiler and look for files with “ebpf” in their file names in the directory p4c/testdata/p4_16_samples, you will find many test programs written to test p4c-ebpf. Many of them have #include <ebpf_model.p4> near the top. The instantiation of main near the end of the file is different than v1model, as you can see in those test programs.

If you read more at the link https://github.com/p4lang/p4c/blob/main/backends/ebpf/README.md that you mentioned, especially the section titled “Supported Capabilities”, you will see that p4c-ebpf only supports P4 programs that calculate a “keep” or “drop” decision for each packet, but do not let you direct the packet to a port, or modify its header fields. Those limitations were what the p4c-ebpf implementer chose to support.

I do not know if there are other P4 back ends for eBPF or uBPF that have a larger set of supported features, as I have not personally used them.

There are public instructions for building the DPDK software switch and using it to compile and run P4 programs written for the PSA and PNA architectures here that you might find useful: https://github.com/jafingerhut/p4-guide/blob/master/ipdk/23.01/README-install-ipdk-networking-container-ubuntu-20.04-and-test.md

Note, the instructions I published for DPDK produce a “spec” file, which is not a C program, as output from p4c-dpdk. The step that is described in those instructions for loading the “spec” file into the DPDK software switch does produce a C source file as an intermediate step, but I do not know if that C program is written anywhere on the file system that you can look at it later. It is compiled and loaded into the DPDK software switch as an intermediate step, though, whether you can see it or not.