ONOS-6769 Support for PacketMetadata in demo P4 programs

Change-Id: I9b3de719f9eb1c87d1df16a5ad0d08a83cebc8f6
diff --git a/tools/test/p4src/p4-16/default.p4 b/tools/test/p4src/p4-16/default.p4
index 36e6279..13243b2 100644
--- a/tools/test/p4src/p4-16/default.p4
+++ b/tools/test/p4src/p4-16/default.p4
@@ -6,8 +6,10 @@
 #include "include/port_counters.p4"
 #include "include/checksums.p4"
 #include "include/actions.p4"
+#include "include/packet_io.p4"
 
-control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control ingress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
+
     direct_counter(CounterType.packets) table0_counter;
 
     table table0 {
@@ -25,30 +27,26 @@
         }
         counters = table0_counter;
     }
+
+    PacketIoIngressControl() packet_io_ingress_control;
     PortCountersControl() port_counters_control;
+
     apply {
-        table0.apply();
+        packet_io_ingress_control.apply(hdr, standard_metadata);
+        if (!hdr.packet_out.isValid()) {
+            table0.apply();
+        }
         port_counters_control.apply(hdr, meta, standard_metadata);
     }
 
 }
 
-control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control egress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
+
+    PacketIoEgressControl() packet_io_egress_control;
     apply {
-        // Nothing to do
+        packet_io_egress_control.apply(hdr, standard_metadata);
     }
 }
 
-@controller_header("packet_in")
-header packet_in_header_t {
-    bit<9> ingress_port;
-    bit<32> other1;
-}
-
-@controller_header("packet_out")
-header packet_out_header_t {
-    bit<9> egress_port;
-    bit<32> other2;
-}
-
 V1Switch(ParserImpl(), verifyChecksum(), ingress(), egress(), computeChecksum(), DeparserImpl()) main;
diff --git a/tools/test/p4src/p4-16/ecmp.p4 b/tools/test/p4src/p4-16/ecmp.p4
index 6b3e73e..3c06c20 100644
--- a/tools/test/p4src/p4-16/ecmp.p4
+++ b/tools/test/p4src/p4-16/ecmp.p4
@@ -6,15 +6,20 @@
 #include "include/port_counters.p4"
 #include "include/checksums.p4"
 #include "include/actions.p4"
+#include "include/packet_io.p4"
 
 
-control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control ingress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
+
     direct_counter(CounterType.packets) ecmp_group_table_counter;
     direct_counter(CounterType.packets) table0_counter;
 
-    action ecmp_group(GroupId groupId, GroupSize groupSize) {
-        meta.ecmp_metadata.groupId = groupId;
-        hash(meta.ecmp_metadata.selector, HashAlgorithm.crc16, (bit<64>)0, { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort, hdr.udp.srcPort, hdr.udp.dstPort }, (bit<128>)groupSize);
+    action ecmp_group(group_id_t group_id, group_size_t groupSize) {
+        meta.ecmp_metadata.group_id = group_id;
+        hash(meta.ecmp_metadata.selector, HashAlgorithm.crc16, (bit<64>)0,
+        { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort, hdr.udp.srcPort,
+            hdr.udp.dstPort },
+        (bit<128>)groupSize);
     }
 
     table ecmp_group_table {
@@ -22,7 +27,7 @@
             set_egress_port(standard_metadata);
         }
         key = {
-            meta.ecmp_metadata.groupId : exact;
+            meta.ecmp_metadata.group_id : exact;
             meta.ecmp_metadata.selector: exact;
         }
         counters = ecmp_group_table_counter;
@@ -44,21 +49,28 @@
         }
         counters = table0_counter;
     }
+
     PortCountersControl() port_counters_control;
+    PacketIoIngressControl() packet_io_ingress_control;
+
     apply {
-        switch (table0.apply().action_run) {
-            ecmp_group: {
-                ecmp_group_table.apply();
+        packet_io_ingress_control.apply(hdr, standard_metadata);
+        if (!hdr.packet_out.isValid()) {
+            switch (table0.apply().action_run) {
+                ecmp_group: {
+                    ecmp_group_table.apply();
+                }
             }
         }
-
         port_counters_control.apply(hdr, meta, standard_metadata);
     }
 }
 
-control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control egress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
+
+    PacketIoEgressControl() packet_io_egress_control;
     apply {
-        // Nothing to do
+        packet_io_egress_control.apply(hdr, standard_metadata);
     }
 }
 
diff --git a/tools/test/p4src/p4-16/empty.p4 b/tools/test/p4src/p4-16/empty.p4
index 09e4740..363ae11 100644
--- a/tools/test/p4src/p4-16/empty.p4
+++ b/tools/test/p4src/p4-16/empty.p4
@@ -5,20 +5,20 @@
     bit<8> dummyField;
 }
 
-struct metadata {
+struct metadata_t {
     dummy_t dummy_metadata;
 }
 
-struct headers {
+struct headers_t {
 }
 
-parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+parser ParserImpl(packet_in packet, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
     state start {
         transition accept;
     }
 }
 
-control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control ingress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
     action dummy_action() {
         meta.dummy_metadata.dummyField = 8w1;
     }
@@ -35,25 +35,25 @@
     }
 }
 
-control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control egress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
     apply {
         // Nothing to do
     }
 }
 
-control DeparserImpl(packet_out packet, in headers hdr) {
+control DeparserImpl(packet_out packet, in headers_t hdr) {
     apply {
         // Nothing to do
     }
 }
 
-control verifyChecksum(in headers hdr, inout metadata meta) {
+control verifyChecksum(in headers_t hdr, inout metadata_t meta) {
     apply {
         // Nothing to do
     }
 }
 
-control computeChecksum(inout headers hdr, inout metadata meta) {
+control computeChecksum(inout headers_t hdr, inout metadata_t meta) {
     apply {
         // Nothing to do
     }
diff --git a/tools/test/p4src/p4-16/include/actions.p4 b/tools/test/p4src/p4-16/include/actions.p4
index 0ef0533..87c1ed6 100644
--- a/tools/test/p4src/p4-16/include/actions.p4
+++ b/tools/test/p4src/p4-16/include/actions.p4
@@ -1,3 +1,5 @@
+#ifndef ACTIONS
+#define ACTIONS
 #include "defines.p4"
 #include "headers.p4"
 
@@ -5,10 +7,12 @@
     standard_metadata.egress_spec = CPU_PORT;
 }
 
-action set_egress_port(inout standard_metadata_t standard_metadata, Port port) {
+action set_egress_port(inout standard_metadata_t standard_metadata, port_t port) {
     standard_metadata.egress_spec = port;
 }
 
 action drop(inout standard_metadata_t standard_metadata) {
     standard_metadata.egress_spec = DROP_PORT;
 }
+
+#endif
\ No newline at end of file
diff --git a/tools/test/p4src/p4-16/include/checksums.p4 b/tools/test/p4src/p4-16/include/checksums.p4
index 09365dc..cb86f90 100644
--- a/tools/test/p4src/p4-16/include/checksums.p4
+++ b/tools/test/p4src/p4-16/include/checksums.p4
@@ -1,17 +1,18 @@
-#ifndef CHECK_SUMS
-#define CHECK_SUMS
+#ifndef CHECKSUMS
+#define CHECKSUMS
 #include "headers.p4"
 #include "metadata.p4"
 
-control verifyChecksum(in headers hdr, inout metadata meta) {
+control verifyChecksum(in headers_t hdr, inout metadata_t meta) {
     apply {
         // Nothing to do
     }
 }
 
-control computeChecksum(inout headers hdr, inout metadata meta) {
+control computeChecksum(inout headers_t hdr, inout metadata_t meta) {
     apply {
         // Nothing to do
     }
 }
+
 #endif
diff --git a/tools/test/p4src/p4-16/include/defines.p4 b/tools/test/p4src/p4-16/include/defines.p4
index 24974a1..ef258f6 100644
--- a/tools/test/p4src/p4-16/include/defines.p4
+++ b/tools/test/p4src/p4-16/include/defines.p4
@@ -1,10 +1,15 @@
 #ifndef DEFINES
 #define DEFINES
-// Logic ports as defined in the simple_switch target
+
 #define MAX_PORTS 254
 #define CPU_PORT 9w255
 #define DROP_PORT 9w511
-typedef bit<16> GroupId;
-typedef bit<8> GroupSize;
-typedef bit<9> Port;
+
+#define ETH_TYPE_IPV4 16w0x0800
+#define IP_TYPE_TCP 8w6
+#define IP_TYPE_UDP 8w17
+
+typedef bit<16> group_id_t;
+typedef bit<8> group_size_t;
+typedef bit<9> port_t;
 #endif
diff --git a/tools/test/p4src/p4-16/include/headers.p4 b/tools/test/p4src/p4-16/include/headers.p4
index d497370..aeca349 100644
--- a/tools/test/p4src/p4-16/include/headers.p4
+++ b/tools/test/p4src/p4-16/include/headers.p4
@@ -1,5 +1,16 @@
 #ifndef HEADERS
 #define HEADERS
+
+@controller_header("packet_in")
+header packet_in_header_t {
+    bit<9> ingress_port;
+}
+
+@controller_header("packet_out")
+header packet_out_header_t {
+    bit<9> egress_port;
+}
+
 struct intrinsic_metadata_t {
     bit<32> ingress_global_timestamp;
     bit<32> lf_field_list;
@@ -49,10 +60,12 @@
     bit<16> checksum;
 }
 
-struct headers {
+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;
 }
 #endif
diff --git a/tools/test/p4src/p4-16/include/metadata.p4 b/tools/test/p4src/p4-16/include/metadata.p4
index e08057c..a026e2d 100644
--- a/tools/test/p4src/p4-16/include/metadata.p4
+++ b/tools/test/p4src/p4-16/include/metadata.p4
@@ -2,19 +2,19 @@
 #define METADATA
 
 struct ecmp_metadata_t {
-    bit<16> groupId;
+    bit<16> group_id;
     bit<16> selector;
 }
 
-struct wcmp_meta_t {
-    bit<16> groupId;
+struct wcmp_metadata_t {
+    bit<16> group_id;
     bit<8>  numBits;
     bit<64> selector;
 }
 
-struct metadata {
+struct metadata_t {
     ecmp_metadata_t ecmp_metadata;
-    wcmp_meta_t wcmp_meta;
+    wcmp_metadata_t wcmp_meta;
     intrinsic_metadata_t intrinsic_metadata;
 }
 #endif
diff --git a/tools/test/p4src/p4-16/include/packet_io.p4 b/tools/test/p4src/p4-16/include/packet_io.p4
new file mode 100644
index 0000000..6f02e28
--- /dev/null
+++ b/tools/test/p4src/p4-16/include/packet_io.p4
@@ -0,0 +1,22 @@
+#ifndef PACKET_IO
+#define PACKET_IO
+
+control PacketIoIngressControl(inout headers_t hdr, inout standard_metadata_t standard_metadata) {
+    apply {
+        if (hdr.packet_out.isValid()) {
+            standard_metadata.egress_spec = hdr.packet_out.egress_port;
+        }
+    }
+}
+
+control PacketIoEgressControl(inout headers_t hdr, inout standard_metadata_t standard_metadata) {
+    apply {
+        hdr.packet_out.setInvalid();
+        if (standard_metadata.egress_spec == CPU_PORT) {
+            hdr.packet_in.setValid();
+            hdr.packet_in.ingress_port = standard_metadata.ingress_port;
+        }
+    }
+}
+
+#endif
\ No newline at end of file
diff --git a/tools/test/p4src/p4-16/include/parsers.p4 b/tools/test/p4src/p4-16/include/parsers.p4
index e9fbc6f..68f3876 100644
--- a/tools/test/p4src/p4-16/include/parsers.p4
+++ b/tools/test/p4src/p4-16/include/parsers.p4
@@ -3,11 +3,14 @@
 #include "headers.p4"
 #include "metadata.p4"
 
-#define ETH_TYPE_IPV4 16w0x0800
-#define IP_TYPE_TCP 8w6
-#define IP_TYPE_UDP 8w17
+parser ParserImpl(packet_in packet, out headers_t hdr, inout metadata_t meta,
+                    inout standard_metadata_t standard_metadata) {
 
-parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+    state parse_packet_out {
+        packet.extract(hdr.packet_out);
+        transition parse_ethernet;
+    }
+
     state parse_ethernet {
         packet.extract(hdr.ethernet);
         transition select(hdr.ethernet.etherType) {
@@ -36,12 +39,16 @@
     }
 
     state start {
-        transition parse_ethernet;
+        transition select(standard_metadata.ingress_port) {
+            CPU_PORT: parse_packet_out;
+            default: parse_ethernet;
+        }
     }
 }
 
-control DeparserImpl(packet_out packet, in headers hdr) {
+control DeparserImpl(packet_out packet, in headers_t hdr) {
     apply {
+        packet.emit(hdr.packet_in);
         packet.emit(hdr.ethernet);
         packet.emit(hdr.ipv4);
         packet.emit(hdr.udp);
diff --git a/tools/test/p4src/p4-16/include/port_counters.p4 b/tools/test/p4src/p4-16/include/port_counters.p4
index 90916ba..93d2b4d 100644
--- a/tools/test/p4src/p4-16/include/port_counters.p4
+++ b/tools/test/p4src/p4-16/include/port_counters.p4
@@ -2,7 +2,7 @@
 #define PORT_COUNTERS
 #include "defines.p4"
 
-control PortCountersControl(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control PortCountersControl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
     counter(MAX_PORTS, CounterType.packets) egress_port_counter;
     counter(MAX_PORTS, CounterType.packets) ingress_port_counter;
 
diff --git a/tools/test/p4src/p4-16/wcmp.p4 b/tools/test/p4src/p4-16/wcmp.p4
index 6dff6f1..3b7f6eb 100644
--- a/tools/test/p4src/p4-16/wcmp.p4
+++ b/tools/test/p4src/p4-16/wcmp.p4
@@ -6,17 +6,22 @@
 #include "include/port_counters.p4"
 #include "include/checksums.p4"
 #include "include/actions.p4"
+#include "include/packet_io.p4"
 
 #define SELECTOR_WIDTH 64
 const bit<SELECTOR_WIDTH> ONE = 64w1;
 
-control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control ingress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
+
     direct_counter(CounterType.packets) table0_counter;
     direct_counter(CounterType.packets) wcmp_group_table_counter;
 
-    action wcmp_group(GroupId groupId) {
-        meta.wcmp_meta.groupId = groupId;
-        hash(meta.wcmp_meta.numBits, HashAlgorithm.crc16, (bit<64>)2, { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort, hdr.udp.srcPort, hdr.udp.dstPort }, (bit<128>)62);
+    action wcmp_group(group_id_t group_id) {
+        meta.wcmp_meta.group_id = group_id;
+        hash(meta.wcmp_meta.numBits, HashAlgorithm.crc16, (bit<64>)2,
+        { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort, hdr.udp.srcPort,
+            hdr.udp.dstPort },
+        (bit<128>)62);
     }
 
     action wcmp_set_selector() {
@@ -45,27 +50,34 @@
             set_egress_port(standard_metadata);
         }
         key = {
-            meta.wcmp_meta.groupId : exact;
+            meta.wcmp_meta.group_id : exact;
             meta.wcmp_meta.selector: lpm;
         }
         counters = wcmp_group_table_counter;
     }
 
     PortCountersControl() port_counters_control;
+    PacketIoIngressControl() packet_io_ingress_control;
+
     apply {
-        switch (table0.apply().action_run) {
-            wcmp_group: {
-                wcmp_set_selector();
-                wcmp_group_table.apply();
+        packet_io_ingress_control.apply(hdr, standard_metadata);
+        if (!hdr.packet_out.isValid()) {
+            switch (table0.apply().action_run) {
+                wcmp_group: {
+                    wcmp_set_selector();
+                    wcmp_group_table.apply();
+                }
             }
         }
         port_counters_control.apply(hdr, meta, standard_metadata);
     }
 }
 
-control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+control egress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) {
+
+    PacketIoEgressControl() packet_io_egress_control;
     apply {
-        // Nothing to do
+        packet_io_egress_control.apply(hdr, standard_metadata);
     }
 }