Homework 5
Changelog
- v1: November 14, 2019
Overview
In this homework assignment, you will develop a simple form of in-band network telemetry using the P4 language. You will also see some of the shortcomings of the language with respect to modularity.
Due Date
- 11:59pm, November 26, 2019
Academic Integrity
This assignment must be completed individually. All work you submit
must be your own and sharing or receiving code is forbidden, with the
exception of your partner. Do not look for or submit code you find on
the Internet, and do not post solutions or partial solutions on the
discussion site. If you make use of any outside materials, you must
give attribution. You may ask general questions about the development
environment, p4c
, bmv2
, Mininet, etc., and you may discuss
high-level details of the exercises with your classmates. If you have
any questions about what is allowed and what is not allowed, please
ask the instructor first!
Starter Code
You can download starter code for this assignment as a zipfile from CMS.
Exercise 0: Warmup
To familiarize yourself with the starter code, take a look at the
files in the homework05
directory. It includes two sub-directories,
source_routing
and tunnel
, which implement basic point-to-point
forwarding based on solutions to previous homework assignments. Note
that we have factored out the headers a common file headers.p4
which
is included in the switch.p4
for each solution.
Test that each forwarding solution works by linking its switch.p4
file in the top-level directory and running it as follows:
% ln -s source_route/switch.p4 switch.p4
% make
...
mininet> xterm h1 h2
You can use the provided send.py
and receive.py
scripts in each
directory to send data between hosts.
For example, using the source_routing
code, the send.py
script
will prompt you for a sequence of hops (associated with ports) that
connect the source to the destination. With the topology supplied in
the topology.json
file, you could either use the sequence
2 1
or the sequence 2 3 2 2 1
to reach h2
from h1
. In either case,
on the receiver side, you should see an output like this:
sniffing on eth0
0000 FF FF FF FF FF FF 08 00 00 00 01 11 08 00 45 00 ..............E.
0010 00 21 00 01 00 00 3E 11 63 AB 0A 00 01 0B 0A 00 .!....>.c.......
0020 02 16 04 D2 10 E1 00 0D D3 00 00 00 00 00 00 ...............
###[ Ethernet ]###
dst = ff:ff:ff:ff:ff:ff
src = 08:00:00:00:01:11
type = 0x800
###[ IP ]###
version = 4L
ihl = 5L
tos = 0x0
len = 33
id = 1
flags =
frag = 0L
ttl = 62
proto = udp
chksum = 0x63ab
src = 10.0.1.11
dst = 10.0.2.22
\options \
###[ UDP ]###
sport = 1234
dport = 4321
len = 13
chksum = 0xd300
###[ Telemetry ]###
count = 0
maxBytes = 0
\hops \
For the tunnel
code, you will need to run the P4 Runtime controller
provided in tunnel/mycontroller.py
.
To submit: Nothing.
Exercise 1: Modular In-Band Telemetry
In-band network telemetry refers to a family of applications that collect information about how the network is forwarding packets using (certain) data packets rather than separate monitoring probes. For example, one could keep track of the forwarding paths that packets take (useful when the network uses multi-path forwarding such as ECMP), or characteristics of the path itself such as the peak utilization aggregated across each link.
In this exercise we will implement a simple form of in-band telemetry that collects two pieces of information:
-
The sequence of ports used to forward the packet through the network, stored in reverse order
-
The approximate maximum number of bytes transmitted on any of those ports, calculated using an expotentially-weighted moving average.
The headers.p4
file defines a pair of headers that represent this
data:
header telemetry_t {
bit<8> count;
bit<32> maxBytes;
}
header hop_t {
bit<16> portId;
}
struct headers {
...
telemetry_t telemetry;
hop_t[MAX_HOPS] hops;
}
Note that count
indicates the number of hop_t
headers that follow
while maxBytes
is populated with the approximate maximum number of
bytes.
Your job is to fill in the missing code in telemetry.p4
so it
collects this data. However, for full credit, your solution should
work with any reasonable forwarding scheme. That is, as long as the
base forwarding scheme invokes your parser, egress control, and
deparser at the appropriate program point, the combined program should
collect correct telemetry data. You can check that your solution meets
this requirement by testing that it works with both
source_route/switch.p4
and tunnel/switch.p4
.
Implementation Steps
To complete this exericse, you should extend the starter code in
telemetry.p4
as follows:
-
Fill in the parser to extract the
telemetry
andhops
headers from the packet data. For simplicity, you may assume that telemetry packets all have UDP destination port4321
. -
Fill in the deparser to emit the
telemetry
andhops
headers. -
Fill in the egress control to populate the
hops
stack with the list of the ports used to forward the packet through the network. Recall that in the egress control,standard_metadata.egress_port
contains the port selected by the ingress control. -
Note that for the supplied
receive.py
script to work correctly, you will likely need to update some fields in theipv4
andudp
headers to reflect the fact the new size of the packet. - Now extend your solution to keep track of an exponentially weighted
moving average of the number of bytes transmitted on each port. You
may assume that the switch has at most 16 ports. More specifically,
on each packet, you should update the estimate as follows:
new_estimate = .75 * old_estimate + .25 * packet_size
Note that the packet size can be obtained from the IP header or from
standard_metadata.packet_length
. Also note that while P4 does not have floating-point numbers, you can implement division by powers of 2 using shifting. - Finally, use these estimates to compute an approximate value for the number of bytes seen at the most congested port as this packet traversed the network.
Testing
To test that your solution is working correctly, you can use the
supplied send.py
and receive.py
scripts. Your solution should work
in an arbitrary (connected) topology and you should be able to verify
that it is working as expected by examining the telemetry data printed
by the receive.py
script.
To submit: Submit telemetry.p4
and submit on CMS.
Karma: Other path properties
Note: Karma exercises are suggested problems that are completely optional. Feel free to try them if you are so inclined, or skip them if you are busy!
-
Verify that your solution works with a multi-path routing scheme such as ECMP. Write a script to visualize or analyze the load balancing properties of the network using collected telemetry data.
-
Explore adding other forms of telemetry such as timestamps, or the depth of the queue in the traffic manager.
To submit: Assemble your solution into a file karma.zip
and
submit on CMS.
Debriefing
-
How many hours did you spend on this assignment?
-
Would you rate it as easy, moderate, or difficult?
-
If you worked with a partner, please briefly describe both of your contributions to the solution you submitted.
-
How deeply do you feel you understand the material it covers (0%-100%)?
-
If you have any other comments, I would like to hear them! Please write them down or send email to
jnfoster@cs.cornell.edu
To submit: debriefing.txt