[ONOS-7154] Initial INT pipeline implementation

Change-Id: I85829350349c77abfcb14445de290be599573fea
diff --git a/pipelines/basic/src/main/resources/include/custom_headers.p4 b/pipelines/basic/src/main/resources/include/custom_headers.p4
new file mode 100644
index 0000000..035e322
--- /dev/null
+++ b/pipelines/basic/src/main/resources/include/custom_headers.p4
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CUSTOM_HEADERS__
+#define __CUSTOM_HEADERS__
+struct headers_t {
+    packet_out_header_t packet_out;
+    packet_in_header_t packet_in;
+    ethernet_t ethernet;
+    ipv4_t ipv4;
+    tcp_t tcp;
+    udp_t udp;
+}
+
+struct local_metadata_t {
+    bit<16>       l4_src_port;
+    bit<16>       l4_dst_port;
+    next_hop_id_t next_hop_id;
+}
+
+#endif
\ No newline at end of file
diff --git a/pipelines/basic/src/main/resources/include/headers.p4 b/pipelines/basic/src/main/resources/include/headers.p4
index 038e952..d8478a6 100644
--- a/pipelines/basic/src/main/resources/include/headers.p4
+++ b/pipelines/basic/src/main/resources/include/headers.p4
@@ -71,19 +71,4 @@
     bit<16> checksum;
 }
 
-struct headers_t {
-    ethernet_t ethernet;
-    ipv4_t ipv4;
-    tcp_t tcp;
-    udp_t udp;
-    packet_out_header_t packet_out;
-    packet_in_header_t packet_in;
-}
-
-struct local_metadata_t {
-    bit<16>       l4_src_port;
-    bit<16>       l4_dst_port;
-    next_hop_id_t next_hop_id;
-}
-
 #endif
diff --git a/pipelines/basic/src/main/resources/include/int_defines.p4 b/pipelines/basic/src/main/resources/include/int_defines.p4
new file mode 100644
index 0000000..30f0ce6
--- /dev/null
+++ b/pipelines/basic/src/main/resources/include/int_defines.p4
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* -*- P4_16 -*- */
+#ifndef __INT_DEFINE__
+#define __INT_DEFINE__
+
+#include "defines.p4"
+
+const next_hop_id_t INT_PORT = 54321;
+
+typedef bit<48> timestamp_t;
+typedef bit<32> switch_id_t;
+
+const bit<8> INT_HEADER_LEN_WORD = 4;
+
+const bit<8> CPU_MIRROR_SESSION_ID = 250;
+
+#endif
\ No newline at end of file
diff --git a/pipelines/basic/src/main/resources/include/int_headers.p4 b/pipelines/basic/src/main/resources/include/int_headers.p4
new file mode 100644
index 0000000..8d8850f
--- /dev/null
+++ b/pipelines/basic/src/main/resources/include/int_headers.p4
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* -*- P4_16 -*- */
+#ifndef __CUSTOM_HEADERS__
+#define __CUSTOM_HEADERS__
+
+/* INT headers */
+header int_header_t {
+    bit<2>  ver;
+    bit<2>  rep;
+    bit<1>  c;
+    bit<1>  e;
+    bit<5>  rsvd1;
+    bit<5>  ins_cnt;
+    bit<8>  max_hop_cnt;
+    bit<8>  total_hop_cnt;
+    bit<4>  instruction_mask_0003; /* split the bits for lookup */
+    bit<4>  instruction_mask_0407;
+    bit<4>  instruction_mask_0811;
+    bit<4>  instruction_mask_1215;
+    bit<16> rsvd2;
+}
+
+// INT meta-value headers - different header for each value type
+header int_switch_id_t {
+    bit<32> switch_id;
+}
+header int_port_ids_t {
+    bit<16> ingress_port_id;
+    bit<16> egress_port_id;
+}
+header int_hop_latency_t {
+    bit<32> hop_latency;
+}
+header int_q_occupancy_t {
+    bit<8> q_id;
+    bit<24> q_occupancy;
+}
+header int_ingress_tstamp_t {
+    bit<32> ingress_tstamp;
+}
+header int_egress_tstamp_t {
+    bit<32> egress_tstamp;
+}
+header int_q_congestion_t {
+    bit<8> q_id;
+    bit<24> q_congestion;
+}
+header int_egress_port_tx_util_t {
+    bit<32> egress_port_tx_util;
+}
+
+header int_data_t {
+    // Maximum int metadata stack size in bits:
+    // (0xFF -4) * 32 (excluding INT shim header, tail header and INT header)
+    varbit<8032> data;
+}
+
+/* INT shim header for TCP/UDP */
+header intl4_shim_t {
+    bit<8> int_type;
+    bit<8> rsvd1;
+    bit<8> len;
+    bit<8> rsvd2;
+}
+/* INT tail header for TCP/UDP */
+header intl4_tail_t {
+    bit<8> next_proto;
+    bit<16> dest_port;
+    bit<8> dscp;
+}
+
+header 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;
+}
+
+struct headers_t {
+    packet_out_header_t packet_out;
+    packet_in_header_t packet_in;
+    ethernet_t ethernet;
+    ipv4_t ipv4;
+    tcp_t tcp;
+    udp_t udp;
+
+    // INT specific headers
+    intl4_shim_t intl4_shim;
+    int_header_t int_header;
+    int_data_t int_data;
+    int_switch_id_t int_switch_id;
+    int_port_ids_t int_port_ids;
+    int_hop_latency_t int_hop_latency;
+    int_q_occupancy_t int_q_occupancy;
+    int_ingress_tstamp_t int_ingress_tstamp;
+    int_egress_tstamp_t int_egress_tstamp;
+    int_q_congestion_t int_q_congestion;
+    int_egress_port_tx_util_t int_egress_tx_util;
+    intl4_tail_t intl4_tail;
+}
+
+struct local_metadata_t {
+    bit<16>       l4_src_port;
+    bit<16>       l4_dst_port;
+    next_hop_id_t next_hop_id;
+    bit<16>       selector;
+    int_metadata_t int_meta;
+}
+
+#endif
\ No newline at end of file
diff --git a/pipelines/basic/src/main/resources/include/int_parser.p4 b/pipelines/basic/src/main/resources/include/int_parser.p4
new file mode 100644
index 0000000..63c29fb
--- /dev/null
+++ b/pipelines/basic/src/main/resources/include/int_parser.p4
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* -*- P4_16 -*- */
+#ifndef __PARSER__
+#define __PARSER__
+
+parser int_parser (
+    packet_in packet,
+    out headers_t hdr,
+    inout local_metadata_t local_metadata,
+    inout standard_metadata_t standard_metadata) {
+    state start {
+        transition select(standard_metadata.ingress_port) {
+            CPU_PORT: parse_packet_out;
+            default: parse_ethernet;
+        }
+    }
+
+    state parse_packet_out {
+        packet.extract(hdr.packet_out);
+        transition parse_ethernet;
+    }
+
+    state parse_ethernet {
+        packet.extract(hdr.ethernet);
+        transition select(hdr.ethernet.ether_type) {
+            ETH_TYPE_IPV4 : parse_ipv4;
+            default : accept;
+        }
+    }
+
+    state parse_ipv4 {
+        packet.extract(hdr.ipv4);
+        transition select(hdr.ipv4.protocol) {
+            IP_PROTO_TCP : parse_tcp;
+            IP_PROTO_UDP : parse_udp;
+            default: accept;
+        }
+    }
+
+    state parse_tcp {
+        packet.extract(hdr.tcp);
+        transition 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;
+            default: accept;
+        }
+    }
+
+    state parse_intl4_shim {
+        packet.extract(hdr.intl4_shim);
+        transition parse_int_header;
+    }
+
+    state parse_int_header {
+        packet.extract(hdr.int_header);
+        // If there is no INT metadata but the INT header (and corresponding shim header
+        // and tail header) exists, default value of length field in shim header
+        // should be INT_HEADER_LEN_WORD.
+        local_metadata.int_meta.metadata_len = hdr.intl4_shim.len - INT_HEADER_LEN_WORD;
+        transition select (local_metadata.int_meta.metadata_len) {
+            0: parse_intl4_tail;
+            default: parse_int_data;
+        }
+    }
+
+    state parse_int_data {
+        // Parse INT metadata, not INT header, INT shim header and INT tail header
+        packet.extract(hdr.int_data, (bit<32>) ((hdr.intl4_shim.len - INT_HEADER_LEN_WORD) << 5));
+        transition parse_intl4_tail;
+    }
+
+    state parse_intl4_tail {
+        packet.extract(hdr.intl4_tail);
+        transition accept;
+    }
+}
+
+control int_deparser(
+    packet_out packet,
+    in headers_t hdr) {
+    apply {
+        packet.emit(hdr.packet_in);
+        packet.emit(hdr.ethernet);
+        packet.emit(hdr.ipv4);
+        packet.emit(hdr.tcp);
+        packet.emit(hdr.udp);
+        packet.emit(hdr.intl4_shim);
+        packet.emit(hdr.int_header);
+        packet.emit(hdr.int_switch_id);
+        packet.emit(hdr.int_port_ids);
+        packet.emit(hdr.int_hop_latency);
+        packet.emit(hdr.int_q_occupancy);
+        packet.emit(hdr.int_ingress_tstamp);
+        packet.emit(hdr.int_egress_tstamp);
+        packet.emit(hdr.int_q_congestion);
+        packet.emit(hdr.int_egress_tx_util);
+        packet.emit(hdr.int_data);
+        packet.emit(hdr.intl4_tail);
+    }
+}
+
+#endif
\ No newline at end of file
diff --git a/pipelines/basic/src/main/resources/include/int_sink.p4 b/pipelines/basic/src/main/resources/include/int_sink.p4
new file mode 100644
index 0000000..29c85ef
--- /dev/null
+++ b/pipelines/basic/src/main/resources/include/int_sink.p4
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* -*- P4_16 -*- */
+#ifndef __INT_SINK__
+#define __INT_SINK__
+
+// TODO: implement report logic to external collector
+control process_int_sink (
+    inout headers_t hdr,
+    inout local_metadata_t local_metadata,
+    inout standard_metadata_t standard_metadata) {
+    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;
+    }
+
+    apply {
+        if (local_metadata.int_meta.sink == 1) {
+            int_sink();
+            restore_port();
+        }
+    }
+}
+#endif
\ No newline at end of file
diff --git a/pipelines/basic/src/main/resources/include/int_source.p4 b/pipelines/basic/src/main/resources/include/int_source.p4
new file mode 100644
index 0000000..a09309f
--- /dev/null
+++ b/pipelines/basic/src/main/resources/include/int_source.p4
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* -*- P4_16 -*- */
+#ifndef __INT_SOURCE__
+#define __INT_SOURCE__
+
+// Insert INT header to the packet
+control process_int_source (
+    inout headers_t hdr,
+    inout local_metadata_t local_metadata,
+    inout standard_metadata_t standard_metadata) {
+
+    direct_counter(CounterType.packets_and_bytes) counter_int_source;
+
+    action int_source(bit<8> max_hop, bit<5> ins_cnt, bit<4> ins_mask0003, bit<4> ins_mask0407) {
+        // insert INT shim header
+        hdr.intl4_shim.setValid();
+        // int_type: Hop-by-hop type (1) , destination type (2)
+        hdr.intl4_shim.int_type = 1;
+        hdr.intl4_shim.len = INT_HEADER_LEN_WORD;
+
+        // insert INT header
+        hdr.int_header.setValid();
+        hdr.int_header.ver = 0;
+        hdr.int_header.rep = 0;
+        hdr.int_header.c = 0;
+        hdr.int_header.e = 0;
+        hdr.int_header.rsvd1 = 0;
+        hdr.int_header.ins_cnt = ins_cnt;
+        hdr.int_header.max_hop_cnt = max_hop;
+        hdr.int_header.total_hop_cnt = 0;
+        hdr.int_header.instruction_mask_0003 = ins_mask0003;
+        hdr.int_header.instruction_mask_0407 = ins_mask0407;
+        hdr.int_header.instruction_mask_0811 = 0; // not supported
+        hdr.int_header.instruction_mask_1215 = 0; // not supported
+
+        // insert INT tail header
+        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;
+
+        // add the header len (8 bytes) to total len
+        hdr.ipv4.len = hdr.ipv4.len + 16;
+        hdr.udp.length_ = hdr.udp.length_ + 16;
+    }
+
+    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
+        }
+        counters = counter_int_source;
+        size = 1024;
+    }
+
+    apply {
+        tb_int_source.apply();
+    }
+}
+
+control process_set_source_sink (
+    inout headers_t hdr,
+    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;
+
+    action int_set_source () {
+        local_metadata.int_meta.source =  1;
+    }
+
+    action int_set_sink () {
+        local_metadata.int_meta.sink = 1;
+    }
+
+    table tb_set_source {
+        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_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;
+        size = 1024;
+    }
+
+    apply {
+        if (hdr.udp.isValid()) {
+            tb_set_source.apply();
+            tb_set_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
new file mode 100644
index 0000000..7f553c5
--- /dev/null
+++ b/pipelines/basic/src/main/resources/include/int_transit.p4
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* -*- P4_16 -*- */
+#ifndef __INT_TRANSIT__
+#define __INT_TRANSIT__
+control process_int_transit (
+    inout headers_t hdr,
+    inout local_metadata_t local_metadata,
+    inout standard_metadata_t standard_metadata) {
+
+    direct_counter(CounterType.packets_and_bytes) counter_int_insert;
+    direct_counter(CounterType.packets_and_bytes) counter_int_inst_0003;
+    direct_counter(CounterType.packets_and_bytes) counter_int_inst_0407;
+
+    action int_update_total_hop_cnt() {
+        hdr.int_header.total_hop_cnt = hdr.int_header.total_hop_cnt + 1;
+    }
+
+    action int_transit(switch_id_t switch_id) {
+        local_metadata.int_meta.switch_id = switch_id;
+        local_metadata.int_meta.insert_byte_cnt = (bit<16>) hdr.int_header.ins_cnt << 2;
+    }
+
+    /* Instr Bit 0 */
+    action int_set_header_0() { //switch_id
+        hdr.int_switch_id.setValid();
+        hdr.int_switch_id.switch_id = local_metadata.int_meta.switch_id;
+    }
+    action int_set_header_1() { //port_ids
+        hdr.int_port_ids.setValid();
+        hdr.int_port_ids.ingress_port_id =
+        (bit<16>) standard_metadata.ingress_port;
+        hdr.int_port_ids.egress_port_id =
+        (bit<16>) standard_metadata.egress_port;
+    }
+    action int_set_header_2() { //hop_latency
+        hdr.int_hop_latency.setValid();
+        hdr.int_hop_latency.hop_latency =
+        (bit<32>) standard_metadata.deq_timedelta;
+    }
+    action int_set_header_3() { //q_occupancy
+        // TODO: Support egress queue ID
+        hdr.int_q_occupancy.setValid();
+        hdr.int_q_occupancy.q_id =
+        0;
+        // (bit<8>) standard_metadata.egress_qid;
+        hdr.int_q_occupancy.q_occupancy =
+        (bit<24>) standard_metadata.deq_qdepth;
+    }
+    action int_set_header_4() { //ingress_tstamp
+        hdr.int_ingress_tstamp.setValid();
+        hdr.int_ingress_tstamp.ingress_tstamp =
+        (bit<32>) standard_metadata.enq_timestamp;
+    }
+    action int_set_header_5() { //egress_timestamp
+        hdr.int_egress_tstamp.setValid();
+        hdr.int_egress_tstamp.egress_tstamp =
+        (bit<32>) standard_metadata.enq_timestamp +
+        (bit<32>) standard_metadata.deq_timedelta;
+    }
+    action int_set_header_6() { //q_congestion
+        // TODO: implement queue congestion support in BMv2
+        // TODO: update egress queue ID
+        hdr.int_q_congestion.setValid();
+        hdr.int_q_congestion.q_id =
+        0;
+        // (bit<8>) standard_metadata.egress_qid;
+        hdr.int_q_congestion.q_congestion =
+        // (bit<24>) queueing_metadata.deq_congestion;
+        0;
+    }
+    action int_set_header_7() { //egress_port_tx_utilization
+        // TODO: implement tx utilization support in BMv2
+        hdr.int_egress_tx_util.setValid();
+        hdr.int_egress_tx_util.egress_port_tx_util =
+        // (bit<32>) queueing_metadata.tx_utilization;
+        0;
+    }
+
+    /* action function for bits 0-3 combinations, 0 is msb, 3 is lsb */
+    /* Each bit set indicates that corresponding INT header should be added */
+    action int_set_header_0003_i0() {
+    }
+    action int_set_header_0003_i1() {
+        int_set_header_3();
+    }
+    action int_set_header_0003_i2() {
+        int_set_header_2();
+    }
+    action int_set_header_0003_i3() {
+        int_set_header_3();
+        int_set_header_2();
+    }
+    action int_set_header_0003_i4() {
+        int_set_header_1();
+    }
+    action int_set_header_0003_i5() {
+        int_set_header_3();
+        int_set_header_1();
+    }
+    action int_set_header_0003_i6() {
+        int_set_header_2();
+        int_set_header_1();
+    }
+    action int_set_header_0003_i7() {
+        int_set_header_3();
+        int_set_header_2();
+        int_set_header_1();
+    }
+    action int_set_header_0003_i8() {
+        int_set_header_0();
+    }
+    action int_set_header_0003_i9() {
+        int_set_header_3();
+        int_set_header_0();
+    }
+    action int_set_header_0003_i10() {
+        int_set_header_2();
+        int_set_header_0();
+    }
+    action int_set_header_0003_i11() {
+        int_set_header_3();
+        int_set_header_2();
+        int_set_header_0();
+    }
+    action int_set_header_0003_i12() {
+        int_set_header_1();
+        int_set_header_0();
+    }
+    action int_set_header_0003_i13() {
+        int_set_header_3();
+        int_set_header_1();
+        int_set_header_0();
+    }
+    action int_set_header_0003_i14() {
+        int_set_header_2();
+        int_set_header_1();
+        int_set_header_0();
+    }
+    action int_set_header_0003_i15() {
+        int_set_header_3();
+        int_set_header_2();
+        int_set_header_1();
+        int_set_header_0();
+    }
+
+    /* action function for bits 4-7 combinations, 4 is msb, 7 is lsb */
+    action int_set_header_0407_i0() {
+    }
+    action int_set_header_0407_i1() {
+        int_set_header_7();
+    }
+    action int_set_header_0407_i2() {
+        int_set_header_6();
+    }
+    action int_set_header_0407_i3() {
+        int_set_header_7();
+        int_set_header_6();
+    }
+    action int_set_header_0407_i4() {
+        int_set_header_5();
+    }
+    action int_set_header_0407_i5() {
+        int_set_header_7();
+        int_set_header_5();
+    }
+    action int_set_header_0407_i6() {
+        int_set_header_6();
+        int_set_header_5();
+    }
+    action int_set_header_0407_i7() {
+        int_set_header_7();
+        int_set_header_6();
+        int_set_header_5();
+    }
+    action int_set_header_0407_i8() {
+        int_set_header_4();
+    }
+    action int_set_header_0407_i9() {
+        int_set_header_7();
+        int_set_header_4();
+    }
+    action int_set_header_0407_i10() {
+        int_set_header_6();
+        int_set_header_4();
+    }
+    action int_set_header_0407_i11() {
+        int_set_header_7();
+        int_set_header_6();
+        int_set_header_4();
+    }
+    action int_set_header_0407_i12() {
+        int_set_header_5();
+        int_set_header_4();
+    }
+    action int_set_header_0407_i13() {
+        int_set_header_7();
+        int_set_header_5();
+        int_set_header_4();
+    }
+    action int_set_header_0407_i14() {
+        int_set_header_6();
+        int_set_header_5();
+        int_set_header_4();
+    }
+    action int_set_header_0407_i15() {
+        int_set_header_7();
+        int_set_header_6();
+        int_set_header_5();
+        int_set_header_4();
+    }
+
+    table tb_int_insert {
+        key = {
+            local_metadata.int_meta.sink: exact;
+        }
+        actions = {
+            int_transit;
+        }
+        counters = counter_int_insert;
+        size = 2;
+    }
+
+    /* Table to process instruction bits 0-3 */
+    table tb_int_inst_0003 {
+        key = {
+            hdr.int_header.instruction_mask_0003 : exact;
+        }
+        actions = {
+            int_set_header_0003_i0;
+            int_set_header_0003_i1;
+            int_set_header_0003_i2;
+            int_set_header_0003_i3;
+            int_set_header_0003_i4;
+            int_set_header_0003_i5;
+            int_set_header_0003_i6;
+            int_set_header_0003_i7;
+            int_set_header_0003_i8;
+            int_set_header_0003_i9;
+            int_set_header_0003_i10;
+            int_set_header_0003_i11;
+            int_set_header_0003_i12;
+            int_set_header_0003_i13;
+            int_set_header_0003_i14;
+            int_set_header_0003_i15;
+        }
+        counters = counter_int_inst_0003;
+        size = 16;
+    }
+
+    /* Table to process instruction bits 4-7 */
+    table tb_int_inst_0407 {
+        key = {
+            hdr.int_header.instruction_mask_0407 : exact;
+        }
+        actions = {
+            int_set_header_0407_i0;
+            int_set_header_0407_i1;
+            int_set_header_0407_i2;
+            int_set_header_0407_i3;
+            int_set_header_0407_i4;
+            int_set_header_0407_i5;
+            int_set_header_0407_i6;
+            int_set_header_0407_i7;
+            int_set_header_0407_i8;
+            int_set_header_0407_i9;
+            int_set_header_0407_i10;
+            int_set_header_0407_i11;
+            int_set_header_0407_i12;
+            int_set_header_0407_i13;
+            int_set_header_0407_i14;
+            int_set_header_0407_i15;
+        }
+        counters = counter_int_inst_0407;
+        size = 16;
+    }
+
+    apply {
+        tb_int_insert.apply();
+        tb_int_inst_0003.apply();
+        tb_int_inst_0407.apply();
+        int_update_total_hop_cnt();
+    }
+}
+
+control process_int_outer_encap (
+    inout headers_t hdr,
+    inout local_metadata_t local_metadata,
+    inout standard_metadata_t standard_metadata) {
+
+    action int_update_ipv4() {
+        hdr.ipv4.len = hdr.ipv4.len + local_metadata.int_meta.insert_byte_cnt;
+    }
+    action int_update_udp() {
+        hdr.udp.length_ = hdr.udp.length_ + local_metadata.int_meta.insert_byte_cnt;
+        hdr.intl4_shim.len = hdr.intl4_shim.len + (bit<8>)hdr.int_header.ins_cnt;
+    }
+
+    apply {
+        if (hdr.ipv4.isValid()) {
+            int_update_ipv4();
+        }
+
+        if (hdr.intl4_shim.isValid()) {
+            int_update_udp();
+        }
+    }
+}
+
+#endif