[ONOS-7154] Add DSCP bit support as an INT header indicator

Change-Id: I2e80dd64b8c73808e96bba7470c1c331b562c45e
diff --git a/pipelines/basic/src/main/resources/include/headers.p4 b/pipelines/basic/src/main/resources/include/headers.p4
index d8478a6..e45c915 100644
--- a/pipelines/basic/src/main/resources/include/headers.p4
+++ b/pipelines/basic/src/main/resources/include/headers.p4
@@ -38,7 +38,8 @@
 header ipv4_t {
     bit<4>  version;
     bit<4>  ihl;
-    bit<8>  diffserv;
+    bit<6>  dscp;
+    bit<2>  ecn;
     bit<16> len;
     bit<16> identification;
     bit<3>  flags;
diff --git a/pipelines/basic/src/main/resources/include/int_defines.p4 b/pipelines/basic/src/main/resources/include/int_definitions.p4
similarity index 92%
rename from pipelines/basic/src/main/resources/include/int_defines.p4
rename to pipelines/basic/src/main/resources/include/int_definitions.p4
index 30f0ce6..18125f2 100644
--- a/pipelines/basic/src/main/resources/include/int_defines.p4
+++ b/pipelines/basic/src/main/resources/include/int_definitions.p4
@@ -20,7 +20,8 @@
 
 #include "defines.p4"
 
-const next_hop_id_t INT_PORT = 54321;
+/* indicate INT at LSB of DSCP */
+const bit<6> INT_DSCP = 0x1;
 
 typedef bit<48> timestamp_t;
 typedef bit<32> switch_id_t;
diff --git a/pipelines/basic/src/main/resources/include/int_headers.p4 b/pipelines/basic/src/main/resources/include/int_headers.p4
index 8d8850f..d55c571 100644
--- a/pipelines/basic/src/main/resources/include/int_headers.p4
+++ b/pipelines/basic/src/main/resources/include/int_headers.p4
@@ -84,12 +84,11 @@
     bit<8> dscp;
 }
 
-header int_metadata_t {
+struct int_metadata_t {
     switch_id_t switch_id;
     bit<16> insert_byte_cnt;
     bit<1>  source;
     bit<1>  sink;
-    bit<16> origin_port;
     bit<8>  mirror_id;
     bit<16> flow_id;
     bit<8>  metadata_len;
diff --git a/pipelines/basic/src/main/resources/include/int_parser.p4 b/pipelines/basic/src/main/resources/include/int_parser.p4
index 63c29fb..b178ea4 100644
--- a/pipelines/basic/src/main/resources/include/int_parser.p4
+++ b/pipelines/basic/src/main/resources/include/int_parser.p4
@@ -15,8 +15,8 @@
  */
 
 /* -*- P4_16 -*- */
-#ifndef __PARSER__
-#define __PARSER__
+#ifndef __INT_PARSER__
+#define __INT_PARSER__
 
 parser int_parser (
     packet_in packet,
@@ -54,15 +54,20 @@
 
     state parse_tcp {
         packet.extract(hdr.tcp);
-        transition accept;
+        local_metadata.l4_src_port = hdr.tcp.src_port;
+        local_metadata.l4_dst_port = hdr.tcp.dst_port;
+        transition select((hdr.ipv4.dscp & INT_DSCP) == INT_DSCP) {
+            true: parse_intl4_shim;
+            default: accept;
+        }
     }
 
     state parse_udp {
         packet.extract(hdr.udp);
         local_metadata.l4_src_port = hdr.udp.src_port;
         local_metadata.l4_dst_port = hdr.udp.dst_port;
-        transition select(hdr.udp.dst_port) {
-            INT_PORT: parse_intl4_shim;
+        transition select((hdr.ipv4.dscp & INT_DSCP) == INT_DSCP) {
+            true: parse_intl4_shim;
             default: accept;
         }
     }
diff --git a/pipelines/basic/src/main/resources/include/int_sink.p4 b/pipelines/basic/src/main/resources/include/int_sink.p4
index 29c85ef..f87339e 100644
--- a/pipelines/basic/src/main/resources/include/int_sink.p4
+++ b/pipelines/basic/src/main/resources/include/int_sink.p4
@@ -23,27 +23,34 @@
     inout headers_t hdr,
     inout local_metadata_t local_metadata,
     inout standard_metadata_t standard_metadata) {
+    action restore_header () {
+        hdr.udp.dst_port = hdr.intl4_tail.dest_port;
+        hdr.ipv4.dscp = (bit<6>)hdr.intl4_tail.dscp;
+    }
+
     action int_sink() {
         // restore length fields of IPv4 header and UDP header
         hdr.ipv4.len = hdr.ipv4.len - (bit<16>)((hdr.intl4_shim.len - (bit<8>)hdr.int_header.ins_cnt) << 2); 
         hdr.udp.length_ = hdr.udp.length_ - (bit<16>)((hdr.intl4_shim.len - (bit<8>)hdr.int_header.ins_cnt) << 2);
-        // restore original dst port
-        local_metadata.int_meta.origin_port = hdr.intl4_tail.dest_port;
         // remove all the INT information from the packet
         hdr.int_header.setInvalid();
         hdr.int_data.setInvalid();
         hdr.intl4_shim.setInvalid();
         hdr.intl4_tail.setInvalid();
-    }
-
-    action restore_port () {
-        hdr.udp.dst_port = local_metadata.int_meta.origin_port;
+        hdr.int_switch_id.setInvalid();
+        hdr.int_port_ids.setInvalid();
+        hdr.int_hop_latency.setInvalid();
+        hdr.int_q_occupancy.setInvalid();
+        hdr.int_ingress_tstamp.setInvalid();
+        hdr.int_egress_tstamp.setInvalid();
+        hdr.int_q_congestion.setInvalid();
+        hdr.int_egress_tx_util.setInvalid();
     }
 
     apply {
         if (local_metadata.int_meta.sink == 1) {
+            restore_header();
             int_sink();
-            restore_port();
         }
     }
 }
diff --git a/pipelines/basic/src/main/resources/include/int_source.p4 b/pipelines/basic/src/main/resources/include/int_source.p4
index a09309f..15a8b264 100644
--- a/pipelines/basic/src/main/resources/include/int_source.p4
+++ b/pipelines/basic/src/main/resources/include/int_source.p4
@@ -52,26 +52,26 @@
         hdr.intl4_tail.setValid();
         hdr.intl4_tail.next_proto = hdr.ipv4.protocol;
         hdr.intl4_tail.dest_port = local_metadata.l4_dst_port;
-        hdr.intl4_tail.dscp = 0; // not used
-
-        hdr.udp.dst_port = INT_PORT;
+        hdr.intl4_tail.dscp = (bit<8>) hdr.ipv4.dscp;
 
         // add the header len (8 bytes) to total len
         hdr.ipv4.len = hdr.ipv4.len + 16;
         hdr.udp.length_ = hdr.udp.length_ + 16;
     }
+    action int_source_dscp(bit<8> max_hop, bit<5> ins_cnt, bit<4> ins_mask0003, bit<4> ins_mask0407) {
+        int_source(max_hop, ins_cnt, ins_mask0003, ins_mask0407);
+        hdr.ipv4.dscp = INT_DSCP;
+    }
 
     table tb_int_source {
         key = {
-            local_metadata.int_meta.sink: exact;
-            local_metadata.int_meta.source: exact;
             hdr.ipv4.src_addr: ternary;
             hdr.ipv4.dst_addr: ternary;
             local_metadata.l4_src_port: ternary;
             local_metadata.l4_dst_port: ternary;
         }
         actions = {
-            int_source; // sink = 0 & source = 1
+            int_source_dscp;
         }
         counters = counter_int_source;
         size = 1024;
@@ -87,18 +87,17 @@
     inout local_metadata_t local_metadata,
     inout standard_metadata_t standard_metadata) {
 
-    direct_counter(CounterType.packets_and_bytes) counter_set_source;
-    direct_counter(CounterType.packets_and_bytes) counter_set_sink;
+    direct_counter(CounterType.packets_and_bytes) counter_set_source_sink;
 
     action int_set_source () {
-        local_metadata.int_meta.source =  1;
+        local_metadata.int_meta.source = 1;
     }
 
     action int_set_sink () {
         local_metadata.int_meta.sink = 1;
     }
 
-    table tb_set_source {
+    table tb_set_source_sink {
         key = {
             hdr.ipv4.src_addr: ternary;
             hdr.ipv4.dst_addr: ternary;
@@ -107,30 +106,14 @@
         }
         actions = {
             int_set_source;
-        }
-        counters = counter_set_source;
-        size = 1024;
-    }
-
-    table tb_set_sink {
-        key = {
-            hdr.ipv4.src_addr: ternary;
-            hdr.ipv4.dst_addr: ternary;
-            local_metadata.l4_src_port: ternary;
-            local_metadata.l4_dst_port: ternary;
-        }
-        actions = {
             int_set_sink;
         }
-        counters = counter_set_sink;
+        counters = counter_set_source_sink;
         size = 1024;
     }
 
     apply {
-        if (hdr.udp.isValid()) {
-            tb_set_source.apply();
-            tb_set_sink.apply();
-        }
+        tb_set_source_sink.apply();
     }
 }
 #endif
diff --git a/pipelines/basic/src/main/resources/include/int_transit.p4 b/pipelines/basic/src/main/resources/include/int_transit.p4
index 7f553c5..9c066bd0 100644
--- a/pipelines/basic/src/main/resources/include/int_transit.p4
+++ b/pipelines/basic/src/main/resources/include/int_transit.p4
@@ -307,6 +307,8 @@
     }
     action int_update_udp() {
         hdr.udp.length_ = hdr.udp.length_ + local_metadata.int_meta.insert_byte_cnt;
+    }
+    action int_update_shim() {
         hdr.intl4_shim.len = hdr.intl4_shim.len + (bit<8>)hdr.int_header.ins_cnt;
     }
 
@@ -314,10 +316,12 @@
         if (hdr.ipv4.isValid()) {
             int_update_ipv4();
         }
-
-        if (hdr.intl4_shim.isValid()) {
+        if (hdr.udp.isValid()) {
             int_update_udp();
         }
+        if (hdr.intl4_shim.isValid()) {
+            int_update_shim();
+        }
     }
 }