TNSM_Latency_Prediction / code / parser / example / ingress.p4
ingress.p4
Raw
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)
{
    bool int_added = false;

    action int_set_header_0() { // 32 bits
        hdr.int_switch_id.setValid();
        hdr.int_switch_id.switch_id = (bit<32>)hdr.common_metadata.switch_id;
    }

    action int_set_header_1() { // 32 bits
        hdr.int_timestamp_ig.setValid();
        hdr.int_timestamp_ig.igs = hdr.common_metadata.ts1;
    }

    action int_set_header_0003_i3() {
        int_set_header_0();
        int_set_header_1();
        // 4 bytes for switch_id and 8 bytes for ingress ts

        hdr.int_shim.len = hdr.int_shim.len +
            METADATA_8_BYTE_AS_WORDS;

        hdr.ipv4.totalLen = hdr.ipv4.totalLen +
            METADATA_4_BYTES; //we add ing tstamp size later

        hdr.udp.len = hdr.udp.len +
            METADATA_4_BYTES;

        hdr.common_metadata.added_int_metadata =
            hdr.common_metadata.added_int_metadata +
            METADATA_8_BYTE_AS_WORDS;
    }

    table add_telemetry_t {
        key = {
            hdr.int_meta.instruction_mask_0003 : exact;
        }
        actions = {
            int_set_header_0003_i3;
            NoAction;
        }
        default_action = NoAction();
        size = 2;
        const entries = {
            3 : int_set_header_0003_i3();
        }
    }

    action add_int_shim(){
        hdr.int_shim.setValid();

        hdr.int_shim._type = 1;
        // npt=0 ->, npt=1 -> orignal UDP port, npt=2 ->IP proto
        hdr.int_shim.npt = 0;
        hdr.int_shim.res1 = 0;
        hdr.int_shim.res2 = 0;
        hdr.int_shim.len = 0;

        hdr.int_shim.npt_field[15:8] = 0;
        hdr.int_shim.npt_field[7:2] = hdr.ipv4.dscp;
        hdr.int_shim.npt_field[1:0] = 0;
        //hdr.int_shim.npt_field = 0;
        hdr.ipv4.dscp = DSCP_INT;
    }

    action add_int_meta(){
        hdr.int_meta.setValid();

        hdr.int_meta.ver = 2;
        hdr.int_meta.d = 0;
        hdr.int_meta.e = 0;
        hdr.int_meta.m = 0;
        hdr.int_meta.rsvd1 = 0;
        hdr.int_meta.hop_metadata_len = 8;
        hdr.int_meta.remaining_hop_cnt = 64;
        hdr.int_meta.instruction_mask_0003 = 3;
        hdr.int_meta.instruction_mask_0407 = 0;
        hdr.int_meta.instruction_mask_0811 = 0;
        hdr.int_meta.instruction_mask_1215 = 0;
        hdr.int_meta.domain_sp_id = 0;
        hdr.int_meta.ds_inst = 0;
        hdr.int_meta.ds_flags = 0;

        //Added 2 words for metadata length
        hdr.int_shim.len = INT_META_HEADER_LEN_WORDS;
    }

    action add_int_headers() {
        add_int_shim();
        add_int_meta();
        int_added = true;
    }

    action add_mpls_header(mpls_label_t label) {
        hdr.mpls.setValid();
        hdr.mpls.label_id = label;
        hdr.mpls.exp = 0;
        hdr.mpls.bos = 1;
        hdr.mpls.ttl = 64;

        hdr.ethernet.etherType = ETHERTYPE_MPLS;
    }

    action exchange_mpls_label(mpls_label_t label) {
        hdr.mpls.label_id = label;
    }

    action remove_mpls_header() {
        hdr.mpls.setInvalid();
        hdr.ethernet.etherType = ETHERTYPE_IPV4;
    }

    action send_to(egressSpec_t port) {
        ig_tm_md.ucast_egress_port = port;
        hdr.common_metadata.output_port = port;
    }

    table mpls_add_t {
        key = {
            hdr.common_metadata.switch_id   : exact;
            hdr.ipv4.srcAddr                : exact;
        }
        actions = {
            add_mpls_header;
            NoAction;
        }
        default_action = NoAction;
        size           = 10;
    }

    table mpls_rm_t {
        key = {
            hdr.common_metadata.switch_id   : exact;
            hdr.ipv4.dstAddr                : exact;
        }
        actions = {
            remove_mpls_header;
            NoAction;
        }
        default_action = NoAction;
        size           = 10;
    }

    table mpls_exc_t {
        key = {
            hdr.mpls.label_id : exact;
        }
        actions = {
            exchange_mpls_label;
            NoAction;
        }
        default_action = NoAction;
        size           = 100;
    }

    table mpls_fwd_t {
        key = {
            hdr.mpls.label_id : exact;
        }
        actions = {
            send_to;
            NoAction;
        }
        default_action = NoAction;
        size           = 100;
    }

    table mpls_telemetry_t {
        key = {
            hdr.mpls.label_id : exact;
        }
        actions = {
            add_int_headers;
            NoAction;
        }
        default_action = NoAction;
        size           = 10;
    }

    table ipv4_fwd_t {
        key = {
            hdr.ipv4.dstAddr : lpm;
        }
        actions = {
            send_to;
            NoAction;
        }
        default_action = NoAction;
        size           = 10;
    }

    action get_switch_id(switch_id_t s_id){
        hdr.common_metadata.switch_id = (bit<8>)s_id;
    }

    table process_switch_id {
        key = {
            ig_intr_md.ingress_port : exact;
        }
        actions = {
            get_switch_id;
            NoAction;
        }
        default_action = NoAction;
        size           = 64;
    }

    table ldp_tcp_t {
        key = {
              hdr.ipv4.dstAddr : exact;
        }
        actions = {
            send_to;
            NoAction();
        }
        default_action = NoAction();
        size           = 10;
    }

    table ldp_udp_t {
        key = {
              ig_intr_md.ingress_port : exact;
              hdr.udp.dstPort         : exact;
        }
        actions = {
            send_to;
            NoAction();
        }
        default_action = NoAction();
        size           = 10;
    }

    table arp_t {
        key = {
              ig_intr_md.ingress_port : exact;
              hdr.ethernet.etherType : exact;
        }
        actions = {
            send_to;
            NoAction;
        }
        default_action = NoAction();
        size           = 10;
    }


    apply{

        if(arp_t.apply().hit){
            return;
        }

        if(hdr.udp.isValid()){
            if(ldp_udp_t.apply().hit){
                return;
            }
        }

        if(hdr.tcp.isValid()){
            if(ldp_tcp_t.apply().hit){
                return;
            }
        }

        hdr.common_metadata.setValid();
        hdr.common_metadata._pad = 0;
        hdr.common_metadata.added_int_metadata = 0;
        hdr.common_metadata.ts1 = (bit<32>)ig_intr_md.ingress_mac_tstamp;

        if (hdr.ipv4.isValid()) {
            process_switch_id.apply();

            mpls_add_t.apply();

            if(hdr.mpls.isValid()){

                //Is it time to remove MPLS?
                if(!mpls_rm_t.apply().hit){
                    // Exchange label if label is still there
                    mpls_exc_t.apply();
                };

                //Shall we add telemetry to this packet?
                mpls_telemetry_t.apply();
            }


            if(hdr.mpls.isValid()){
                //If MPLS still valid then fwd based on it
                mpls_fwd_t.apply();
            }else{
                //Else we are likely stripping MPLS and fwd based on IP
                //or just fwd based on IP
                ipv4_fwd_t.apply();
            }


            if(hdr.int_shim.isValid() && hdr.int_meta.isValid()){

                if(int_added){
                    hdr.ipv4.totalLen = hdr.ipv4.totalLen +
                        INT_SHIM_HEADER_LEN_BYTES;
                    hdr.ipv4.totalLen = hdr.ipv4.totalLen +
                        INT_META_HEADER_LEN_BYTES;
                    hdr.udp.len = hdr.udp.len +
                        INT_SHIM_HEADER_LEN_BYTES;
                    hdr.udp.len = hdr.udp.len    +
                        INT_META_HEADER_LEN_BYTES;
                }

                add_telemetry_t.apply();
            }

        }

    }

}