/* -*- P4_16 -*- */ #include #include /************************************************************************* ************* C O N S T A N T S A N D T Y P E S ******************* *************************************************************************/ /* Header Stuff */ enum bit<16> ether_type_t { TPID = 0x8100, IPV4 = 0x0800, ARP = 0x0806, IPV6 = 0x86DD, MPLS = 0x8847 } enum bit<8> ip_protocol_t { ICMP = 1, IGMP = 2, TCP = 6, UDP = 17 } typedef bit<48> mac_addr_t; typedef bit<32> ipv4_addr_t; /* Metadata and Table Stuff */ const int IPV4_HOST_SIZE = 65536; const int IPV4_LPM_SIZE = 12288; #define BLOOM_FILTER_ENTRIES 4096 #define BLOOM_FILTER_BIT_WIDTH 1 /************************************************************************* *********************** H E A D E R S ********************************* *************************************************************************/ /* Define all the headers the program will recognize */ /* The actual sets of headers processed by each gress can differ */ /* Standard ethernet header */ header ethernet_h { mac_addr_t dst_addr; mac_addr_t src_addr; ether_type_t ether_type; } header vlan_tag_h { bit<3> pcp; bit<1> cfi; bit<12> vid; ether_type_t ether_type; } header ipv4_h { bit<4> version; bit<4> ihl; bit<8> diffserv; bit<16> total_len; bit<16> identification; bit<3> flags; bit<13> frag_offset; bit<8> ttl; ip_protocol_t protocol; bit<16> hdr_checksum; ipv4_addr_t src_addr; ipv4_addr_t dst_addr; } header ipv4_options_h { varbit<320> data; } header tcp_h { bit<16> sPort; bit<16> dPort; bit<32> seqNo; bit<32> ackNo; bit<4> dataOffset; bit<4> res; bit<1> cwr; bit<1> ece; bit<1> urg; bit<1> ack; bit<1> psh; bit<1> rst; bit<1> syn; bit<1> fin; bit<16> window; bit<16> checksum; bit<16> urgentPtr; } /************************************************************************* ************** I N G R E S S P R O C E S S I N G ******************* *************************************************************************/ /*********************** H E A D E R S ************************/ struct my_ingress_headers_t { ethernet_h ethernet; vlan_tag_h[2] vlan_tag; ipv4_h ipv4; tcp_h tcp; } /****** G L O B A L I N G R E S S M E T A D A T A *********/ struct my_ingress_metadata_t { ipv4_addr_t dst_ipv4; mac_addr_t dst_mac; bit<1> ipv4_csum_err; bit<1> bf_tmp; } /*********************** P A R S E R **************************/ parser IngressParser(packet_in pkt, /* User */ out my_ingress_headers_t hdr, out my_ingress_metadata_t meta, /* Intrinsic */ out ingress_intrinsic_metadata_t ig_intr_md) { Checksum() ipv4_checksum; /* This is a mandatory state, required by Tofino Architecture */ state start { pkt.extract(ig_intr_md); pkt.advance(PORT_METADATA_SIZE); transition meta_init; } state meta_init { meta.ipv4_csum_err = 0; meta.dst_ipv4 = 0; meta.dst_mac = 0; meta.bf_tmp = 0; transition parse_ethernet; } state parse_ethernet { pkt.extract(hdr.ethernet); transition select(hdr.ethernet.ether_type) { ether_type_t.TPID : parse_vlan_tag; ether_type_t.IPV4 : parse_ipv4; default: accept; } } state parse_vlan_tag { pkt.extract(hdr.vlan_tag.next); transition select(hdr.vlan_tag.last.ether_type) { ether_type_t.TPID : parse_vlan_tag; ether_type_t.IPV4 : parse_ipv4; default: accept; } } state parse_ipv4 { pkt.extract(hdr.ipv4); meta.dst_ipv4 = hdr.ipv4.dst_addr; ipv4_checksum.add(hdr.ipv4); meta.ipv4_csum_err = (bit<1>)ipv4_checksum.verify(); transition select( hdr.ipv4.ihl, hdr.ipv4.frag_offset, hdr.ipv4.protocol) { (5, 0, ip_protocol_t.TCP) : parse_tcp; default: accept; } } state parse_tcp { pkt.extract(hdr.tcp); transition accept; } } /***************** M A T C H - A C T I O N *********************/ control MyIngress( /* User */ inout my_ingress_headers_t hdr, inout my_ingress_metadata_t meta, /* Intrinsic */ in ingress_intrinsic_metadata_t ig_intr_md, in ingress_intrinsic_metadata_from_parser_t ig_prsr_md, inout ingress_intrinsic_metadata_for_deparser_t ig_dprsr_md, inout ingress_intrinsic_metadata_for_tm_t ig_tm_md) { Register, bit<32>>(32w262144) bloom_filter_1; Register, bit<32>>(32w262144) bloom_filter_2; Register, bit<32>>(32w262144) bloom_filter_3; Hash>(HashAlgorithm_t.RANDOM) hash_1; Hash>(HashAlgorithm_t.RANDOM) hash_2; Hash>(HashAlgorithm_t.RANDOM) hash_3; RegisterAction, bit<32>, bit<1>>(bloom_filter_1) insert_bloom_filter_1 = { void apply(inout bit<1> value, out bit<1> rv) { value = 1w1; } }; RegisterAction, bit<32>, bit<1>>(bloom_filter_1) get_bloom_filter_1 = { void apply(inout bit<1> value, out bit<1> rv) { rv = value; } }; RegisterAction, bit<32>, bit<1>>(bloom_filter_2) insert_bloom_filter_2 = { void apply(inout bit<1> value, out bit<1> rv) { value = 1w1; } }; RegisterAction, bit<32>, bit<1>>(bloom_filter_2) get_bloom_filter_2 = { void apply(inout bit<1> value, out bit<1> rv) { rv = value; } }; RegisterAction, bit<32>, bit<1>>(bloom_filter_3) insert_bloom_filter_3 = { void apply(inout bit<1> value, out bit<1> rv) { value = 1w1; } }; RegisterAction, bit<32>, bit<1>>(bloom_filter_3) get_bloom_filter_3 = { void apply(inout bit<1> value, out bit<1> rv) { rv = value; } }; action send(PortId_t port) { ig_tm_md.ucast_egress_port = port; } action drop() { ig_dprsr_md.drop_ctl = 1; } table ipv4_host { key = { hdr.ipv4.dst_addr : exact; } actions = { send; drop; } default_action = send(64); size = 512; } bit<1> res_1 = 0; bit<1> res_2 = 0; bit<1> res_3 = 0; bit<1> res = 0; apply{ bit<32> test_hash_1 = (bit<32>)(hash_1.get({hdr.ipv4.protocol, hdr.ipv4.src_addr, hdr.ipv4.dst_addr, hdr.ipv4.dst_addr, hdr.tcp.dPort})[17:0]); bit<32> test_hash_2 = (bit<32>)(hash_2.get({hdr.ipv4.protocol, hdr.ipv4.src_addr, hdr.ipv4.dst_addr, hdr.ipv4.dst_addr, hdr.tcp.dPort})[17:0]); bit<32> test_hash_3 = (bit<32>)(hash_3.get({hdr.ipv4.protocol, hdr.ipv4.src_addr, hdr.ipv4.dst_addr, hdr.ipv4.dst_addr, hdr.tcp.dPort})[17:0]); if(hdr.tcp.syn == 1){ insert_bloom_filter_1.execute(test_hash_1); insert_bloom_filter_2.execute(test_hash_2); insert_bloom_filter_3.execute(test_hash_3); res = 1; } else{ res_1 = get_bloom_filter_1.execute(test_hash_1); res_2 = get_bloom_filter_2.execute(test_hash_2); res_3 = get_bloom_filter_3.execute(test_hash_3); if((res_1==1)&&(res_2==1)&&(res_3==1)){ res = 1; } } if(res == 1){ ipv4_host.apply(); } } } /********************* D E P A R S E R ************************/ control IngressDeparser(packet_out pkt, /* User */ inout my_ingress_headers_t hdr, in my_ingress_metadata_t meta, /* Intrinsic */ in ingress_intrinsic_metadata_for_deparser_t ig_dprsr_md) { Checksum() ipv4_checksum; apply { hdr.ipv4.hdr_checksum = ipv4_checksum.update({ hdr.ipv4.version, hdr.ipv4.ihl, hdr.ipv4.diffserv, hdr.ipv4.total_len, hdr.ipv4.identification, hdr.ipv4.flags, hdr.ipv4.frag_offset, hdr.ipv4.ttl, hdr.ipv4.protocol, hdr.ipv4.src_addr, hdr.ipv4.dst_addr /* Adding hdr.ipv4_options.data results in an error */ }); pkt.emit(hdr); } } /************************************************************************* **************** E G R E S S P R O C E S S I N G ******************* *************************************************************************/ /*********************** H E A D E R S ************************/ struct my_egress_headers_t { } /******** G L O B A L E G R E S S M E T A D A T A *********/ struct my_egress_metadata_t { } /*********************** P A R S E R **************************/ parser EgressParser(packet_in pkt, /* User */ out my_egress_headers_t hdr, out my_egress_metadata_t meta, /* Intrinsic */ out egress_intrinsic_metadata_t eg_intr_md) { /* This is a mandatory state, required by Tofino Architecture */ state start { pkt.extract(eg_intr_md); transition accept; } } /***************** M A T C H - A C T I O N *********************/ control MyEgress( /* User */ inout my_egress_headers_t hdr, inout my_egress_metadata_t meta, /* Intrinsic */ in egress_intrinsic_metadata_t eg_intr_md, in egress_intrinsic_metadata_from_parser_t eg_prsr_md, inout egress_intrinsic_metadata_for_deparser_t eg_dprsr_md, inout egress_intrinsic_metadata_for_output_port_t eg_oport_md) { apply { } } /********************* D E P A R S E R ************************/ control EgressDeparser(packet_out pkt, /* User */ inout my_egress_headers_t hdr, in my_egress_metadata_t meta, /* Intrinsic */ in egress_intrinsic_metadata_for_deparser_t eg_dprsr_md) { apply { pkt.emit(hdr); } } /************ F I N A L P A C K A G E ******************************/ Pipeline( IngressParser(), MyIngress(), IngressDeparser(), EgressParser(), MyEgress(), EgressDeparser() ) pipe; Switch(pipe) main;