#include #include #include "header.p4" #include "parser.p4" const bit<16> MAX_ADDRESS = 0x1F; const bit<16> THRESHOLD_COUNT = 8; register>(32w1) last_reset_time; register>(32w32) hashtable_a0; register>(32w32) hashtable_a1; register>(32w32) hashtable_a2; register>(32w32) hashtable_a3; register>(32w32) hashtable_b0; register>(32w32) hashtable_b1; register>(32w32) hashtable_b2; register>(32w32) hashtable_b3; register>(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> 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;