Integrating INT into fabric pipeline
Change-Id: I9555de0852de79d1a3c7302ecaa17ff112fc5107
diff --git a/pipelines/fabric/src/main/resources/include/checksum.p4 b/pipelines/fabric/src/main/resources/include/checksum.p4
index d920235..4d1b803 100644
--- a/pipelines/fabric/src/main/resources/include/checksum.p4
+++ b/pipelines/fabric/src/main/resources/include/checksum.p4
@@ -29,7 +29,8 @@
{
hdr.ipv4.version,
hdr.ipv4.ihl,
- hdr.ipv4.diffserv,
+ hdr.ipv4.dscp,
+ hdr.ipv4.ecn,
hdr.ipv4.total_len,
hdr.ipv4.identification,
hdr.ipv4.flags,
@@ -57,7 +58,8 @@
{
hdr.ipv4.version,
hdr.ipv4.ihl,
- hdr.ipv4.diffserv,
+ hdr.ipv4.dscp,
+ hdr.ipv4.ecn,
hdr.ipv4.total_len,
hdr.ipv4.identification,
hdr.ipv4.flags,
diff --git a/pipelines/fabric/src/main/resources/include/define.p4 b/pipelines/fabric/src/main/resources/include/define.p4
index 176911e..74c964e 100644
--- a/pipelines/fabric/src/main/resources/include/define.p4
+++ b/pipelines/fabric/src/main/resources/include/define.p4
@@ -53,6 +53,14 @@
#define GTPU_VERSION 0x01
#define GTP_PROTOCOL_TYPE_GTP 0x01
+#define PKT_INSTANCE_TYPE_NORMAL 0
+#define PKT_INSTANCE_TYPE_INGRESS_CLONE 1
+#define PKT_INSTANCE_TYPE_EGRESS_CLONE 2
+#define PKT_INSTANCE_TYPE_COALESCED 3
+#define PKT_INSTANCE_TYPE_INGRESS_RECIRC 4
+#define PKT_INSTANCE_TYPE_REPLICATION 5
+#define PKT_INSTANCE_TYPE_RESUBMIT 6
+
typedef bit<3> fwd_type_t;
typedef bit<32> next_id_t;
typedef bit<20> mpls_label_t;
@@ -101,4 +109,29 @@
const pcc_gate_status_t PCC_GATE_OPEN = 1w0;
const pcc_gate_status_t PCC_GATE_CLOSED = 1w1;
+/* indicate INT at LSB of DSCP */
+const bit<6> INT_DSCP = 0x1;
+
+typedef bit<48> timestamp_t;
+typedef bit<32> switch_id_t;
+typedef bit<32> ip_address_t;
+typedef bit<16> l4_port_t;
+
+const bit<8> INT_HEADER_LEN_WORD = 4;
+
+const bit<8> CPU_MIRROR_SESSION_ID = 250;
+const bit<32> REPORT_MIRROR_SESSION_ID = 500;
+
+const bit<4> NPROTO_ETHERNET = 0;
+const bit<4> NPROTO_TELEMETRY_DROP_HEADER = 1;
+const bit<4> NPROTO_TELEMETRY_SWITCH_LOCAL_HEADER = 2;
+
+const bit<6> HW_ID = 1;
+const bit<8> REPORT_FIXED_HEADER_LEN = 12;
+const bit<8> DROP_REPORT_HEADER_LEN = 12;
+const bit<8> LOCAL_REPORT_HEADER_LEN = 16;
+const bit<8> ETH_HEADER_LEN = 14;
+const bit<8> IPV4_MIN_HEAD_LEN = 20;
+const bit<8> UDP_HEADER_LEN = 8;
+
#endif
diff --git a/pipelines/fabric/src/main/resources/include/header.p4 b/pipelines/fabric/src/main/resources/include/header.p4
index bc0b18f..c1df60e 100644
--- a/pipelines/fabric/src/main/resources/include/header.p4
+++ b/pipelines/fabric/src/main/resources/include/header.p4
@@ -55,7 +55,8 @@
header ipv4_t {
bit<4> version;
bit<4> ihl;
- bit<8> diffserv;
+ bit<6> dscp;
+ bit<2> ecn;
bit<16> total_len;
bit<16> identification;
bit<3> flags;
@@ -147,6 +148,122 @@
}
#endif // WITH_SPGW
+#ifdef WITH_INT
+// Report Telemetry Headers
+header report_fixed_header_t {
+ bit<4> ver;
+ bit<4> nproto;
+ bit<1> d;
+ bit<1> q;
+ bit<1> f;
+ bit<15> rsvd;
+ bit<6> hw_id;
+ bit<32> seq_no;
+ bit<32> ingress_tstamp;
+}
+
+// Telemetry drop report header
+header drop_report_header_t {
+ bit<32> switch_id;
+ bit<16> ingress_port_id;
+ bit<16> egress_port_id;
+ bit<8> queue_id;
+ bit<8> drop_reason;
+ bit<16> pad;
+}
+
+// Switch Local Report Header
+header local_report_header_t {
+ bit<32> switch_id;
+ bit<16> ingress_port_id;
+ bit<16> egress_port_id;
+ bit<8> queue_id;
+ bit<24> queue_occupancy;
+ bit<32> egress_tstamp;
+}
+
+header_union local_report_t {
+ drop_report_header_t drop_report_header;
+ local_report_header_t local_report_header;
+}
+
+// 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;
+}
+
+struct int_metadata_t {
+ switch_id_t switch_id;
+ bit<16> insert_byte_cnt;
+ bit<1> source;
+ bit<1> sink;
+ bit<8> mirror_id;
+ bit<16> flow_id;
+ bit<8> metadata_len;
+}
+#endif // WITH_INT
+
//Custom metadata definition
struct fabric_metadata_t {
fwd_type_t fwd_type;
@@ -160,6 +277,10 @@
#ifdef WITH_SPGW
spgw_meta_t spgw;
#endif // WITH_SPGW
+#ifdef WITH_INT
+ int_metadata_t int_meta;
+ bool compute_checksum;
+#endif // WITH_INT
}
struct parsed_headers_t {
@@ -181,6 +302,28 @@
icmp_t icmp;
packet_out_header_t packet_out;
packet_in_header_t packet_in;
+#ifdef WITH_INT
+ // INT Report Encapsulation
+ ethernet_t report_ethernet;
+ ipv4_t report_ipv4;
+ udp_t report_udp;
+ // INT Report Headers
+ report_fixed_header_t report_fixed_header;
+ local_report_t report_local;
+ // 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;
+#endif //WITH_INT
}
#endif
diff --git a/pipelines/fabric/src/main/resources/include/int_report.p4 b/pipelines/fabric/src/main/resources/include/int_report.p4
new file mode 100644
index 0000000..da158e2
--- /dev/null
+++ b/pipelines/fabric/src/main/resources/include/int_report.p4
@@ -0,0 +1,99 @@
+/*
+ * 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_REPORT__
+#define __INT_REPORT__
+
+control process_int_report (
+ inout parsed_headers_t hdr,
+ inout fabric_metadata_t fabric_metadata,
+ inout standard_metadata_t standard_metadata) {
+
+ action add_report_fixed_header() {
+ /* Device should include its own INT metadata as embedded,
+ * we'll not use fabric_report_header for this purpose.
+ */
+ hdr.report_fixed_header.setValid();
+ hdr.report_fixed_header.ver = 0;
+ /* only support for flow_watchlist */
+ hdr.report_fixed_header.nproto = NPROTO_ETHERNET;
+ hdr.report_fixed_header.d = 0;
+ hdr.report_fixed_header.q = 0;
+ hdr.report_fixed_header.f = 1;
+ hdr.report_fixed_header.rsvd = 0;
+ //TODO how to get information specific to the switch
+ hdr.report_fixed_header.hw_id = HW_ID;
+ // TODO how save a variable and increment
+ hdr.report_fixed_header.seq_no = 0;
+ //TODO how to get timestamp from ingress ns
+ hdr.report_fixed_header.ingress_tstamp =
+ (bit<32>) standard_metadata.enq_timestamp;
+ }
+
+ action do_report_encapsulation(mac_addr_t src_mac, mac_addr_t mon_mac, ip_address_t src_ip,
+ ip_address_t mon_ip, l4_port_t mon_port) {
+ //Report Ethernet Header
+ hdr.report_ethernet.setValid();
+ hdr.report_ethernet.dst_addr = mon_mac;
+ hdr.report_ethernet.src_addr = src_mac;
+ hdr.report_ethernet.ether_type = ETHERTYPE_IPV4;
+
+ //Report IPV4 Header
+ hdr.report_ipv4.setValid();
+ hdr.report_ipv4.version = 4w4;
+ hdr.report_ipv4.ihl = 4w5;
+ hdr.report_ipv4.dscp = 6w0;
+ hdr.report_ipv4.ecn = 2w0;
+ /* Total Len is report_ipv4_len + report_udp_len + report_fixed_hdr_len + ethernet_len + ipv4_totalLen */
+ hdr.report_ipv4.total_len = (bit<16>) IPV4_MIN_HEAD_LEN + (bit<16>) UDP_HEADER_LEN +
+ (bit<16>) REPORT_FIXED_HEADER_LEN + (bit<16>) ETH_HEADER_LEN + hdr.ipv4.total_len;
+ /* Dont Fragment bit should be set */
+ hdr.report_ipv4.identification = 0;
+ hdr.report_ipv4.flags = 0;
+ hdr.report_ipv4.frag_offset = 0;
+ hdr.report_ipv4.ttl = 0xFF;
+ hdr.report_ipv4.protocol = PROTO_UDP;
+ hdr.report_ipv4.src_addr = src_ip;
+ hdr.report_ipv4.dst_addr = mon_ip;
+
+ //Report UDP Header
+ hdr.report_udp.setValid();
+ hdr.report_udp.src_port = 0;
+ hdr.report_udp.dst_port = mon_port;
+ hdr.report_udp.len = (bit<16>) UDP_HEADER_LEN + (bit<16>) REPORT_FIXED_HEADER_LEN +
+ (bit<16>) ETH_HEADER_LEN + hdr.ipv4.total_len;
+
+ fabric_metadata.compute_checksum = true;
+ add_report_fixed_header();
+ }
+
+ /* Cloned packet instance_type is PKT_INSTANCE_TYPE_INGRESS_CLONE=1
+ * Packet is forwarded according to the mirroring_add command
+ */
+ table tb_generate_report {
+ key = {
+ }
+ actions = {
+ do_report_encapsulation;
+ }
+ }
+
+ apply {
+ tb_generate_report.apply();
+ }
+}
+#endif
diff --git a/pipelines/fabric/src/main/resources/include/int_sink.p4 b/pipelines/fabric/src/main/resources/include/int_sink.p4
new file mode 100644
index 0000000..4c272d6
--- /dev/null
+++ b/pipelines/fabric/src/main/resources/include/int_sink.p4
@@ -0,0 +1,54 @@
+/*
+ * 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__
+
+control process_int_sink (
+ inout parsed_headers_t hdr,
+ inout fabric_metadata_t fabric_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.total_len = hdr.ipv4.total_len - (bit<16>)(hdr.intl4_shim.len << 2);
+ hdr.udp.len = hdr.udp.len - (bit<16>)(hdr.intl4_shim.len << 2);
+ // remove all the INT information from the packet
+ hdr.int_header.setInvalid();
+ hdr.int_data.setInvalid();
+ hdr.intl4_shim.setInvalid();
+ hdr.intl4_tail.setInvalid();
+ 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 {
+ restore_header();
+ int_sink();
+ }
+}
+#endif
\ No newline at end of file
diff --git a/pipelines/fabric/src/main/resources/include/int_source.p4 b/pipelines/fabric/src/main/resources/include/int_source.p4
new file mode 100644
index 0000000..57c2b79
--- /dev/null
+++ b/pipelines/fabric/src/main/resources/include/int_source.p4
@@ -0,0 +1,127 @@
+/*
+ * 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 parsed_headers_t hdr,
+ inout fabric_metadata_t fabric_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 = fabric_metadata.l4_dst_port;
+ hdr.intl4_tail.dscp = (bit<8>) hdr.ipv4.dscp;
+
+ // add the header len (8 bytes) to total len
+ hdr.ipv4.total_len = hdr.ipv4.total_len + 16;
+ hdr.udp.len = hdr.udp.len + 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 = {
+ hdr.ipv4.src_addr: ternary;
+ hdr.ipv4.dst_addr: ternary;
+ fabric_metadata.l4_src_port: ternary;
+ fabric_metadata.l4_dst_port: ternary;
+ }
+ actions = {
+ int_source_dscp;
+ }
+ counters = counter_int_source;
+ size = 1024;
+ }
+
+ apply {
+ tb_int_source.apply();
+ }
+}
+
+control process_set_source_sink (
+ inout parsed_headers_t hdr,
+ inout fabric_metadata_t fabric_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 () {
+ fabric_metadata.int_meta.source = 1;
+ }
+
+ action int_set_sink () {
+ fabric_metadata.int_meta.sink = 1;
+ }
+
+ table tb_set_source {
+ key = {
+ standard_metadata.ingress_port: exact;
+ }
+ actions = {
+ int_set_source;
+ }
+ counters = counter_set_source;
+ size = 256;
+ }
+ table tb_set_sink {
+ key = {
+ standard_metadata.egress_spec: exact;
+ }
+ actions = {
+ int_set_sink;
+ }
+ counters = counter_set_sink;
+ size = 256;
+ }
+
+ apply {
+ tb_set_source.apply();
+ tb_set_sink.apply();
+ }
+}
+#endif
diff --git a/pipelines/fabric/src/main/resources/include/int_transit.p4 b/pipelines/fabric/src/main/resources/include/int_transit.p4
new file mode 100644
index 0000000..3f863e8
--- /dev/null
+++ b/pipelines/fabric/src/main/resources/include/int_transit.p4
@@ -0,0 +1,326 @@
+/*
+ * 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 parsed_headers_t hdr,
+ inout fabric_metadata_t fabric_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) {
+ fabric_metadata.int_meta.switch_id = switch_id;
+ fabric_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 = fabric_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 = {}
+ 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 parsed_headers_t hdr,
+ inout fabric_metadata_t fabric_metadata,
+ inout standard_metadata_t standard_metadata) {
+
+ action int_update_ipv4() {
+ hdr.ipv4.total_len = hdr.ipv4.total_len + fabric_metadata.int_meta.insert_byte_cnt;
+ }
+ action int_update_udp() {
+ hdr.udp.len = hdr.udp.len + fabric_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;
+ }
+
+ apply {
+ if (hdr.ipv4.isValid()) {
+ int_update_ipv4();
+ }
+ if (hdr.udp.isValid()) {
+ int_update_udp();
+ }
+ if (hdr.intl4_shim.isValid()) {
+ int_update_shim();
+ }
+ }
+}
+
+#endif
diff --git a/pipelines/fabric/src/main/resources/include/parser.p4 b/pipelines/fabric/src/main/resources/include/parser.p4
index 3f70f3e..b94ca50 100644
--- a/pipelines/fabric/src/main/resources/include/parser.p4
+++ b/pipelines/fabric/src/main/resources/include/parser.p4
@@ -113,7 +113,14 @@
packet.extract(hdr.tcp);
fabric_metadata.l4_src_port = hdr.tcp.src_port;
fabric_metadata.l4_dst_port = hdr.tcp.dst_port;
+#ifdef WITH_INT
+ transition select(hdr.ipv4.isValid() && ((hdr.ipv4.dscp & INT_DSCP) == INT_DSCP)) {
+ true: parse_intl4_shim;
+ default: accept;
+ }
+#else
transition accept;
+#endif // WITH_INT
}
state parse_udp {
@@ -125,9 +132,14 @@
UDP_PORT_GTPU: parse_gtpu;
default: accept;
}
+#elif WITH_INT
+ transition select(hdr.ipv4.isValid() && (hdr.ipv4.dscp & INT_DSCP) == INT_DSCP) {
+ true: parse_intl4_shim;
+ default: accept;
+ }
#else
transition accept;
-#endif // WITH_SPGW
+#endif // WITH_SPGW, WITH_INT
}
state parse_icmp {
@@ -135,6 +147,36 @@
transition accept;
}
+#ifdef WITH_INT
+ 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.
+ fabric_metadata.int_meta.metadata_len = hdr.intl4_shim.len - INT_HEADER_LEN_WORD;
+ transition select (fabric_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;
+ }
+#endif // WITH_INT
+
#ifdef WITH_SPGW
state parse_gtpu {
packet.extract(hdr.gtpu);
@@ -155,7 +197,14 @@
packet.extract(hdr.gtpu_udp);
fabric_metadata.l4_src_port = hdr.gtpu_udp.src_port;
fabric_metadata.l4_dst_port = hdr.gtpu_udp.dst_port;
+#ifdef WITH_INT
+ transition select(hdr.ipv4.isValid() && (hdr.ipv4.dscp & INT_DSCP) == INT_DSCP) {
+ true: parse_intl4_shim;
+ default: accept;
+ }
+#else
transition accept;
+#endif // WITH_INT
}
#endif // WITH_SPGW
}
@@ -163,6 +212,12 @@
control FabricDeparser(packet_out packet, in parsed_headers_t hdr) {
apply {
packet.emit(hdr.packet_in);
+#ifdef WITH_INT
+ packet.emit(hdr.report_ethernet);
+ packet.emit(hdr.report_ipv4);
+ packet.emit(hdr.report_udp);
+ packet.emit(hdr.report_fixed_header);
+#endif // WITH_INT
packet.emit(hdr.ethernet);
packet.emit(hdr.vlan_tag);
packet.emit(hdr.mpls);
@@ -179,6 +234,20 @@
packet.emit(hdr.tcp);
packet.emit(hdr.udp);
packet.emit(hdr.icmp);
+#ifdef WITH_INT
+ 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 // WITH_INT
}
}
diff --git a/pipelines/fabric/src/main/resources/include/spgw.p4 b/pipelines/fabric/src/main/resources/include/spgw.p4
index 0dfd8f1..b3ac361 100644
--- a/pipelines/fabric/src/main/resources/include/spgw.p4
+++ b/pipelines/fabric/src/main/resources/include/spgw.p4
@@ -209,7 +209,8 @@
gtpu_ipv4.setValid();
gtpu_ipv4.version = IP_VERSION_4;
gtpu_ipv4.ihl = IPV4_MIN_IHL;
- gtpu_ipv4.diffserv = 0;
+ gtpu_ipv4.dscp = 0;
+ gtpu_ipv4.ecn = 0;
gtpu_ipv4.total_len = spgw_meta.ipv4_len
+ (IPV4_HDR_SIZE + UDP_HDR_SIZE + GTP_HDR_SIZE);
gtpu_ipv4.identification = 0x1513; /* From NGIC */
@@ -292,7 +293,8 @@
{
gtpu_ipv4.version,
gtpu_ipv4.ihl,
- gtpu_ipv4.diffserv,
+ gtpu_ipv4.dscp,
+ gtpu_ipv4.ecn,
gtpu_ipv4.total_len,
gtpu_ipv4.identification,
gtpu_ipv4.flags,