6.4 KiB
Implementing an ARP/ICMP Responder
Introduction
This exercise extends the IPv4 Forwarding program to
allow your switches to respond to ARP and ICMP requests. Once implemented,
your hosts will be able to ping
other hosts connected to the switch, and
have the switch respond.
This exercise makes several simplifying assumptions:
- The network topology contains exactly one switch and two hosts.
- ARP and ICMP requests to the hosts are ignored; only requests sent to the switch receive responses.
Implementing the full functionality of ARP and ICMP is straightforward but beyond the scope of this tutorial and left as an exercise to the reader.
Spoiler alert: There is a reference solution in the
solution
sub-directory. Feel free to compare your implementation to the reference.
Step 1: Run the (incomplete) starter code
The directory with this README also contains a skeleton P4 program,
arp.p4
, which initially drops all packets. Your job will be to
extend it to reply to ARP and ICMP requests.
As a first step, compile the incomplete arp.p4
and bring up a
switch in Mininet to test its behavior.
-
In your shell, run:
./run.sh
This will:
- compile
arp.p4
, and - start a Mininet instance with one switch (
s1
) connected to two hosts (h1
,h2
). - The hosts are assigned IPs of
10.0.1.10
and10.0.2.10
.
- compile
-
Once the P4 source compiles without error, you can test your program at the mininet prompt using the
ping
utility.mininet> h1 ping h2
Once the program is implemented correctly, you will see a response to the ping in the mininet window.
-
Type
exit
in the mininet terminal to exit.
A note about the control plane
P4 programs define a packet-processing pipeline, but the rules governing packet processing are inserted into the pipeline 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.
In this exercise, the control plane logic has already been implemented. As
part of bringing up the Mininet instance, the run.sh
script will install
packet-processing rules in the tables of each switch. These are defined in the
simple_router.config
file.
Step 2: Implement ARP/ICMP Replies
In this exercise, we are using entries in the ipv4_lpm
table as a
database, which we can reference when responding to ARP and ICMP requests.
Without the proper entries in the table, the solution will not work.
From a high-level, the task involves implementing two main components: ARP replies and ICMP replies.
ARP Reply
When the switch receives and ARP request asking to resolve the switch's IP address, it will need to perform the following actions:
- Swap the source and destination MAC addresses in the Ethernet header,
- set the ARP operation to ARP_REPLY (
2
) in the ARP header, - update the sender hardware address (SHA) and sender protocol address (SPA) in the ARP header to be the MAC and IP addresses of the switch, and
- set the target hardware address (THA) and target protocol address (TPA) to be the SHA and SPA of the arriving ARP packet.
ICMP Reply
When the switch receives and ICMP request containing the switch's IP and MAC addresses, it will need to perform the following actions:
- Swap the source and destination MAC addresses in the Ethernet header,
- swap the source and destination IP addresses in the ICMP header, and
- set the type field in the ICMP header to
ICMP_ECHO_REPLY
(0
). - To simplify the exercise, we can ignore the checksum by setting to checksum field to 0.
We have provided a skeleton arp.p4
file to get you started. In this
file, places to modify are marked by TODO
.
There are, of course, different possible solutions. We describe one approach
below. It builds on the IPv4 Forwarding solution, which
used the table ipv4_lpm
for L3 forwarding, by adding a second table named
forward
, which checks if a packet is an ARP or ICMP packet and invokes
actions to send an ARP reply, forward an IPv4 packet, or send an ICMP reply.
Broadly speaking, a complete solution will contain the following components:
-
Header type definitions for
ethernet_t
,arp_t
,ipv4_t
, andicmp_t
. -
A structure (named
my_metadata_t
inarp.p4
) with metadata fields for the packet's souce and destination MAC addresses, IPv4 address, egress port, as well as a hard-coded MAC address for the switch. -
TODO: Parsers for Ethernet, ARP, IPv4, and ICMP packet header types.
-
TODO: A control type declaration for ingress processing, containing:
-
An action for
drop
. -
An action (named
set_dst_info
) to store information in the metadata structure, rather than immediately writing to the packet header. -
A table (named
ipv4_lpm
) that will match on the destination IP address and invoke theset_dst_info
action. -
An action to send an ICMP reply.
-
An action to send an ARP reply.
-
A table (named
forward
) that will forward IPv4 packets, send an ARP reply, send an ICMP reply, or drop a packet. -
An
apply
block that implements the control logic to invoke the two tables.
-
-
A deparser that emits headers in the proper order.
To keep the exercise simple, we will ignore the ipv4_checksum
. You should not
need any control plane rules for this exercise.
Step 3: Run your solution
Follow the instructions from Step 1. This time, you should be able to
successfully ping
the switch.
Troubleshooting
There are several ways that problems might manifest:
-
arp.p4
fails to compile. In this case,run.sh
will report the error emitted from the compiler and stop. -
arp.p4
compiles, but the switch does not process packets in the desired way. Thebuild/logs/<switch-name>.log
files contain trace messages describing how each switch processes each packet. The output is detailed and can help pinpoint logic errors in your implementation.
Note that there are no control plane rules installed in this example, and so the
receive.py
andsend.py
scripts from the IPv4 Forwarding example will not work.
Cleaning up Mininet
In the latter case above, run.sh
may leave a Mininet instance running in
the background. Use the following command to clean up these instances:
mn -c
Next Steps
Congratulations, your implementation works! Move on to the next exercise: turning your switch into a Calculator.