How to wait for a period in P4


Recently, I have had some questions about the P4 .
I want to store the packet and wait one second, then forward the packet to a specific port. I find how to store packet data in the register. However, I don’t know how to wait for a period in P4.

Thanks in advance!

Hi and welcome @ckt620and,

I believe this is not a feature present in bmv2 simple switch, if you were asking about bmv2 (might be wrong though). I think I have seen other people requesting this feature or asking questions about it but not sure if anyone did any progress on their own. I also believe that this is quite an expensive feature to implement in P4 hardware switches, so I believe this has little to no sense in terms of the resources needed (in the medium/large scale of random time packet buffering). Of course, if the feature has a strong use case, I guess it could be present at some point in time.

When it comes to bmv2 or software switches, I think this feature is easier to implement and more cost effective. I think you have several options right now, not all focus on what you exactly need but they might work:

  • If you do not want to work a lot developing this feature, you might want to send the packet to the controller. Then keep it some time and send it back. Your precision is little in this case, you will probably never be able to be very precise us/ms if that is your time scale. If you are willing to allow a large error, this is your best bet. When I mean a large error, I mean that if you plan to keep the packet 500 ms, there might be 50 or 100 ms of innacuracy. I am not sure about the actual error offset, but I guess you understand what I mean.

  • Alternatively, you can try to create the “timers” at the control plane and then send a packet to the switch that functions as a trigger. Instead of buffering a packet, you make the control plane become the one that triggers sending the delayed packet. So the packet generated from the control plane will trigger capturing the values you need from the register and then this new packet is built and sent.

  • You can go all the way and develop a new pkt.emit_sleep(header.field, time). I have no idea how to exactly do this but I imagine it will not be an easy task. You have thoguh some nice people that have contributed to a guide a few days ago. Check this thread or PR. I guess this will also require a change into the P4 compiler.

  • You can try to imitate a cloning function like E2I that drops one of the packets and the cloned one sleeps until it is sent to ingress. Then you can try to check if it is cloned and use a particular port. This is not exactly what you asked but it is another possibility. This will require similar changes compared to the previous point.

Hope it helps :slight_smile:

Hi @ederollora ,

Thank you for your response. I try to send the packet to the controller. Then keep it for one second and send it back. It solves my problem, thanks.

But I have another problem. If P4 is multi-threads or supports concurrency? If the ingress can process another packet when I use the cloning function E2E to clone the packet.

Thank you :grinning:


This is from andyfingerhut in this thread:

By default, simple_switch and simple_switch_grpc runs multiple threads. One thread runs ingress for all packets. There are 4 threads numbered 0…3 that run egress code for packets destined to different output ports, where packets destined to output port X run on thread (X % 4). Each of these threads on a Linux system typically runs on a separate CPU core, if your system has enough CPU cores available. See the function start_and_return_ in this file: behavioral-model/simple_switch.cpp at main · p4lang/behavioral-model · GitHub

Multiple threads is similar to running multiple pipelines, in that on a multi-core CPU there are physically separate CPU cores processing packets on different threads.

I guess it is possible that a packet can be processed a packet is being cloned. Not sure though why that would be an issue in your use case. Maybe you can explåin further.


When a P4-programmable device sends a clone to the controller, the P4 device is not blocked waiting for a response from that packet. In general, there might NEVER be a response to such a packet sent to the controller (there are many valid use cases for this, e.g. sending L2 and L3 keepalive packets from the network device to the controller, with no response from the controller back to the network device).

Hi @ederollora @andyfingerhut ,

Thanks for your responses. I previously didn’t make a clear explanation of my question. Following is my original problem. If I use clone to keep creating redundancy packets in the data plane. These redundancy packets don’t send them to the controller. The cloning stop when I receive a new packet. Is the design feasible in a bmv2 simple switch?

Thank you very much!

With bmv2 simple_switch or simple_switch_grpc processes, you can configure a mirror session to send packets to a multicast group. If you have N output ports, you could configure N multicast groups. Support your output ports were numbered 0 to N-1. The first multicast group would replicate the packet to output ports 0 plus the CPU port. The second multicast group would replicate the packet to output ports 1 plus the CPU port. etc. Until the Nth multicast group would replicate the packet to output ports N-1 and the CPU port. Then choose a mirror session id to clone the packet to depending upon which output port you want the packet to go to.