/* -*- 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; // 192.168.11.254
const bit<32> ENCAP_IP_DST = 0x0A620B04; // 192.168.11.4
const bit<16> ENCAP_UDP_DST = 0xD431; //54321
/* Table Sizes */
const int IPV4_HOST_SIZE = 65536;
const int IPV4_LPM_SIZE = 12288;
/*************************************************************************
*********************** 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 timestamps_ingress_h {
bit<48> ts2;
bit<48> ts1;
}
header timestamps_egress_h {
bit<48> ts5;
bit<24> ts4;
bit<24> ts3;
}
header timestamp_ts6_h {
bit<48> value;
bit<16> decimal;
}
/*************************************************************************
************** 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 parse_ts;
}
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)
{
Random<bit<10>>() randomNum;
action drop_pkt() {
ig_dprsr_md.drop_ctl = 1;
}
/*action setBoundaries(bit<10> b) {
maxNum = b;
}
table setUpSampling_t {
key = {
}
actions = {
setBoundaries;
}
default_action = setBoundaries(102);
size = 1;
}*/
apply {
if(hdr.ethernet.etherType != 0xabcd){
drop_pkt();
}else{
bit<10> num = randomNum.get();
#ifdef PERCENT_10
// When sending 100 million packets
// 0-1023, 1024/10=102.4, 0 to 101.4, choosing 102, just over 10%
if (num <= 102){
#elif PERCENT_1
// When sending billion packets
// 0-1023, 1024/10=10.24, 0 to 9.24, choosing 10, just over 1%
if (num <= 10){
#endif
ig_tm_md.ucast_egress_port = (bit<9>)2;
}else{
drop_pkt();
}
}
//setUpSampling_t.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)
{
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;
timestamp_ts6_h ts6;
timestamps_egress_h ts_egress;
timestamps_ingress_h ts_ingress;
ethernet_h ethernet;
}
/******** 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 parse_ethernet;
}
state parse_ethernet {
pkt.extract(hdr.ethernet);
transition parse_ts;
}
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 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)
{
Random<bit<16>>() randomPort;
action encap(){
hdr.outer_ethernet.setValid();
hdr.outer_ethernet.srcAddr = ENCAP_MAC_SRC;
hdr.outer_ethernet.dstAddr = ENCAP_MAC_DST;
hdr.outer_ethernet.etherType = ETHERTYPE_IPV4;
hdr.outer_ipv4.setValid();
hdr.outer_ipv4.version = 4;
hdr.outer_ipv4.ihl = 5;
hdr.outer_ipv4.dscp = 0;
hdr.outer_ipv4.ecn = 0;
hdr.outer_ipv4.totalLen = eg_intr_md.pkt_length + 24;
hdr.outer_ipv4.identification = 0xabcd;
hdr.outer_ipv4.flags = 4;
hdr.outer_ipv4.fragOffset = 0;
hdr.outer_ipv4.ttl = 31;
hdr.outer_ipv4.hdrChecksum = 0;
hdr.outer_ipv4.protocol = PROTOCOL_UDP;
hdr.outer_ipv4.srcAddr = ENCAP_IP_SRC;
hdr.outer_ipv4.dstAddr = ENCAP_IP_DST;
hdr.outer_udp.setValid();
hdr.outer_udp.srcPort = 0;
hdr.outer_udp.dstPort = ENCAP_UDP_DST;
hdr.outer_udp._length = eg_intr_md.pkt_length + 4;
hdr.outer_udp.checksum = 0;
}
table encapsulate_t {
key = {
}
actions = {
encap;
NoAction;
}
default_action = encap;
size = 1;
}
apply {
encapsulate_t.apply();
bit<16> port = randomPort.get();
hdr.outer_udp.srcPort = port;
}
}
/********************* 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)
{
Checksum() ipv4_checksum;
apply {
hdr.outer_ipv4.hdrChecksum = ipv4_checksum.update({
hdr.outer_ipv4.version,
hdr.outer_ipv4.ihl,
hdr.outer_ipv4.dscp,
hdr.outer_ipv4.ecn,
hdr.outer_ipv4.totalLen,
hdr.outer_ipv4.identification,
hdr.outer_ipv4.flags,
hdr.outer_ipv4.fragOffset,
hdr.outer_ipv4.ttl,
hdr.outer_ipv4.protocol,
hdr.outer_ipv4.srcAddr,
hdr.outer_ipv4.dstAddr
});
pkt.emit(hdr.outer_ethernet);
pkt.emit(hdr.outer_ipv4);
pkt.emit(hdr.outer_udp);
pkt.emit(hdr.ts6);
pkt.emit(hdr.ts_egress);
pkt.emit(hdr.ts_ingress);
pkt.emit(hdr.ethernet);
}
}
/************ F I N A L P A C K A G E ******************************/
Pipeline(
IngressParser(),
Ingress(),
IngressDeparser(),
EgressParser(),
Egress(),
EgressDeparser()
) pipe;
Switch(pipe) main;