From 971ceb7d90db1999c7a9fc2bdfb9074e09c7299f Mon Sep 17 00:00:00 2001 From: nikkytub Date: Fri, 13 Mar 2020 10:35:35 +0530 Subject: [PATCH] Added quality of service(QOS) via Differentiated services (#330) * Added quality of service(QOS) via Differentiated services * Altered to classify network traffic in Ingress * Updated readme for QoS --- README.md | 1 + exercises/qos/Makefile | 3 + exercises/qos/README.md | 166 ++++++++++++++++++++ exercises/qos/qos.p4 | 202 +++++++++++++++++++++++++ exercises/qos/receive.py | 21 +++ exercises/qos/s1-runtime.json | 52 +++++++ exercises/qos/s2-runtime.json | 51 +++++++ exercises/qos/s3-runtime.json | 40 +++++ exercises/qos/send.py | 56 +++++++ exercises/qos/setup.png | Bin 0 -> 103713 bytes exercises/qos/solution/qos.p4 | 276 ++++++++++++++++++++++++++++++++++ exercises/qos/topology.json | 28 ++++ 12 files changed, 896 insertions(+) create mode 100644 exercises/qos/Makefile create mode 100644 exercises/qos/README.md create mode 100644 exercises/qos/qos.p4 create mode 100755 exercises/qos/receive.py create mode 100644 exercises/qos/s1-runtime.json create mode 100644 exercises/qos/s2-runtime.json create mode 100644 exercises/qos/s3-runtime.json create mode 100755 exercises/qos/send.py create mode 100644 exercises/qos/setup.png create mode 100644 exercises/qos/solution/qos.p4 create mode 100644 exercises/qos/topology.json diff --git a/README.md b/README.md index f5bb2f7..6502fd5 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ you get started with P4 programming, organized into several modules: * [Source Routing](./exercises/source_routing) * [Calculator](./exercises/calc) * [Load Balancing](./exercises/load_balance) +* [Quality of Service](./exercises/qos) 5. Stateful Packet Processing * [Firewall](./exercises/firewall) diff --git a/exercises/qos/Makefile b/exercises/qos/Makefile new file mode 100644 index 0000000..23bdc5b --- /dev/null +++ b/exercises/qos/Makefile @@ -0,0 +1,3 @@ +BMV2_SWITCH_EXE = simple_switch_grpc + +include ../../utils/Makefile diff --git a/exercises/qos/README.md b/exercises/qos/README.md new file mode 100644 index 0000000..8b62c7d --- /dev/null +++ b/exercises/qos/README.md @@ -0,0 +1,166 @@ +# Implementing QOS + +## Introduction + +The objective of this tutorial is to extend basic L3 forwarding with +an implementation of Quality of Service (QOS) using Differentiated Services. + +Diffserv is simple and scalable. It classifies and manages network traffic and provides QOS on modern IP networks. + +As before, we have already defined the control plane rules for +routing, so you only need to implement the data plane logic of your P4 +program. + +> **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, +`qos.p4`, which initially implements L3 forwarding. Your job (in the +next step) will be to extend it to properly set the `diffserv` bits. + +Before that, let's compile the incomplete `qos.p4` and bring up a +network in Mininet to test its behavior. + +1. In your shell, run: + ```bash + make + ``` + This will: + * compile `qos.p4`, and + * start a Mininet instance with three switches (`s1`, `s2`, `s3`) configured + in a triangle. There are 5 hosts. `h1` and `h11` are connected to `s1`. + `h2` and `h22` are connected to `s2` and `h3` is connected to `s3`. + * The hosts are assigned IPs of `10.0.1.1`, `10.0.2.2`, etc + (`10.0..`). + * The control plane programs the P4 tables in each switch based on + `sx-runtime.json` + +2. We want to send traffic from `h1` to `h2`. If we +capture packets at `h2`, we should see the right diffserv value. + +![Setup](setup.png) + +3. You should now see a Mininet command prompt. Open two terminals +for `h1` and `h2`, respectively: + ```bash + mininet> xterm h1 h2 + ``` +4. In `h2`'s XTerm, start the server that captures packets: + ```bash + ./receive.py + ``` +5. In `h1`'s XTerm, send one packet per second to `h2` using send.py +say for 30 seconds. + To send UDP: + ```bash + ./send.py --p=UDP --des=10.0.2.2 --m="P4 is cool" --dur=30 + ``` + To send TCP: + ```bash + ./send.py --p=TCP --des=10.0.2.2 --m="P4 is cool" --dur=30 + ``` + The message "P4 is cool" should be received in `h2`'s xterm, +6. At `h2`, the `ipv4.tos` field (DiffServ+ECN) is always 1 +7. type `exit` to close each XTerm window + +Your job is to extend the code in `qos.p4` to implement the diffserv logic +for setting the diffserv flag. + +## Step 2: Implement Diffserv + +The `qos.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. + +First we have to change the ipv4_t header by splitting the TOS field +into DiffServ and ECN fields. Remember to update the checksum block +accordingly. Then, in the egress control block we must compare the +protocol in IP header with IP protocols. Based on the traffic classes +and priority, the `diffserv` flag will be set. + +A complete `qos.p4` will contain the following components: + +1. Header type definitions for Ethernet (`ethernet_t`) and IPv4 (`ipv4_t`). +2. Parsers for Ethernet, IPv4, +3. An action to drop a packet, using `mark_to_drop()`. +4. An action (called `ipv4_forward`), which will: + 1. Set the egress port for the next hop. + 2. Update the ethernet destination address with the address of + the next hop. + 3. Update the ethernet source address with the address of the switch. + 4. Decrement the TTL. +5. An ingress control block that checks the protocols and sets the ipv4.diffserv. +6. A deparser that selects the order in which headers are inserted into the outgoing + packet. +7. A `package` instantiation supplied with the parser, control, + checksum verification and recomputation and deparser. + +## Step 3: Run your solution + +Follow the instructions from Step 1. This time, when your message from +`h1` is delivered to `h2`, you should see `tos` values change from 0x1 +to 0xb9 for UDP and 0xb1 for TCP. It depends upon the action you choose +in Ingress processing. + +To easily track the `tos` values you may want to redirect the output +of `h2` to a file by running the following for `h2` + ```bash + ./receive.py > h2.log + ``` +and just print the `tos` values `grep tos h2.log` in a separate window +``` + tos = 0xb9 + tos = 0xb9 + tos = 0xb9 + tos = 0xb9 + tos = 0xb9 + tos = 0xb9 + tos = 0xb9 + tos = 0xb9 + tos = 0xb1 + tos = 0xb1 + tos = 0xb1 + tos = 0xb1 + tos = 0xb1 + tos = 0xb1 + tos = 0xb1 + tos = 0xb1 + +``` + +### Food for thought + +How can we let the user use other protocols? + +### Troubleshooting + +There are several ways that problems might manifest: + +1. `qos.p4` fails to compile. In this case, `make` will report the + error emitted from the compiler and stop. +2. `qos.p4` compiles but does not support the control plane rules in + the `sX-runtime.json` files that `make` tries to install using + a Python controller. In this case, `make` will log the controller output + in the `logs` directory. Use these error messages to fix your `qos.p4` + implementation. +3. `qos.p4` compiles, and the control plane rules are installed, but + the switch does not process packets in the desired way. The + `/tmp/p4s..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. + The `build/-.pcap` also contains the + pcap of packets on each interface. Use `tcpdump -r -xxx` + to print the hexdump of the packets. + +#### 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 +make stop +``` diff --git a/exercises/qos/qos.p4 b/exercises/qos/qos.p4 new file mode 100644 index 0000000..f08586a --- /dev/null +++ b/exercises/qos/qos.p4 @@ -0,0 +1,202 @@ +/* -*- P4_16 -*- */ +#include +#include + +const bit<16> TYPE_IPV4 = 0x800; + +/* IP protocols */ +const bit<8> IP_PROTOCOLS_ICMP = 1; +const bit<8> IP_PROTOCOLS_IGMP = 2; +const bit<8> IP_PROTOCOLS_IPV4 = 4; +const bit<8> IP_PROTOCOLS_TCP = 6; +const bit<8> IP_PROTOCOLS_UDP = 17; +const bit<8> IP_PROTOCOLS_IPV6 = 41; +const bit<8> IP_PROTOCOLS_GRE = 47; +const bit<8> IP_PROTOCOLS_IPSEC_ESP = 50; +const bit<8> IP_PROTOCOLS_IPSEC_AH = 51; +const bit<8> IP_PROTOCOLS_ICMPV6 = 58; +const bit<8> IP_PROTOCOLS_EIGRP = 88; +const bit<8> IP_PROTOCOLS_OSPF = 89; +const bit<8> IP_PROTOCOLS_PIM = 103; +const bit<8> IP_PROTOCOLS_VRRP = 112; + + +/************************************************************************* +*********************** 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; +} + +/* + * TODO: split tos to two fields 6 bit diffserv and 2 bit ecn + */ +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> tos; + 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 { +} + +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(standard_metadata); + } + + 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; + } + +/* TODO: Implement actions for different traffic classes */ + + + table ipv4_lpm { + key = { + hdr.ipv4.dstAddr: lpm; + } + actions = { + ipv4_forward; + drop; + NoAction; + } + size = 1024; + default_action = NoAction(); + } + +/* TODO: set hdr.ipv4.diffserv on the basis of protocol */ + 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 { + /* TODO: replace tos with diffserv and ecn */ + update_checksum( + hdr.ipv4.isValid(), + { hdr.ipv4.version, + hdr.ipv4.ihl, + hdr.ipv4.tos, + 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/exercises/qos/receive.py b/exercises/qos/receive.py new file mode 100755 index 0000000..486f0d9 --- /dev/null +++ b/exercises/qos/receive.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +import sys +from scapy.all import sniff, get_if_list + + +def handle_pkt(pkt): + print "got a packet" + pkt.show2() + sys.stdout.flush() + + +def main(): + iface = 'eth0' + print "sniffing on %s" % iface + sys.stdout.flush() + sniff(iface=iface, prn=lambda x: handle_pkt(x)) + + +if __name__ == '__main__': + main() diff --git a/exercises/qos/s1-runtime.json b/exercises/qos/s1-runtime.json new file mode 100644 index 0000000..e79c845 --- /dev/null +++ b/exercises/qos/s1-runtime.json @@ -0,0 +1,52 @@ +{ + "target": "bmv2", + "p4info": "build/qos.p4.p4info.txt", + "bmv2_json": "build/qos.json", + "table_entries": [ + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.1.1", 32] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:01:01", + "port": 2 + } + }, + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.1.11", 32] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:01:11", + "port": 1 + } + }, + + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.2.0", 24] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:02:00", + "port": 3 + } + }, + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.3.0", 24] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:03:00", + "port": 4 + } + } + ] +} diff --git a/exercises/qos/s2-runtime.json b/exercises/qos/s2-runtime.json new file mode 100644 index 0000000..243f1d2 --- /dev/null +++ b/exercises/qos/s2-runtime.json @@ -0,0 +1,51 @@ +{ + "target": "bmv2", + "p4info": "build/qos.p4.p4info.txt", + "bmv2_json": "build/qos.json", + "table_entries": [ + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.2.2", 32] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:02:02", + "port": 2 + } + }, + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.2.22", 32] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:02:22", + "port": 1 + } + }, + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.1.0", 24] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:01:00", + "port": 3 + } + }, + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.3.0", 24] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:03:00", + "port": 4 + } + } + ] +} diff --git a/exercises/qos/s3-runtime.json b/exercises/qos/s3-runtime.json new file mode 100644 index 0000000..9e0f7fa --- /dev/null +++ b/exercises/qos/s3-runtime.json @@ -0,0 +1,40 @@ +{ + "target": "bmv2", + "p4info": "build/qos.p4.p4info.txt", + "bmv2_json": "build/qos.json", + "table_entries": [ + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.3.3", 32] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:03:03", + "port": 1 + } + }, + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.1.0", 24] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:01:00", + "port": 2 + } + }, + { + "table": "MyIngress.ipv4_lpm", + "match": { + "hdr.ipv4.dstAddr": ["10.0.2.0", 24] + }, + "action_name": "MyIngress.ipv4_forward", + "action_params": { + "dstAddr": "08:00:00:00:02:00", + "port": 3 + } + } + ] +} diff --git a/exercises/qos/send.py b/exercises/qos/send.py new file mode 100755 index 0000000..9887a3e --- /dev/null +++ b/exercises/qos/send.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +import argparse +import socket + +from scapy.all import sendp, send, hexdump, get_if_list, get_if_hwaddr +from scapy.all import Ether, IP, UDP, TCP + +from time import sleep + + +def get_if(): + 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 + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--p", help="Protocol name To send TCP/UDP etc packets", type=str) + parser.add_argument("--des", help="IP address of the destination", type=str) + parser.add_argument("--m", help="Raw Message", type=str) + parser.add_argument("--dur", help="in seconds", type=str) + args = parser.parse_args() + + if args.p and args.des and args.m and args.dur: + addr = socket.gethostbyname(args.des) + iface = get_if() + if args.p == 'UDP': + pkt = Ether(src=get_if_hwaddr(iface), dst="ff:ff:ff:ff:ff:ff") / IP(dst=addr, tos=1) / UDP(dport=4321, sport=1234) / args.m + pkt.show2() + try: + for i in range(int(args.dur)): + sendp(pkt, iface=iface) + sleep(1) + except KeyboardInterrupt: + raise + elif args.p == 'TCP': + pkt = Ether(src=get_if_hwaddr(iface), dst="ff:ff:ff:ff:ff:ff") / IP(dst=addr, tos=1) / TCP() / args.m + pkt.show2() + try: + for i in range(int(args.dur)): + sendp(pkt, iface=iface) + sleep(1) + except KeyboardInterrupt: + raise + + +if __name__ == '__main__': + main() diff --git a/exercises/qos/setup.png b/exercises/qos/setup.png new file mode 100644 index 0000000000000000000000000000000000000000..bf2a66b3f956de0c786ef031f50734ef35043e46 GIT binary patch literal 103713 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 literal 0 HcmV?d00001 diff --git a/exercises/qos/solution/qos.p4 b/exercises/qos/solution/qos.p4 new file mode 100644 index 0000000..01c6aff --- /dev/null +++ b/exercises/qos/solution/qos.p4 @@ -0,0 +1,276 @@ +/* -*- P4_16 -*- */ +#include +#include + +const bit<16> TYPE_IPV4 = 0x800; + +/* IP protocols */ +const bit<8> IP_PROTOCOLS_ICMP = 1; +const bit<8> IP_PROTOCOLS_IGMP = 2; +const bit<8> IP_PROTOCOLS_IPV4 = 4; +const bit<8> IP_PROTOCOLS_TCP = 6; +const bit<8> IP_PROTOCOLS_UDP = 17; +const bit<8> IP_PROTOCOLS_IPV6 = 41; +const bit<8> IP_PROTOCOLS_GRE = 47; +const bit<8> IP_PROTOCOLS_IPSEC_ESP = 50; +const bit<8> IP_PROTOCOLS_IPSEC_AH = 51; +const bit<8> IP_PROTOCOLS_ICMPV6 = 58; +const bit<8> IP_PROTOCOLS_EIGRP = 88; +const bit<8> IP_PROTOCOLS_OSPF = 89; +const bit<8> IP_PROTOCOLS_PIM = 103; +const bit<8> IP_PROTOCOLS_VRRP = 112; + + +/************************************************************************* +*********************** 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<6> diffserv; + bit<2> ecn; + 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 { +} + +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(standard_metadata); + } + + 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; + } + + /* Default Forwarding */ + action default_forwarding() { + hdr.ipv4.diffserv = 0; + } + + /* Expedited Forwarding */ + action expedited_forwarding() { + hdr.ipv4.diffserv = 46; + } + + /* Voice Admit */ + action voice_admit() { + hdr.ipv4.diffserv = 44; + } + + /* Assured Forwarding */ + /* Class 1 Low drop probability */ + action af_11() { + hdr.ipv4.diffserv = 10; + } + + /* Class 1 Med drop probability */ + action af_12() { + hdr.ipv4.diffserv = 12; + } + + /* Class 1 High drop probability */ + action af_13() { + hdr.ipv4.diffserv = 14; + } + + /* Class 2 Low drop probability */ + action af_21() { + hdr.ipv4.diffserv = 18; + } + + /* Class 2 Med drop probability */ + action af_22() { + hdr.ipv4.diffserv = 20; + } + + /* Class 2 High drop probability */ + action af_23() { + hdr.ipv4.diffserv = 22; + } + + /* Class 3 Low drop probability */ + action af_31() { + hdr.ipv4.diffserv = 26; + } + + /* Class 3 Med drop probability */ + action af_32() { + hdr.ipv4.diffserv = 28; + } + + /* Class 3 High drop probability */ + action af_33() { + hdr.ipv4.diffserv = 30; + } + + /* Class 4 Low drop probability */ + action af_41() { + hdr.ipv4.diffserv = 34; + } + + /* Class 4 Med drop probability */ + action af_42() { + hdr.ipv4.diffserv = 36; + } + + /* Class 4 High drop probability */ + action af_43() { + hdr.ipv4.diffserv = 38; + } + + table ipv4_lpm { + key = { + hdr.ipv4.dstAddr: lpm; + } + actions = { + ipv4_forward; + drop; + NoAction; + } + size = 1024; + default_action = NoAction(); + } + + apply { + if (hdr.ipv4.isValid()) { + if (hdr.ipv4.protocol == IP_PROTOCOLS_UDP) { + expedited_forwarding(); + } + else if (hdr.ipv4.protocol == IP_PROTOCOLS_TCP) { + voice_admit(); + } + 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.ecn, + 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/exercises/qos/topology.json b/exercises/qos/topology.json new file mode 100644 index 0000000..6d4be03 --- /dev/null +++ b/exercises/qos/topology.json @@ -0,0 +1,28 @@ +{ + "hosts": { + "h1": {"ip": "10.0.1.1/31", "mac": "08:00:00:00:01:01", + "commands":["route add default gw 10.0.1.0 dev eth0", + "arp -i eth0 -s 10.0.1.0 08:00:00:00:01:00"]}, + "h11": {"ip": "10.0.1.11/31", "mac": "08:00:00:00:01:11", + "commands":["route add default gw 10.0.1.10 dev eth0", + "arp -i eth0 -s 10.0.1.10 08:00:00:00:01:00"]}, + "h2": {"ip": "10.0.2.2/31", "mac": "08:00:00:00:02:02", + "commands":["route add default gw 10.0.2.3 dev eth0", + "arp -i eth0 -s 10.0.2.3 08:00:00:00:02:00"]}, + "h22": {"ip": "10.0.2.22/31", "mac": "08:00:00:00:02:22", + "commands":["route add default gw 10.0.2.23 dev eth0", + "arp -i eth0 -s 10.0.2.23 08:00:00:00:02:00"]}, + "h3": {"ip": "10.0.3.3/31", "mac": "08:00:00:00:03:03", + "commands":["route add default gw 10.0.3.2 dev eth0", + "arp -i eth0 -s 10.0.3.2 08:00:00:00:03:00"]} + }, + "switches": { + "s1": { "runtime_json" : "s1-runtime.json" }, + "s2": { "runtime_json" : "s2-runtime.json" }, + "s3": { "runtime_json" : "s3-runtime.json" } + }, + "links": [ + ["h1", "s1-p2"], ["h11", "s1-p1"], ["s1-p3", "s2-p3"], ["s1-p4", "s3-p2"], + ["s3-p3", "s2-p4"], ["h2", "s2-p2"], ["h22", "s2-p1"], ["h3", "s3-p1"] + ] +}