How to implement softwared P4 switch in PC or general server to achieve better performance?

I am new to P4 and I want to deploy P4 switches in a virtual environment (among multiple VMS, select the middle VM as the P4 switch) and I would like to ask if there is a better way to do this, for example SONiC has support for P4 (link: SONiC P4 Software Switch · sonic-net/SONiC Wiki · GitHub) However, it is no longer maintained, and I am not sure how to make P4 interact with network ports on bmv2. Can you help me?

Be very grateful


  1. When you deploy a BMV2 switch you can a assigni to it virtual of physical interfaces, as is written here GitHub - p4lang/behavioral-model: The reference P4 software switch you can pass the interfaces via the flag -i 0@<iface0> -i 1@<iface1>
  2. P4 DPDK is under development but definetely provides better persormance respect to bmv2 here the guide made by Andy for deploying it p4-guide/ at master · jafingerhut/p4-guide · GitHub


Thank you for your reply
At present, bmv2 and p4c have been deployed on an industrial PC, but there are some problems when using it as a p4 switch.I refer to the information you provide, as well as a link (Getting Started with P4 - Open Networking Foundation).
I run the following command line:

sudo simple_switch --interface 0@enp2s0 --interface 1@enp4s0 test.bmv2/test.json &
table_add ipv4_match to_port_action => 0
table_add ipv4_match to_port_action => 1

I plan to link two windows hosts through P4siwtch, with the following topology:

windows PC<----wired link----> industrial PC<----wired link---->windows PC enp2s0(P4 Switch)enp4s0___________11.11.1.2

windows PC can’t ping each other successfully,But I capture packet information on industrial PC by wireshark(It shows correct source address).And I followed the links above to complete the whole experiment, which passed correctly…
But two physical hosts cannot communicate. Why is this?
Shouldn’t I bind the physical port directly to the virtual switch side?
The experiment on a physical machine is closer to the real world ,as we intend to simulate the effect of a p4 switch in a data center to assist computing services.but faces some difficulties. :tired_face:

Hi @JYT ,

you should check if the packets reached the bmv2 switches, I truly believe that this not happen. You should implement workaround via a vxlan among physical switch interfaces and virtual interfaces to assign to the bmv2. Because usually the packets are not sent at usespace (where the bmv2 switch runs) so bascally they are not forwarded by the bmv2.

I kind of get it.
Although I used wireshark to try to capture the physical network card, it clearly showed.

the bmv2 should be on a different space from the physical NIC. (The bmv2 in user space cannot connect to the physical NIC in kernel space.)
maybe bind veth and physical port with cmd as follw:

sudo ip link set dev nsp2s0 master veth1

Physical NIC enp2s0 reaches the bmv2 software switch through veth1,Is it right?
I will continue to collect some information and have a try. Thank you very much for your reply.

I have not done it before, but if you run the simple_switch or simple_switch_grpc processes as root, you should be able to specify physical ethernet interface names on the command line, or veth interface names, to bind to numbers that are the numeric ids that the P4 program uses to identify the input port or target output port.

I know for sure you can do this with veth ports, as I do it frequently. Whatever network namespace you run the simple_switch_grpc process in, those interface names must be visible in that network namespace.

Thank you for your reply. I can’t agree with you more.

Like DavideS said,vxlan will help enp2s0 which work in kernelspace connect to bmv2 software switch which work in userspace.
I’m trying,reply latest work later.

Still failed…
Just as a simple report and record, through the following records:
Added a br0 where veth1 and physical NIC enp2s0 are added to br0. Add another br2, connecting veth3 and enp4s0.

# ip link add br0 type bridge
# ip link set veth1 master br0
# ip link set enp2s0 master br0
# br 2 like above.

arp enabled like this:

echo 2>
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.enp2s0.arp_announce = 2

br0/2 forward setting,income from eth1,forward to enp2s0.