Copy to CPU
Description
This program illustrates as simply as possible how to send packets to CPU (e.g. to a controller).
The P4 program does the following:
- incoming packets are mirrored to the CPU port using the
clone_ingress_pkt_to_egress
action primitive - packets mirrored to CPU are encapsulated with a custom
cpu_header
which includes 2 fields:device
(1 byte, set to0
) andreason
(one byte, set to0xab
) - the original packet is dropped in the egress pipeline
Take a look at the [P4 code] (p4src/copy_to_cpu.p4). The program is very short
and should be easy to understand. You will notice that we use a mirror session
id of 250
in the program. This number is not relevant in itself, but needs to
be consistent between the P4 program and the runtime application.
Running the demo
We provide a small demo to let you test the program. It consists of the following scripts:
- [run_switch.sh] (run_switch.sh): compile the P4 program and starts the switch, also configures the data plane by running the CLI [commands] (commands.txt)
- [receive.py] (receive.py): sniff packets on port 3 (veth7) and print a hexdump of them
- [send_one.py] (send_one.py): send one simple IPv4 packet on port 0 (veth1)
If you take a look at [commands.txt] (commands.txt), you'll notice the following
command: mirroring_add 250 3
. This means that all the cloned packets with
mirror id 250
will be sent to port 3
, which is our de facto CPU port. This
is the reason why [receive.py] (receive.py) listens for incoming packets on port
3
.
To run the demo:
- start the switch and configure the tables and the mirroring session:
sudo ./run_switch.sh
- start the CPU port listener:
sudo python receive.py
- send packets with
sudo python send_one.py
. Every time you send one packet, it should be displayed by the listener, encapsulated with our CPU header.
This is a very simple example obviously. Feel free to build upon it. For example, instead of dropping the original packet, you could try to broadcast it out of every non-ingress port to have a working L2 switch. You could also build a L2 controller which receives CPU packets and modifies tables appropriately.