diff --git a/P4D2_2017_Fall/exercises/README.md b/P4D2_2017_Fall/exercises/README.md index 256d2b7..2cf3de8 100644 --- a/P4D2_2017_Fall/exercises/README.md +++ b/P4D2_2017_Fall/exercises/README.md @@ -9,7 +9,7 @@ programming, organized into four modules: 1. Introduction * [Basic Forwarding](./basic) -* [Scrambler](./scrambler) +* [Basic Tunneling](./basic_tunnel) 2. Monitoring and Debugging * [Explicit Congestion Notification](./ecn) @@ -21,7 +21,6 @@ programming, organized into four modules: 4. Dynamic Behavior * [Load Balancing](./load_balance) -* [HULA](./hula) ## Obtaining required software diff --git a/P4D2_2017_Fall/exercises/scrambler/Makefile b/P4D2_2017_Fall/exercises/scrambler/Makefile deleted file mode 100644 index f378756..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/Makefile +++ /dev/null @@ -1 +0,0 @@ -include ../../utils/Makefile diff --git a/P4D2_2017_Fall/exercises/scrambler/README.md b/P4D2_2017_Fall/exercises/scrambler/README.md deleted file mode 100644 index 63c3562..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/README.md +++ /dev/null @@ -1,123 +0,0 @@ -# Implementing basic forwarding with scrambled addresses - -## Introduction - -In this exercise, you will extend your solution to the basic -forwarding exercise with a new twist: switches will invert the bits -representing Ethernet and IPv4 address. Hence, in our triangle -topology, the packets in the interior of the network will have -unintelligble addresses. - -> **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, -`scrambler.p4`, which initially drops all packets. Your job (in the -next step) will be to extend it to properly forward IPv4 packets. - -Before that, let's compile the incomplete `scrambler.p4` and bring -up a switch in Mininet to test its behavior. - -1. In your shell, run: - ```bash - make - ``` - This will: - * compile `scrambler.p4`, and - * start a Mininet instance with three switches (`s1`, `s2`, `s3`) configured - in a triangle, each connected to one host (`h1`, `h2`, `h3`). - * The hosts are assigned IPs of `10.0.1.1`, `10.0.2.2`, etc. - -2. You should now see a Mininet command prompt. Open two terminals -for `h1` and `h2`, respectively: - ```bash - mininet> xterm h1 h2 - ``` -3. Each host includes a small Python-based messaging client and -server. In `h2`'s xterm, start the server: - ```bash - ./receive.py - ``` -4. In `h1`'s xterm, send a message from the client: - ```bash - ./send.py 10.0.2.2 "P4 is cool" - ``` - The message will not be received. -5. Type `exit` to leave each xterm and the Mininet command line. - -The message was not received because each switch is programmed with -`scrambler.p4`, which drops all packets on arrival. Your job is to -extend this file. - -### 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 -`make` script will install packet-processing rules in the tables of -each switch. These are defined in the `sX-commands.txt` files, where -`X` corresponds to the switch number. - -**Important:** A P4 program also defines the interface between the -switch pipeline and control plane. The `sX-commands.txt` files -contain lists of commands for the BMv2 switch API. These commands -refer to specific tables, keys, and actions by name, and any changes -in the P4 program that add or rename tables, keys, or actions will -need to be reflected in these command files. - -## Step 2: Extend the basic forwarding solution to flip bits - -The `scrambler.p4` file contains a skeleton P4 program in which one of -the actions has a `TODO` comment. These should guide your -implementation---replace the `TODO` with logic implementing the -missing piece. - -A complete `scrambler.p4` will add an action `flip()` that inverts the -bits in the Ethernet and IPv4 headers. - -## Step 3: Run your solution - -Follow the instructions from Step 1. This time, your message from -`h1` should be delivered to `h2`. - -### Troubleshooting - -There are several issues that might arise when developing your -solution: - -1. `scrambler.p4` fails to compile. In this case, `make` will -report the error emitted from the compiler and stop. - -2. `scrambler.p4` compiles but does not support the control plane -rules in the `sX-commands.txt` files that `make` tries to install -using the BMv2 CLI. In this case, `make` will report these errors -to `stderr`. Use these error messages to fix your `scrambler.p4` -implementation. - -3. `scrambler.p4` compiles, and the control plane rules are installed, -but the switch does not process packets in the desired way. The -`build/logs/.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. - -#### Cleaning up Mininet - -In the latter two cases above, `make` may leave a Mininet instance -running in the background. Use the following command to clean up -these instances: - -```bash -mn -c -``` - -## Next Steps - -Congratulations, your implementation works! Move on to the next -exercise: implementing [Explicit Congestion Notification](../ecn). diff --git a/P4D2_2017_Fall/exercises/scrambler/receive.py b/P4D2_2017_Fall/exercises/scrambler/receive.py deleted file mode 100755 index c93182f..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/receive.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python -import sys -import struct -import os - -from scapy.all import sniff, sendp, hexdump, get_if_list, get_if_hwaddr -from scapy.all import Packet, IPOption -from scapy.all import ShortField, IntField, LongField, BitField, FieldListField, FieldLenField -from scapy.all import IP, UDP, Raw -from scapy.layers.inet import _IPOption_HDR - -def get_if(): - ifs=get_if_list() - iface=None - for i in get_if_list(): - if "eth0" in i: - iface=i - break; - if not iface: - print "Cannot find eth0 interface" - exit(1) - return iface - -class IPOption_MRI(IPOption): - name = "MRI" - option = 31 - fields_desc = [ _IPOption_HDR, - FieldLenField("length", None, fmt="B", - length_of="swids", - adjust=lambda pkt,l:l+4), - ShortField("count", 0), - FieldListField("swids", - [], - IntField("", 0), - length_from=lambda pkt:pkt.count*4) ] -def handle_pkt(pkt): - print "got a packet" - pkt.show2() -# hexdump(pkt) - sys.stdout.flush() - - -def main(): - ifaces = filter(lambda i: 'eth' in i, os.listdir('/sys/class/net/')) - iface = ifaces[0] - print "sniffing on %s" % iface - sys.stdout.flush() - sniff(filter="tcp", iface = iface, - prn = lambda x: handle_pkt(x)) - -if __name__ == '__main__': - main() diff --git a/P4D2_2017_Fall/exercises/scrambler/s1-commands.txt b/P4D2_2017_Fall/exercises/scrambler/s1-commands.txt deleted file mode 100644 index 0a63bdb..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/s1-commands.txt +++ /dev/null @@ -1,6 +0,0 @@ -table_set_default ipv4_lpm drop -table_add ipv4_lpm ipv4_forward 10.0.2.2/32 => 00:00:00:02:02:00 2 -table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:03:02:00 3 -table_add ipv4_lpm ipv4_forward 245.255.254.254/32 => ff:ff:ff:ff:fe:fe 1 -table_add ipv4_lpm ipv4_forward 245.255.253.253/32 => 00:00:00:02:02:00 2 -table_add ipv4_lpm ipv4_forward 245.255.252.252/32 => 00:00:00:03:02:00 3 diff --git a/P4D2_2017_Fall/exercises/scrambler/s2-commands.txt b/P4D2_2017_Fall/exercises/scrambler/s2-commands.txt deleted file mode 100644 index f1797a6..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/s2-commands.txt +++ /dev/null @@ -1,6 +0,0 @@ -table_set_default ipv4_lpm drop -table_add ipv4_lpm ipv4_forward 10.0.1.1/32 => 00:00:00:01:02:00 2 -table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:03:03:00 3 -table_add ipv4_lpm ipv4_forward 245.255.254.254/32 => 00:00:00:01:02:00 2 -table_add ipv4_lpm ipv4_forward 245.255.253.253/32 => ff:ff:ff:ff:fd:fd 1 -table_add ipv4_lpm ipv4_forward 245.255.252.252/32 => 00:00:00:03:03:00 3 diff --git a/P4D2_2017_Fall/exercises/scrambler/s3-commands.txt b/P4D2_2017_Fall/exercises/scrambler/s3-commands.txt deleted file mode 100644 index a04f7ba..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/s3-commands.txt +++ /dev/null @@ -1,6 +0,0 @@ -table_set_default ipv4_lpm drop -table_add ipv4_lpm ipv4_forward 10.0.0.1/32 => 00:00:00:01:02:00 2 -table_add ipv4_lpm ipv4_forward 10.0.0.2/32 => 00:00:00:02:03:00 3 -table_add ipv4_lpm ipv4_forward 245.255.254.254/32 => 00:00:00:01:01:00 2 -table_add ipv4_lpm ipv4_forward 245.255.253.253/32 => 00:00:00:02:03:00 3 -table_add ipv4_lpm ipv4_forward 245.255.252.252/32 => ff:ff:ff:ff:fc:fc 1 diff --git a/P4D2_2017_Fall/exercises/scrambler/scrambler.p4 b/P4D2_2017_Fall/exercises/scrambler/scrambler.p4 deleted file mode 100644 index 8d4e115..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/scrambler.p4 +++ /dev/null @@ -1,180 +0,0 @@ -/* -*- P4_16 -*- */ -#include -#include - -const bit<16> TYPE_IPV4 = 0x800; - -/************************************************************************* -*********************** H E A D E R S *********************************** -*************************************************************************/ - -typedef bit<9> egressSpec_t; -typedef bit<48> macAddr_t; -typedef bit<32> ip4Addr_t; - -header ethernet_t { - macAddr_t dstAddr; - macAddr_t srcAddr; - bit<16> etherType; -} - -header ipv4_t { - bit<4> version; - bit<4> ihl; - bit<8> diffserv; - bit<16> totalLen; - bit<16> identification; - bit<3> flags; - bit<13> fragOffset; - bit<8> ttl; - bit<8> protocol; - bit<16> hdrChecksum; - ip4Addr_t srcAddr; - ip4Addr_t dstAddr; -} - -struct metadata { - /* empty */ -} - -struct headers { - ethernet_t ethernet; - ipv4_t ipv4; -} - -/************************************************************************* -*********************** P A R S E R *********************************** -*************************************************************************/ - -parser MyParser(packet_in packet, - out headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - - state start { - transition parse_ethernet; - } - - state parse_ethernet { - packet.extract(hdr.ethernet); - transition select(hdr.ethernet.etherType) { - TYPE_IPV4: parse_ipv4; - default: accept; - } - } - - state parse_ipv4 { - packet.extract(hdr.ipv4); - transition accept; - } -} - - -/************************************************************************* -************ C H E C K S U M V E R I F I C A T I O N ************* -*************************************************************************/ - -control MyVerifyChecksum(inout headers hdr, inout metadata meta) { - apply { } -} - - -/************************************************************************* -************** I N G R E S S P R O C E S S I N G ******************* -*************************************************************************/ - -control MyIngress(inout headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - action drop() { - mark_to_drop(); - } - - action flip() { - /* TODO: add code to flip bits in Ethernet and IPv4 addresses. */ - } - - action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) { - standard_metadata.egress_spec = port; - hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; - hdr.ethernet.dstAddr = dstAddr; - hdr.ipv4.ttl = hdr.ipv4.ttl - 1; - flip(); - } - - table ipv4_lpm { - key = { - hdr.ipv4.dstAddr: lpm; - } - actions = { - ipv4_forward; - drop; - NoAction; - } - size = 1024; - default_action = NoAction(); - } - - apply { - if (hdr.ipv4.isValid()) { - ipv4_lpm.apply(); - } - } -} - -/************************************************************************* -**************** E G R E S S P R O C E S S I N G ******************* -*************************************************************************/ - -control MyEgress(inout headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - apply { } -} - -/************************************************************************* -************* C H E C K S U M C O M P U T A T I O N ************** -*************************************************************************/ -control MyComputeChecksum(inout headers hdr, inout metadata meta) { - apply { - update_checksum( - hdr.ipv4.isValid(), - { hdr.ipv4.version, - hdr.ipv4.ihl, - hdr.ipv4.diffserv, - hdr.ipv4.totalLen, - hdr.ipv4.identification, - hdr.ipv4.flags, - hdr.ipv4.fragOffset, - hdr.ipv4.ttl, - hdr.ipv4.protocol, - hdr.ipv4.srcAddr, - hdr.ipv4.dstAddr }, - hdr.ipv4.hdrChecksum, - HashAlgorithm.csum16); - } -} - -/************************************************************************* -*********************** D E P A R S E R ******************************* -*************************************************************************/ - -control MyDeparser(packet_out packet, in headers hdr) { - apply { - packet.emit(hdr.ethernet); - packet.emit(hdr.ipv4); - } -} - -/************************************************************************* -*********************** S W I T C H ******************************* -*************************************************************************/ - -V1Switch( -MyParser(), -MyVerifyChecksum(), -MyIngress(), -MyEgress(), -MyComputeChecksum(), -MyDeparser() -) main; diff --git a/P4D2_2017_Fall/exercises/scrambler/send.py b/P4D2_2017_Fall/exercises/scrambler/send.py deleted file mode 100755 index 00496d9..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/send.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python -import argparse -import sys -import socket -import random -import struct - -from scapy.all import sendp, send, get_if_list, get_if_hwaddr -from scapy.all import Packet -from scapy.all import Ether, IP, UDP, TCP - -def get_if(): - ifs=get_if_list() - iface=None # "h1-eth0" - for i in get_if_list(): - if "eth0" in i: - iface=i - break; - if not iface: - print "Cannot find eth0 interface" - exit(1) - return iface - -def main(): - - if len(sys.argv)<3: - print 'pass 2 arguments: ""' - exit(1) - - addr = socket.gethostbyname(sys.argv[1]) - iface = get_if() - - print "sending on interface %s to %s" % (iface, str(addr)) - pkt = Ether(src=get_if_hwaddr(iface), dst='ff:ff:ff:ff:ff:ff') - pkt = pkt /IP(dst=addr) / TCP(dport=1234, sport=random.randint(49152,65535)) / sys.argv[2] - pkt.show2() - sendp(pkt, iface=iface, verbose=False) - - -if __name__ == '__main__': - main() diff --git a/P4D2_2017_Fall/exercises/scrambler/solution/scrambler.p4 b/P4D2_2017_Fall/exercises/scrambler/solution/scrambler.p4 deleted file mode 100644 index e508af6..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/solution/scrambler.p4 +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- P4_16 -*- */ -#include -#include - -const bit<16> TYPE_IPV4 = 0x800; - -/************************************************************************* -*********************** H E A D E R S *********************************** -*************************************************************************/ - -typedef bit<9> egressSpec_t; -typedef bit<48> macAddr_t; -typedef bit<32> ip4Addr_t; - -header ethernet_t { - macAddr_t dstAddr; - macAddr_t srcAddr; - bit<16> etherType; -} - -header ipv4_t { - bit<4> version; - bit<4> ihl; - bit<8> diffserv; - bit<16> totalLen; - bit<16> identification; - bit<3> flags; - bit<13> fragOffset; - bit<8> ttl; - bit<8> protocol; - bit<16> hdrChecksum; - ip4Addr_t srcAddr; - ip4Addr_t dstAddr; -} - -struct metadata { - /* empty */ -} - -struct headers { - ethernet_t ethernet; - ipv4_t ipv4; -} - -/************************************************************************* -*********************** P A R S E R *********************************** -*************************************************************************/ - -parser MyParser(packet_in packet, - out headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - - state start { - transition parse_ethernet; - } - - state parse_ethernet { - packet.extract(hdr.ethernet); - transition select(hdr.ethernet.etherType) { - TYPE_IPV4: parse_ipv4; - default: accept; - } - } - - state parse_ipv4 { - packet.extract(hdr.ipv4); - transition accept; - } -} - - -/************************************************************************* -************ C H E C K S U M V E R I F I C A T I O N ************* -*************************************************************************/ - -control MyVerifyChecksum(inout headers hdr, inout metadata meta) { - apply { } -} - - -/************************************************************************* -************** I N G R E S S P R O C E S S I N G ******************* -*************************************************************************/ - -control MyIngress(inout headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - action drop() { - mark_to_drop(); - } - - action flip_ethernet() { - hdr.ethernet.srcAddr = ~hdr.ethernet.srcAddr; - hdr.ethernet.dstAddr = ~hdr.ethernet.dstAddr; - } - action flip_ipv4() { - hdr.ipv4.srcAddr = ~hdr.ipv4.srcAddr; - hdr.ipv4.dstAddr = ~hdr.ipv4.dstAddr; - } - - action flip() { - flip_ethernet(); - flip_ipv4(); - } - - action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) { - standard_metadata.egress_spec = port; - hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; - hdr.ethernet.dstAddr = dstAddr; - hdr.ipv4.ttl = hdr.ipv4.ttl - 1; - flip(); - } - - table ipv4_lpm { - key = { - hdr.ipv4.dstAddr: lpm; - } - actions = { - ipv4_forward; - drop; - NoAction; - } - size = 1024; - default_action = NoAction(); - } - - apply { - if (hdr.ipv4.isValid()) { - ipv4_lpm.apply(); - } - } -} - -/************************************************************************* -**************** E G R E S S P R O C E S S I N G ******************* -*************************************************************************/ - -control MyEgress(inout headers hdr, - inout metadata meta, - inout standard_metadata_t standard_metadata) { - apply { } -} - -/************************************************************************* -************* C H E C K S U M C O M P U T A T I O N ************** -*************************************************************************/ - -control MyComputeChecksum(inout headers hdr, inout metadata meta) { - apply { - update_checksum( - hdr.ipv4.isValid(), - { hdr.ipv4.version, - hdr.ipv4.ihl, - hdr.ipv4.diffserv, - hdr.ipv4.totalLen, - hdr.ipv4.identification, - hdr.ipv4.flags, - hdr.ipv4.fragOffset, - hdr.ipv4.ttl, - hdr.ipv4.protocol, - hdr.ipv4.srcAddr, - hdr.ipv4.dstAddr }, - hdr.ipv4.hdrChecksum, - HashAlgorithm.csum16); - } -} - -/************************************************************************* -*********************** D E P A R S E R ******************************* -*************************************************************************/ - -control MyDeparser(packet_out packet, in headers hdr) { - apply { - packet.emit(hdr.ethernet); - packet.emit(hdr.ipv4); - } -} - -/************************************************************************* -*********************** S W I T C H ******************************* -*************************************************************************/ - -V1Switch( -MyParser(), -MyVerifyChecksum(), -MyIngress(), -MyEgress(), -MyComputeChecksum(), -MyDeparser() -) main; diff --git a/P4D2_2017_Fall/exercises/scrambler/topology.json b/P4D2_2017_Fall/exercises/scrambler/topology.json deleted file mode 100644 index e33477c..0000000 --- a/P4D2_2017_Fall/exercises/scrambler/topology.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "hosts": [ - "h1", - "h2", - "h3" - ], - "switches": { - "s1": { "cli_input" : "s1-commands.txt" }, - "s2": { "cli_input" : "s2-commands.txt" }, - "s3": { "cli_input" : "s3-commands.txt" } - }, - "links": [ - ["h1", "s1"], ["s1", "s2"], ["s1", "s3"], - ["s3", "s2"], ["s2", "h2"], ["s3", "h3"] - ] -}