Georgios Nikolaidis e7e6899d5c Added advanced Heavy Hitter Detection example (#136)
* Added advanced Heavy Hitter Detection example

* Changed directory location

* Restored skeleton version

* Added files for common run infra with the other tutorials

* Updated readme

* Autogenerate setup rules

* Commends in simple_router.p4

* Fix typos

* Removed commended out lines
2018-04-25 00:56:09 -07:00

211 lines
5.8 KiB
Plaintext

#include <core.p4>
#include <v1model.p4>
#include "header.p4"
#include "parser.p4"
const bit<16> MAX_ADDRESS = 0x1F;
const bit<16> THRESHOLD_COUNT = 8;
register<bit<48>>(32w1) last_reset_time;
register<bit<32>>(32w32) hashtable_a0;
register<bit<32>>(32w32) hashtable_a1;
register<bit<32>>(32w32) hashtable_a2;
register<bit<32>>(32w32) hashtable_a3;
register<bit<32>>(32w32) hashtable_b0;
register<bit<32>>(32w32) hashtable_b1;
register<bit<32>>(32w32) hashtable_b2;
register<bit<32>>(32w32) hashtable_b3;
register<bit<1>>(32w1) is_a_active;
control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
action rewrite_mac(bit<48> smac) {
hdr.ethernet.srcAddr = smac;
}
action egress_drop() {
mark_to_drop();
}
table send_frame {
actions = {
rewrite_mac;
egress_drop;
NoAction;
}
key = {
standard_metadata.egress_port: exact;
}
size = 256;
default_action = NoAction();
}
apply {
if (hdr.ipv4.isValid()) {
send_frame.apply();
}
}
}
control HashtableUpdate(in register<bit<32>> hashtable,
in HashAlgorithm algo,
in headers hdr,
inout bit<32> bytecount) {
action update_hashtable() {
/* TODO
Use a hashfunction and calculate the corresponding address
of the count-min sketch based on its five-tuple (hdr.ipv4.srcAddr,
hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort)
Read the previous contents of that address, add the packet length to
the previous bytecount, update the register address and keep a
copy of the value in the metadata.
*/
}
apply {
if (hdr.ipv4.isValid()) {
update_hashtable();
}
}
}
control HHD(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
HashtableUpdate() update_hashtable_a0;
HashtableUpdate() update_hashtable_a1;
HashtableUpdate() update_hashtable_a2;
HashtableUpdate() update_hashtable_a3;
HashtableUpdate() update_hashtable_b0;
HashtableUpdate() update_hashtable_b1;
HashtableUpdate() update_hashtable_b2;
HashtableUpdate() update_hashtable_b3;
action calculate_age() {
/* TODO
Read the last_reset_time register and calculate
how long has it been since last reset of sketch A based
on standard_metadata.ingress_global_timestamp.
Save the result in meta.hhd.filter_age.
*/
}
action set_threshold(bit<32> threshold) {
/* TODO
Copy the threshlod to metamhhd.threshold
*/
}
action set_filter() {
/* TODO
Check whether count-min sketch A is active
and set meta.hhd.is_a_active flag appropriately
*/
}
action heavy_hitter_drop() {
mark_to_drop();
}
action decide_heavy_hitter() {
/* TODO
Based on whether A is active and the appropriate
meta.hhd.value_xx values, decide, whether
the packet belongs to a heavy hitter flow or not
and set meta.hhd.is_heavy_hitter flag.
*/
}
table threshold_table {
key = {
meta.hhd.filter_age : ternary;
}
actions = {
set_threshold;
}
size = THRESHOLD_COUNT;
}
table drop_heavy_hitter {
key = {
meta.hhd.is_heavy_hitter : exact;
}
actions = {
heavy_hitter_drop;
NoAction;
}
size = 2;
default_action = NoAction();
}
apply {
calculate_age();
set_filter();
threshold_table.apply();
update_hashtable_a0.apply(hashtable_a0, HashAlgorithm.crc32, hdr, meta.hhd.value_a0);
update_hashtable_a1.apply(hashtable_a1, HashAlgorithm.crc32_custom, hdr, meta.hhd.value_a1);
update_hashtable_a2.apply(hashtable_a2, HashAlgorithm.crc16, hdr, meta.hhd.value_a2);
update_hashtable_a3.apply(hashtable_a3, HashAlgorithm.crc16_custom, hdr, meta.hhd.value_a3);
update_hashtable_b0.apply(hashtable_b0, HashAlgorithm.crc32, hdr, meta.hhd.value_b0);
update_hashtable_b1.apply(hashtable_b1, HashAlgorithm.crc32_custom, hdr, meta.hhd.value_b1);
update_hashtable_b2.apply(hashtable_b2, HashAlgorithm.crc16, hdr, meta.hhd.value_b2);
update_hashtable_b3.apply(hashtable_b3, HashAlgorithm.crc16_custom, hdr, meta.hhd.value_b3);
decide_heavy_hitter();
drop_heavy_hitter.apply();
}
}
control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
action ingress_drop() {
mark_to_drop();
}
action set_nhop(bit<32> nhop_ipv4, bit<9> port) {
meta.ingress_metadata.nhop_ipv4 = nhop_ipv4;
standard_metadata.egress_spec = port;
hdr.ipv4.ttl = hdr.ipv4.ttl + 8w255;
}
action set_dmac(bit<48> dmac) {
hdr.ethernet.dstAddr = dmac;
}
table ipv4_lpm {
actions = {
ingress_drop;
set_nhop;
NoAction;
}
key = {
hdr.ipv4.dstAddr: lpm;
}
size = 1024;
default_action = NoAction();
}
table forward {
actions = {
set_dmac;
ingress_drop;
NoAction;
}
key = {
meta.ingress_metadata.nhop_ipv4: exact;
}
size = 512;
default_action = NoAction();
}
HHD() hhd;
apply {
if (hdr.ipv4.isValid()) {
ipv4_lpm.apply();
forward.apply();
hhd.apply(hdr, meta, standard_metadata);
}
}
}
V1Switch(ParserImpl(), verifyChecksum(), ingress(), egress(), computeChecksum(), DeparserImpl()) main;