This assignment includes 2 exercises: Access Control List (ACL) and Load Balancing. Both exercises assume that you possess basic networking knowledge and some familiarity with the P4 language. Please take a look at the P4 language spec. We use P4_16 in this assignment.
- Access Control List asks you to write a P4 program to implement an ACL on a switch.
- Load Balancing asks you to write a P4 program to implement a simple load balancer on a switch.
This assignment can be done individually or in groups of 2 students. You are only required to implement either access control list or load balancing. If you implement both, you can get a bonus of two points.
We provide a new VM for this assignment. The vagrantfile is under course-net-assignment/assignment4/
.
To build the virtual machine:
- Use
git pull
to get the latestcourse-net-assignment
repo. - Use
cd course-net-assignment/assignment4/
to enter the assignment directory that contains the configuration of the new VM. - Use
vagrant up
to provision the VM and install the necessary dependencies. This will take about 1 hour or even longer. - Similar to previous assignments, you can use
vagrant ssh
to enter the VM andvagrant suspend
to suspend the VM.
Before you start this assignment, review the lecture slides on programmable switches. In addition, the P4 tutorial and cheatsheet are also helpful for this assignment.
Place yourself in the course-net-assignment/assignment4/exercises/acl
directory.
We provide a skeleton P4 program,
acl.p4
, which initially forwards all packets. Your job is to
extend this skeleton program to properly implement an ACL with two following rules:
- drop all the UDP packets with dstPort=80
- drop all the packets with dstIP=10.0.1.4
Before that, let's compile the incomplete acl.p4
and bring
up a switch in Mininet to test its behavior.
-
In your shell, run:
make run
This will:
- compile
acl.p4
, and - start a Mininet instance with one switch (
s1
) connected to four hosts (h1
,h2
,h3
andh4
). Mininet is a network simulator that can simulate a virtual network in the VM. - The hosts are assigned with IP addresses of
10.0.1.1
,10.0.1.2
,10.0.1.3
and10.0.1.4
. The output of this command line may be useful when you debug.
- compile
-
You should now see a Mininet command prompt. Open two terminals for
h1
andh2
, respectively:mininet> xterm h1 h2
-
Each host includes a small Python-based messaging client and server. In
h2
's xterm, go to the current exercise folder (cd exercises/acl
) and start the server with the listening port:./receive.py 80
-
In
h1
's xterm, go to the current exercise folder (cd exercises/acl
) and send a message toh2
:./send.py 10.0.1.2 UDP 80 "P4 IS COOL"
The command line means
h1
will send a message to10.0.1.2
with udp.dstport=80. The message will be received and displayed inh2
. -
Type
exit
to leave each xterm and the Mininet command line. Then, to stop mininet:make stop
And to delete all pcaps, build files, and logs:
make clean
A P4 program defines a packet-processing pipeline, but the rules within each table are inserted by the control plane. When a rule matches a packet, its action is invoked with parameters supplied by the control plane as part of the rule.
As part of bringing up the Mininet instance, the
make run
command will install packet-processing rules in the tables of
each switch. These are defined in the s1-acl.json
files.
Important: We use P4Runtime to install the control plane rules. The
content of files s1-acl.json
refer to specific names of tables, keys, and
actions, as defined in the P4Info file produced by the compiler (look for the
file build/acl.p4info
after executing make run
). Any changes in the P4
program that add or rename tables, keys, or actions will need to be reflected in
these s1-acl.json
files.
The acl.p4
file contains a skeleton P4 program with key pieces of
logic replaced by TODO
comments. Your implementation should follow
the structure given in this file---replace each TODO
with logic
implementing the missing piece.
A complete acl.p4
will contain the following components:
- Header type definitions for Ethernet (
ethernet_t
), IPv4 (ipv4_t
), TCP (tcp_t
) and UDP (udp_t
). - Parsers for Ethernet, IPv4, TCP or UDP headers.
- An action
drop()
to drop a packet, usingmark_to_drop()
. - An action (called
ipv4_forward
) that:- Sets the egress port for the next hop.
- Updates the ethernet destination address with the address of the next hop.
- Updates the ethernet source address with the address of the switch.
- Decrements the TTL.
- TODO: A control that:
- Defines a table that will match IP dstAddr and UDP dstPort, and
invoke either
drop
orNoAction
. - An
apply
block that applies the table. - Rules added to
s1-acl.json
that denies all the UDP packets with dstPort=80 or dstAddr=10.0.1.4.
- Defines a table that will match IP dstAddr and UDP dstPort, and
invoke either
- A
package
instantiation supplied with the parser, control, and deparser.In general, a package also requires instances of checksum verification and recomputation controls. These are not necessary for this assignment and are replaced with instantiations of empty controls.
Follow the instructions from Step 1. This time, your message from
h1
should not be delivered to h4
and any message with a udp.dstPort=80 will be dropped by the switch.
Place yourself in the assignment4/exercises/load_balance
directory.
In this exercise, you will implement a simple load balancer on a switch. The switch you will implement will use two tables to forward packets to one of two destination hosts at random. The first table will use a hash function (applied to a 5-tuple consisting of the source and destination IP addresses, IP protocol, and source and destination TCP ports) to select one of two hosts. The second table will use the computed hash value to forward the packet to the selected host.
The directory with this README also contains a skeleton P4 program,
load_balance.p4
, which initially drops all packets. Your job is to extend it to properly forward packets.
Before that, let's compile the incomplete load_balance.p4
and bring
up a switch in Mininet to test its behavior.
-
In your shell, run:
make run
This will:
- compile
load_balance.p4
, and - start a Mininet instance with one switch (
s1
) connected to four hosts (h1
,h2
,h3
andh4
). - The hosts are assigned IPs of
10.0.1.1
,10.0.1.2
,10.0.1.3
and10.0.1.4
. - We use the IP address 10.0.1.10 to indicate traffic that should be
load balanced between
h2
andh3
.
- compile
-
You should now see a Mininet command prompt. Open three terminals for
h1
,h2
andh3
, respectively:mininet> xterm h1 h2 h3
-
Each host includes a small Python-based messaging client and server. In
h2
andh3
's XTerms, go to the current exercise folder (cd exercises/load_balance
) and start the servers with listening port:./receive.py 1234
You may need to run
chmod +x receive.py
to make your python script executable. -
In
h1
's XTerm, go to the current exercise folder (cd exercises/load_balance
) and send a message from the client:./send.py 10.0.1.10 "P4 IS COOL"
Run the above command line several times. The message will not be received by
h2
orh3
. -
Type
exit
to leave each XTerm and the Mininet command line. Then, to stop mininet:make stop
And to delete all pcaps, build files, and logs:
make clean
The message was not received because each switch is programmed with
load_balance.p4
, which drops all packets on arrival. Your job is to
extend this file.
The load_balance.p4
file contains a skeleton P4 program with key
pieces of logic replaced by TODO
comments. These should guide your
implementation---replace each TODO
with logic implementing the
missing piece.
A complete load_balance.p4
will contain the following components:
- Header type definitions for Ethernet (
ethernet_t
), IPv4 (ipv4_t
), TCP (tcp_t
) and UDP (udp_t
).. - Parsers for Ethernet, IPv4, TCP or UDP headers.
- An action
drop()
to drop a packet, usingmark_to_drop()
. - TODO: Two tables, which will respectively:
- Select the next hop
- Set the dstip and egress port
- TODO: A control that applies the two tables in step 4.
- A
package
instantiation supplied with the parser, control, and deparser.In general, a package also requires instances of checksum verification and recomputation controls. These are not necessary for this assignment and are replaced with instantiations of empty controls.
Follow the instructions from Step 1. This time, your message from
h1
should be delivered to h2
or h3
. If you send several
messages, they should be spread between h2
and h3
.
- The bash script
test.sh
will run all the exercises with your own implementations. You can also pass "acl" or "lb" as an argument totest.sh
(e.g.test.sh acl
) to test only one exercise. - Do remember to run
make stop
andmake clean
every time before you relaunch your program.
You must submit:
- Put your source code for one of the two exercises, in a folder called
acl
orload_balance
, and submit inassignment4.zip
file. Make sure to submit both the p4 code and the corresponding json file that configures the table entries. - Bonus: If you submit both
acl
andload_balance
and they pass all the tests, you can get a bonus of 2 points, in addition to the 10 points of this assignment. - Submit the assignment by uploading your files to Gradescope. Join the course with entry code 95KRDN.
As always, start early and feel free to ask questions on Piazza and in office hours.
For students that find this assignment not challenging enough, you can read NetCache and NetChain, implement them by yourselves, and think about new applications that can be built with programmable switches.