TNSM_Latency_Prediction / code / descarter / switch_based_counter / switch.p4
switch.p4
Raw
/* -*- P4_16 -*- */

#include <core.p4>
#include <tna.p4>

/*************************************************************************
 ************* C O N S T A N T S    A N D   T Y P E S  *******************
**************************************************************************/
const bit<16> ETHERTYPE_TPID = 0x8100;
const bit<16> ETHERTYPE_IPV4 = 0x0800;
const bit<16> ETHERTYPE_TEST = 0xABCD;
const bit<8> PROTOCOL_UDP = 0x11;



const bit<48> ENCAP_MAC_SRC = 0xac1f6b62b9fe;
const bit<48> ENCAP_MAC_DST = 0xac1f6b62b967;
const bit<32> ENCAP_IP_SRC = 0x0A620BFE;
const bit<32> ENCAP_IP_DST = 0x0A620B04;
const bit<16> ENCAP_UDP_DST = 0xD431; //54321


/* Table Sizes */
const int IPV4_HOST_SIZE = 65536;
const int IPV4_LPM_SIZE  = 12288;

typedef bit<11> latencyValue_t; 

/*************************************************************************
 ***********************  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>   dstAddr;
    bit<48>   srcAddr;
    bit<16>   etherType;
}

header ipv4_h {
    bit<4>    version;
    bit<4>    ihl;
    bit<6>    dscp;
    bit<2>    ecn;
    bit<16>   totalLen;
    bit<16>   identification;
    bit<3>    flags;
    bit<13>   fragOffset;
    bit<8>    ttl;
    bit<8>    protocol;
    bit<16>   hdrChecksum;
    bit<32>   srcAddr;
    bit<32>   dstAddr;
}//20 bytes

header udp_h {
    bit<16> srcPort;
    bit<16> dstPort;
    bit<16> _length;
    bit<16> checksum;
}

/* Timestamping headers */

header timestamp_ts6_h {
    bit<48> value;
    bit<16> decimal;
}

header timestamps_ingress_h {
    bit<48> ts2;
    bit<48> ts1;
}

header timestamps_egress_h {
    bit<48> ts5;
    bit<24> ts4;
    bit<24> ts3;
}

/*************************************************************************
 **************  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;
    timestamp_ts6_h       ts6;
    timestamps_egress_h   ts_egress;
    timestamps_ingress_h  ts_ingress;
}

    /******  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.etherType) {
            ETHERTYPE_TEST: parse_ts;
            default: accept;
        }
    }

    state parse_ts {
        pkt.extract(hdr.ts6);
        pkt.extract(hdr.ts_egress);
        pkt.extract(hdr.ts_ingress);
        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)
{

    Counter<bit<32>, latencyValue_t>(2048, CounterType_t.PACKETS) ingLatencyCounter;
    Counter<bit<32>, latencyValue_t>(2048, CounterType_t.PACKETS) egrLatencyCounter;
    Counter<bit<32>, latencyValue_t>(2048, CounterType_t.PACKETS) e2eLatencyCounter;

    //bit<10> maxNum = 0;

    bit<11> ingLat1 = 0;
    bit<11> ingLat2 = 0;
    bit<11> ingLatFin = 0;
    bit<11> egressLatency = 0;
    bit<11> e2eLatency = 0;


    action drop_pkt() {
        ig_dprsr_md.drop_ctl = 1;
    }    

    action normal_ing_lat(bit<18> ts2, bit<18> ts3){
        ingLatFin = (bit<11>) (ts3 - ts2);
    }

    action surpass_ing_lat(bit<18> ts2, bit<18> ts3){
        hdr.ts_ingress.ts2 = hdr.ts_ingress.ts2 +1;
        ingLat1 = (bit<11>) (0x3ffff - ts2);
        ingLatFin = ingLat1 + (bit<11>)ts3;
    }

    action calc_eg_lat(){
        egressLatency = (bit<11>) (hdr.ts6.value - hdr.ts_egress.ts5);
    }

    action calc_e2e_lat(){
        e2eLatency = (bit<11>) (hdr.ts6.value - hdr.ts_ingress.ts1);
    }

    apply {
        
        bit<18> ts2_cropped = (bit<18>)hdr.ts_ingress.ts2;
        bit<18> ts3_cropped = (bit<18>)hdr.ts_egress.ts3;

        bit<18> diff = ts3_cropped - ts2_cropped;
        if(diff > 0){
            ingLatFin = (bit<11>)diff;

        }else{
            surpass_ing_lat(ts2_cropped, ts3_cropped);

        }

        calc_eg_lat();
        calc_e2e_lat();

        ingLatencyCounter.count(ingLatFin);
        egrLatencyCounter.count(egressLatency);
        //e2eLatencyCounter.count(e2eLatency);

        drop_pkt();

    }    

}


/*********************  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 {
    ethernet_h   outer_ethernet;
    ipv4_h       outer_ipv4;
    udp_h        outer_udp;
    ethernet_h   ethernet;
    ipv4_h       ipv4;
    udp_h        udp;
}

    /********  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;