2017-06-01 11:30:40 -07:00

4.1 KiB

Implementing ECMP on top of simple_router.p4

Introduction

simple_router.p4 is a very simple P4 program which does L3 routing. All the P4 code can be found in the p4src/simple_router.p4 file. In this exercise we will try to build ECMP on top of the starter code. We will be assuming the following network topology:

             --------------------------------- nhop-0 10.0.1.1
             |                                        00:04:00:00:00:00
          1 - 00:aa:bb:00:00:00
             |
-------- 3--sw
             |
          2 - 00:aa:bb:00:00:01
             |
             --------------------------------- nhop-1 10.0.2.1
                                                      00:04:00:00:00:01

Note that we do not assign IPv4 addresses to the 3 switch interfaces, we do not need to for this exercise. We will be sending test packets on interface 3 of the switch. These packets will have destination IP 10.0.0.1. We will assume that both nhop-0 and nhop-1 have a path to 10.0.0.1, which is the final destination of our test packets.

Running the starter code

Before starting make sure that you run sudo ./veth_setup.sh to create the veth pairs required for the demo.

To compile and run the starter code, simply use ./run_demo.sh. The run_demo.sh script will run the P4 compiler (for bmv2), start the switch and populate the tables using the CLI commands from commands.txt.

When the switch is running, you can send test packets with sudo ./run_test.py. Note that this script will take a few seconds to complete. The test sends a few hundred identical TCP packets through the switch, in bursts, on port 3. If you take a look at the P4 code and at commands.txt, you will see that each TCP packet is forwarded out of port 1; since we do not have ECMP working yet.

What you need to do

  1. In this exercise, you need to update the provided P4 program to perform ECMP. When you are done, each incoming TCP test packet should be forwarded to either port 1 or port 2, based on the result of a crc16 hash computation performed on the TCP 5-tuple (ipv4.srcAddr, ipv4.dstAddr, ipv4.protocol, tcp.srcPort, tcp.dstPort). You will need to refer to the P4 spec to familiarize yourself with the P4 constructs you will need.

  2. Once you are done with the P4 code, you will need to update commands.txt to configure your new tables.

  3. After that you can run the above test again. Once again, you will observe that all packets go to the same egress port. Don't panic :)! This is because all packets are identical and therefore are forwarded in the same way, If you add --random-dport when running sudo ./run_test.py, you should observe an even distribution for the ports. This option assigns a random destination port to each test TCP packet (the 5-tuple is different, so the hash is likely to be different).

Hints and directions

  1. You can easily check the syntax of your P4 program with p4-validate <path to simple_router.p4>.

  2. There are 2 major ways of implementing ECMP on top of simple_router.p4. The first one requires 2 tables and the use of the modify_field_with_hash_based_offset primitive. The second one uses a single table with an action profile. You can read about modify_field_with_hash_based_offset and action profiles in the P4 spec.

  3. If you choose to use the first way (with 2 tables), your first table will match on the destination IP address and be in charge of computing an index (using modify_field_with_hash_based_offset), while the second table will match on this computed index to obtain the outgoing interface. This is a high level view of what needs to be implemented in P4.

T1
IP_prefix_1 ---> "random" index in [0, 1] using modify_field_with_hash_based_offset
IP_prefix_2 ---> "random" index in [2, 4] ...
...

T2
index(0)    ---> nhop A
index(1)    ---> nhop B
index(2)    ---> nhop C
index(3)    ---> nhop D
index(4)    ---> nhop E

Remember that T1 and T2's entries will come from your modified commands.txt.