added 3 bmv2 examples: copy_to_cpu, meter, TLV_parsing
This commit is contained in:
62
examples/TLV_parsing/README.md
Normal file
62
examples/TLV_parsing/README.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Copy to CPU
|
||||
|
||||
## Description
|
||||
|
||||
This program illustrates how to parse IPv4 options with bmv2. There is a very
|
||||
easy way to parse IPv4 options in P4 using a single variable length
|
||||
field. However, this means that options are not parsed individually, but
|
||||
together, as one block. All the options are parsed to a single field, which is
|
||||
fine for many use cases but can be insufficient in some. In this example, we use
|
||||
TLV parsing to parse all options separately to their own header instance.
|
||||
|
||||
The program is quite straightforward. The following IPv4 options are supported:
|
||||
|
||||
- end of list
|
||||
- no-op
|
||||
- security
|
||||
- timestamp
|
||||
|
||||
There is one important caveat: when compiling the P4 program, a strict ordering
|
||||
of all packet headers has to be known. This is usually done by inspecting the
|
||||
parse graph and running a topological sorting algorithm on it. However this
|
||||
algorithm will not work if there exists loops in the header graph, as is the
|
||||
case with TLV parsing. There is not yet an official way of enforcing your own
|
||||
header ordeing in the P4 program, so we had to bypass this restriction by using
|
||||
a `@pragma`, as you can see in the code:
|
||||
|
||||
@pragma header_ordering ethernet ipv4_base ipv4_option_security ipv4_option_NOP ipv4_option_timestamp ipv4_option_EOL
|
||||
|
||||
This `@pragma` instruction will be interpreted by the P4 -> bmv2 compiler.
|
||||
|
||||
This order is used by the deparser, when sending a packet out of the egress
|
||||
port, which means that the option layout for the outgoing packet may not be the
|
||||
same as for the incoming packet.
|
||||
|
||||
The table `format_options` makes sure that the IPv4 header is formatted
|
||||
correctly in the outgoing packet.
|
||||
|
||||
Note that the P4 program assumes the incoming packet is correctly formatted. We
|
||||
do not perform any sanity checking because *parser execptions* are not yet
|
||||
supported by bmv2.
|
||||
|
||||
So in a nutshell, all this P4 program does is:
|
||||
|
||||
1. parse the IPv4 options for the incoming packet
|
||||
2. re-serialize the packet again, with a potentially different order for options
|
||||
|
||||
### 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).
|
||||
- [send_one.py] (send_one.py): send an IPv4 packet with options
|
||||
|
||||
To run the demo:
|
||||
- start the switch and configure the tables: `sudo ./run_switch.sh`.
|
||||
- run the Python script: `sudo python send_one.py`.
|
||||
|
||||
Then inspect the `pcap` file for port 0 of the switch (`veth0.pcap`) with
|
||||
Wireshark. You will observe that the order of the IPv4 options has changed but
|
||||
that the outgoing packet contains all the options of the incoming packet and is
|
||||
perfectly valid (with a correct checksum).
|
||||
Reference in New Issue
Block a user