I have a question about the way in which a P4 binary is loaded onto a switch. Say I have written a program that I want to place on a specific P4 switch, I assume I compile the P4 program on my local machine to create the target specific configuration binary. However, once the compilation is complete, what method or methods are used to put the binary onto the target switch? Is it simply sent to the switch through the network or do I need physical access to the switch? If it does go through the network, how does the switch know that it has received a new configuration and not a typical packet?
Thank you for your help.
One way that some switches support loading a new P4 program binary is by connecting to them via a TCP connection on a special control TCP port (by default port number 9559), and sending a P4Runtime API message called
SetForwardingPipelineConfig, where a field of that message is the compiled P4 program binary.
In many cases, this TCP connection is made to a special management port on a physical switch, which is physically distinct and separate from the other “front panel ports” of the switch.
In some cases, a switch might also be configured to receive such TCP connection packets on a front panel port, but then it would need some kind of behavior loaded into the switch to send these received packets to a local control CPU, often on the same board as the switch ASIC.
An example of doing this using the BMv2 software switch (not a real physical switch, but a software switch running as a user space process on a Linux system), and using a Python program to make the P4Runtime API TCP connection and sending the
SetForwardingPipelineConfig message, can be found here: p4-guide/README-p4runtime.md at master · jafingerhut/p4-guide · GitHub
There are also network devices that have other techniques for loading P4 binaries into them, for which you would need to consult the documentation of the particular P4-programmable device from the vendor.
Ok great! Thank you for your response.
I have a follow up question. Suppose I am a user with a host on a network of P4 switches configured as you have described: where loading is done with the P4Runtime API over a TCP connection. As long as I’m on the network, can I make the API call or are there more requirements that I as a host on the P4 network would have to meet in order to make the API call to load a P4 binary?
Thanks for your feedback,
Well, the P4Runtime API connection can be configured on the server/network-device side to require cryptographic authentication, so the host from which you wish to make such a connection would need the proper crypto keys in order to successfully make such a connection.
You would obviously need the basic network connectivity required in order to make a TCP connection from that host to the network device(s) of interest.
Your question is fairly open-ended. You need to turn on all of the relavant devices and supply them sufficient electrical power That is just a joke. If you have any more specific questions about the requirements you are looking for, please ask.
In general, though, you should read the following sentence as if I wrote it in ALL CAPS:
You need to learn about the particular devices you are deploying in your network, and become familiar with the documentation from the device’s vendor, about any special requirements they might have. This trumps any and all other advice I can give you. If your vendor made special requirements, then only the vendor can tell you what they are.
Ok thank you.
I apologize for the ambiguity of the question, I’m pretty new to P4 and am probably not wording my questions very clearly. I think the authentication you mention at the beginning is what I’m interested in. When you say the “API connection can be configured on the server/network-device side to require cryptographic authentication” can this configuration be accomplished through a P4 program or would the architecture of the switch need to be changed? (For example if I wanted to add authentication to a network of BMv2 switches would I need to change the BMv2 source code rather than just reconfigure it with P4) Are there any good resources you can point me to that discuss authenticating the API connection?
A P4Runtime API connection uses gRPC (https://grpc.io), which has built into that library’s implementation the (optional) authentication mechanisms required. The open source simple_switch_grpc process built from the code in the behavioral-model repo already provides this, perhaps from code linked in from another repo such as GitHub - p4lang/PI: An implementation framework for a P4Runtime server (my apologies, I do not know exactly which repo that authentication code is enabled within).
I have copied and pasted below a part of the output from running this command:
--grpc-server-addr arg Bind gRPC server to given address [default is 0.0.0.0:9559] --grpc-server-ssl Enable SSL/TLS for gRPC server --grpc-server-cacert arg Path to pem file holding CA certificate to verify peer against --grpc-server-cert arg Path to pem file holding server certificate --grpc-server-key arg Path to pem file holding server key --grpc-server-with-client-auth Require client to have a valid certificate for mutual authentication
Thank you, I understand the loading process much better now. I have been experimenting with doing this process somewhat manually. Specifically I am interested if it is possible for one of the hosts in the network from the “basic” tutorial
to load a p4 binary onto one of the switches. (This would be while the solution p4 program is implemented on the network meaning that all hosts are able to communicate with each other). Say that I want to load a newly compiled p4 program onto s1 from h1. An issue that I am running into is that I am unsure what address and port number to use in the runtime shell to connect to s1. Based on the printed data from “make run” when building the network initially, I know that the address and port it uses to configure s1 is localhost:50051; however this is the localhost of the virtual machine and not of h1, meaning that h1 isn’t able to use that address and port to configure s1. How can I figure out what address and port h1 could use to reconfigure s1? Is it even possible for h1 to do this in the basic network of the exercise? If not, is this because of the p4 configurations limiting how h1 can communicate or is it because the switch, s1, needs to be configured, outside of the p4 configuration, to accept a connection for a p4 runtime shell?
The way BMv2 works, either:
(1) a process running in the same Linux network namespace as the BMv2
simple_switch_grpc process is running, needs to make a TCP connection on the appropriate TCP port that
simple_switch_grpc is listening on for P4Runtime API connections.
(2) you need to configure things so that a process running on another machine, or on the same machine but running in a different Linux network namespace, has its TCP packets forwarded appropriate so that they eventually reach the Linux network namespace where the
simple_switch_grpc process is running.
There is pretty much an unlimited variety of configurations that can accomplish (2). I have not tried to find one, though, so probably will not personally be much help to you in answering that. The tutorials exercises use Mininet, I believe with separate Linux network namespaces created for each simulated host, and perhaps also for each simulated switch as well, but I’m not certain of that last part. Mininet is used in such a way that it creates veth interface pairs with one endpoint in one namespace, and the other endpoint in a different namespace, to connect simulated hosts to switches, and perhaps also for connecting multiple switches to each other.
You could probably create additional veth pairs between simulated hosts and the Linux network namespace where
simple_switch_grpc processes are running, and cause an application running on a simulated host to use that other veth interface instead of the one connected to a switch. It all sounds do-able, but I don’t have the steps for you to read and follow.