/* -*- P4_16 -*- */ #include #include /************************************************************************* ************* C O N S T A N T S A N D T Y P E S ******************* **************************************************************************/ /************************************************************************* *********************** 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 { bit<48> dst_addr; bit<48> src_addr; bit<16> ether_type; } header vlan_tag_h { bit<3> pcp; bit<1> cfi; bit<12> vid; bit<16> 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; bit<8> protocol; bit<16> hdr_checksum; bit<32> src_addr; bit<32> dst_addr; } header test_reg_h { bit<32> tna_reg_name; bit<8> op; bit<16> opcode; bit<24> reg; bit<8> reg_choice; bit<8> reg_index; bit<16> data; } /************************************************************************* ************** 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; test_reg_h reg; } /****** 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 { } /*********************** 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) { /* This is a mandatory state, required by Tofino Architecture */ state start { pkt.extract(ig_intr_md); pkt.advance(PORT_METADATA_SIZE); transition parse_ethernet; } state parse_ethernet { pkt.extract(hdr.ethernet); transition select(hdr.ethernet.ether_type) { 0x6666 : parse_reg; default: accept; } } state parse_reg { pkt.extract(hdr.reg); transition accept; } } /***************** M A T C H - A C T I O N *********************/ control Ingress( /* 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<8>>(256,0) reg_test1; RegisterAction, bit<8>, bit<16>>(reg_test1) reg1_insert = { void apply(inout bit<16> set_store){ set_store = hdr.reg.data; } }; RegisterAction, bit<8>, bit<16>>(reg_test1) reg1_read = { void apply(inout bit<16> value, out bit<16> ret){ ret = value; value = 0x0; } }; Register,bit<8>>(256,0) reg_test2; RegisterAction, bit<8>, bit<16>>(reg_test2) reg2_insert = { void apply(inout bit<16> set_store){ set_store = hdr.reg.data; } }; RegisterAction, bit<8>, bit<16>>(reg_test2) reg2_read = { void apply(inout bit<16> value, out bit<16> ret){ ret = value; value = 0x0; } }; apply { ig_tm_md.ucast_egress_port = ig_intr_md.ingress_port; if(hdr.reg.opcode == 1){ if(hdr.reg.reg_choice == 1){ reg1_insert.execute(hdr.reg.reg_index); } else if(hdr.reg.reg_choice == 2){ reg2_insert.execute(hdr.reg.reg_index); } else if(hdr.reg.reg_choice == 3){ reg1_insert.execute(hdr.reg.reg_index); reg2_insert.execute(hdr.reg.reg_index); } } else if(hdr.reg.opcode == 2){ if(hdr.reg.reg_choice == 1){ hdr.reg.data = reg1_read.execute(hdr.reg.reg_index); } else if(hdr.reg.reg_choice == 2){ hdr.reg.data = reg2_read.execute(hdr.reg.reg_index); } } } } /********************* 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) { apply { 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 Egress( /* 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(), Ingress(), IngressDeparser(), EgressParser(), Egress(), EgressDeparser() ) pipe; Switch(pipe) main;