|
| 1 | +# Instructions |
| 2 | + |
| 3 | +## Introduction |
| 4 | + |
| 5 | +In this tutorial, you will implement a heavy hitter detection filter. |
| 6 | + |
| 7 | +Network flows typically have a fairly wide distribution in terms of the |
| 8 | +data they transmit, with most of the flows sending little data and few |
| 9 | +flows sending a lot. The latter flows are called heavy hitters, and they |
| 10 | +often have a detrimental effect to network performance. This is |
| 11 | +because they cause congestion, leading to significantly increased completion |
| 12 | +times for small, short-lived flows. Detecting heavy hitters allows us to treat them |
| 13 | +differently, e.g. we can put their packets in low priority queues, allowing |
| 14 | +packets of other flows to face little or no congestion. |
| 15 | + |
| 16 | +In this example, you will implement a heavy hitter detection filter within |
| 17 | +a router. You can find a skeleton of the program in simple_router.p4. In that |
| 18 | +file, you have to fill in the parts that are marked with TODO. |
| 19 | + |
| 20 | +This example is based on [count-min sketch](http://theory.stanford.edu/~tim/s15/l/l2.pdf). |
| 21 | +In fact, we use two count-min sketches which are reset with an offset |
| 22 | +equal to their half-life. With every new packet coming in, we update |
| 23 | +the values of both sketches but we use only the ones of the least |
| 24 | +recently reset one to decide whether a packet belongs to a heavy hitter |
| 25 | +flow or not. |
| 26 | + |
| 27 | +> **Spoiler alert:** There is a reference solution in the `solution` |
| 28 | +> sub-directory. Feel free to compare your implementation to the |
| 29 | +> reference. |
| 30 | +
|
| 31 | + |
| 32 | +## Step 1: Run the (incomplete) starter code |
| 33 | + |
| 34 | +The directory with this README also contains a skeleton P4 program, |
| 35 | +`simple_router.p4`, which implements a simple router. Your job will be to |
| 36 | +extend this skeleton program to properly implement a heavy hitter |
| 37 | +detection filter. |
| 38 | + |
| 39 | +Before that, let's compile the incomplete `simple_router.p4` and bring |
| 40 | +up a switch in Mininet to test its behavior. |
| 41 | + |
| 42 | +1. In your shell, run: |
| 43 | + ```bash |
| 44 | + ./run.sh |
| 45 | + ``` |
| 46 | + This will: |
| 47 | + * create a p4app application, |
| 48 | + * compile `simple_switch.p4`, |
| 49 | + * generate control plane code, |
| 50 | + * start a Mininet instance with one switch (`s1`) conected to |
| 51 | + two hosts (`h1` and `h2`). |
| 52 | + * install the control plane code to your switch, |
| 53 | + * The hosts are assigned IPs of `10.0.0.10` and `10.0.1.10`. |
| 54 | + |
| 55 | +2. You should now see a Mininet command prompt. Run ping between |
| 56 | + `h1` and `h2` to make sure that everything runs correctly: |
| 57 | + ```bash |
| 58 | + mininet> h1 ping h2 |
| 59 | + ``` |
| 60 | + You should see all packets going through. |
| 61 | + |
| 62 | +3. Type `exit` to leave each Mininet command line. |
| 63 | + |
| 64 | +### A note about the control plane |
| 65 | + |
| 66 | +A P4 program defines a packet-processing pipeline, but the rules |
| 67 | +within each table are inserted by the control plane. When a rule |
| 68 | +matches a packet, its action is invoked with parameters supplied by |
| 69 | +the control plane as part of the rule. |
| 70 | + |
| 71 | +In this exercise, we have already implemented the control plane |
| 72 | +logic for you. As part of invoking `run.sh`, a set of rules is generated |
| 73 | +by `setup.py` and when bringing up the Mininet instance, these |
| 74 | +packet-processing rules are installed in the tables of |
| 75 | +the switch. These are defined in the `simple_router.config` file. |
| 76 | + |
| 77 | +## Step 2: Implement the heavy hitter detection filter |
| 78 | + |
| 79 | +The `simple_router.p4` file contains a skeleton P4 program with key pieces of |
| 80 | +logic replaced by `TODO` comments. Your implementation should follow |
| 81 | +the structure given in this file, just replace each `TODO` with logic |
| 82 | +implementing the missing piece. |
| 83 | + |
| 84 | +More specifically, you need to implement the main actions used within |
| 85 | +the heavy hitter detection block. In this example, when our filter |
| 86 | +classifies a packet as belonging to a heavy hitter flow, it marks |
| 87 | +it as such and then the switch drops it before reaching the |
| 88 | +egress control. |
| 89 | + |
| 90 | +## Step 3: Run your solution |
| 91 | + |
| 92 | +Our heavy hitter filter requires periodic reset of the registers of the |
| 93 | +count-min sketches. Running: |
| 94 | +```bash |
| 95 | +bash filter_reset.sh |
| 96 | +``` |
| 97 | +in a terminal window does that periodic reset for you. |
| 98 | + |
| 99 | +The filter currently allows 1000 bytes/sec (you can change that value |
| 100 | +in `setup.py`). |
| 101 | + |
| 102 | +In another terminal window, run: |
| 103 | +```bash |
| 104 | +./run.sh |
| 105 | +``` |
| 106 | + |
| 107 | +In the minigraph window, you can try: |
| 108 | +``` |
| 109 | +h1 ping -s 80 -i 0.1 h2 |
| 110 | +``` |
| 111 | +With this command h1, sends a packet with a total IP length |
| 112 | +of 100 bytes every 100 ms. When you run this command, you |
| 113 | +shouldn't see any drops. If on the other hand you run: |
| 114 | +``` |
| 115 | +h1 ping -s 80 -i 0.05 h2 |
| 116 | +``` |
| 117 | +h1 sends a packet every 50 ms, which puts the flow above |
| 118 | +the filter limit. In this case you will observe that about |
| 119 | +half of the packets send by h1 are being dropped at the switch. |
| 120 | + |
| 121 | +### Next steps |
| 122 | +Check out the code in `setup.py` and `filter_reset.sh`. By changing |
| 123 | +the constants in those, you can experiment with different |
| 124 | +heavy hitter threshold levels, count-min sketch sizes and the accuracy |
| 125 | +of the throughput approximation. |
| 126 | + |
0 commit comments