Add stratum-tofino driver

This patch also introduces a new driver property flag to indicate
whether a P4Runtime target supports default table entries or not.
Stratum targets built against the current version of p4lang/PI do not.

Change-Id: I1fbb57521516bee99057319ed1695cb05b68ee7c
diff --git a/drivers/barefoot/BUILD b/drivers/barefoot/BUILD
index f86f1e3..ee63540 100644
--- a/drivers/barefoot/BUILD
+++ b/drivers/barefoot/BUILD
@@ -15,9 +15,10 @@
 onos_app(
     app_name = "org.onosproject.drivers.barefoot",
     category = "Drivers",
-    description = "Adds support for Barefoot Networks devices",
+    description = "Adds support for switches based on Barefoot Networks ASICs",
     included_bundles = BUNDLES,
     required_apps = [
+        "org.onosproject.drivers.stratum",
         "org.onosproject.drivers.p4runtime",
     ],
     title = "Barefoot Drivers",
diff --git a/drivers/barefoot/src/main/resources/barefoot-drivers.xml b/drivers/barefoot/src/main/resources/barefoot-drivers.xml
index 68c9aec..d712fb4 100644
--- a/drivers/barefoot/src/main/resources/barefoot-drivers.xml
+++ b/drivers/barefoot/src/main/resources/barefoot-drivers.xml
@@ -15,10 +15,21 @@
   ~ limitations under the License.
   -->
 <drivers>
-    <driver name="barefoot" manufacturer="Barefoot Networks" hwVersion="1.0" swVersion="1.0" extends="p4runtime">
+    <driver name="barefoot" manufacturer="Barefoot Networks" hwVersion="1.0"
+            swVersion="1.0" extends="p4runtime">
         <behaviour api="org.onosproject.net.behaviour.PiPipelineProgrammable"
                    impl="org.onosproject.drivers.barefoot.TofinoPipelineProgrammable"/>
         <property name="tableDeleteBeforeUpdate">true</property>
     </driver>
+
+    <driver name="stratum-tofino" manufacturer="Barefoot Networks"
+            hwVersion="Tofino" swVersion="Stratum" extends="stratum">
+        <behaviour api="org.onosproject.net.behaviour.PiPipelineProgrammable"
+                   impl="org.onosproject.drivers.barefoot.TofinoPipelineProgrammable"/>
+        <!-- The current version of p4lang/PI used in Stratum does not
+        support reading default  table entries -->
+        <property name="supportDefaultTableEntry">false</property>
+    </driver>
+
 </drivers>
 
diff --git a/drivers/bmv2/src/main/resources/bmv2-drivers.xml b/drivers/bmv2/src/main/resources/bmv2-drivers.xml
index 9638f9f..0672f73 100644
--- a/drivers/bmv2/src/main/resources/bmv2-drivers.xml
+++ b/drivers/bmv2/src/main/resources/bmv2-drivers.xml
@@ -31,6 +31,9 @@
             hwVersion="BMv2 simple_switch" swVersion="Stratum" extends="stratum">
         <behaviour api="org.onosproject.net.behaviour.PiPipelineProgrammable"
                    impl="org.onosproject.drivers.bmv2.Bmv2PipelineProgrammable"/>
+        <!-- The current version of p4lang/PI used in Stratum does not
+        support reading default table entries -->
+        <property name="supportDefaultTableEntry">false</property>
     </driver>
 </drivers>
 
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
index 8a1f99a..e0e5c1d 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeFlowRuleProgrammable.java
@@ -95,11 +95,9 @@
     private static final String READ_COUNTERS_WITH_TABLE_ENTRIES = "tableReadCountersWithTableEntries";
     private static final boolean DEFAULT_READ_COUNTERS_WITH_TABLE_ENTRIES = true;
 
-    // For default entries, P4Runtime mandates that only MODIFY messages are
-    // allowed. If true, treats default entries as normal table entries,
-    // e.g. inserting them first.
-    private static final String TABLE_DEFAULT_AS_ENTRY = "tableDefaultAsEntry";
-    private static final boolean DEFAULT_TABLE_DEFAULT_AS_ENTRY = false;
+    // True if target supports reading and writing table entries.
+    private static final String SUPPORT_DEFAULT_TABLE_ENTRY = "supportDefaultTableEntry";
+    private static final boolean DEFAULT_SUPPORT_DEFAULT_TABLE_ENTRY = true;
 
     // Used to make sure concurrent calls to write flow rules are serialized so
     // that each request gets consistent access to mirror state.
@@ -204,7 +202,9 @@
                 .filter(t -> !t.isConstantTable())
                 .forEach(t -> {
                     request.tableEntries(t.id());
-                    if (!t.constDefaultAction().isPresent()) {
+                    if (driverBoolProperty(SUPPORT_DEFAULT_TABLE_ENTRY,
+                                           DEFAULT_SUPPORT_DEFAULT_TABLE_ENTRY) &&
+                            !t.constDefaultAction().isPresent()) {
                         request.defaultTableEntry(t.id());
                     }
                 });
@@ -396,15 +396,15 @@
         final TimedEntry<PiTableEntry> piEntryOnDevice = tableMirror.get(handle);
         final UpdateType updateType;
 
-        final boolean defaultAsEntry = driverBoolProperty(
-                TABLE_DEFAULT_AS_ENTRY, DEFAULT_TABLE_DEFAULT_AS_ENTRY);
+        final boolean supportDefaultEntry = driverBoolProperty(
+                SUPPORT_DEFAULT_TABLE_ENTRY, DEFAULT_SUPPORT_DEFAULT_TABLE_ENTRY);
         final boolean deleteBeforeUpdate = driverBoolProperty(
                 DELETE_BEFORE_UPDATE, DEFAULT_DELETE_BEFORE_UPDATE);
 
         if (driverOperation == APPLY) {
             if (piEntryOnDevice == null) {
                 // Entry is first-timer, INSERT or MODIFY if default action.
-                updateType = !piEntryToApply.isDefaultAction() || defaultAsEntry
+                updateType = !piEntryToApply.isDefaultAction() || !supportDefaultEntry
                         ? INSERT : MODIFY;
             } else {
                 if (piEntryToApply.action().equals(piEntryOnDevice.entry().action())) {