Convert default routes to two table entries in fabric.p4 pipeliner

This is a workaround to the still brittle support for default actions
in P4Runtime.

Change-Id: I6d2e76df2519eb2660b793a3fb213387fb388ce6
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipeliner.java b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipeliner.java
index 580d398..a3d3926 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipeliner.java
+++ b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipeliner.java
@@ -17,6 +17,7 @@
 package org.onosproject.pipelines.fabric.pipeliner;
 
 import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onosproject.net.DeviceId;
@@ -224,13 +225,21 @@
     private void processIpv4RoutingRule(IPCriterion ipDstCriterion, ForwardingObjective fwd,
                                         PipelinerTranslationResult.Builder resultBuilder) {
         checkNotNull(ipDstCriterion, "IP dst criterion should not be null");
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchIPDst(ipDstCriterion.ip())
-                .build();
+
+        if (ipDstCriterion.ip().prefixLength() == 0) {
+            setDefaultIpv4Route(fwd, resultBuilder);
+            return;
+        }
+
+        final TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(ipDstCriterion.ip())
+                    .build();
+
         TrafficTreatment treatment = fwd.treatment();
         if (fwd.nextId() != null) {
-            treatment = buildSetNextIdTreatment(fwd.nextId(),
-                                                FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V4);
+            treatment = buildSetNextIdTreatment(
+                    fwd.nextId(),
+                    FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V4);
         }
         FlowRule flowRule = DefaultFlowRule.builder()
                 .withSelector(selector)
@@ -245,6 +254,35 @@
         resultBuilder.addFlowRule(flowRule);
     }
 
+    private void setDefaultIpv4Route(ForwardingObjective fwd,
+                                     PipelinerTranslationResult.Builder resultBuilder) {
+        final TrafficSelector selector1 = DefaultTrafficSelector.builder()
+                .matchIPDst(IpPrefix.valueOf("0.0.0.0/1")).build();
+        final TrafficSelector selector2 = DefaultTrafficSelector.builder()
+                .matchIPDst(IpPrefix.valueOf("128.0.0.0/1")).build();
+
+        TrafficTreatment treatment = fwd.treatment();
+        if (fwd.nextId() != null) {
+            treatment = buildSetNextIdTreatment(
+                    fwd.nextId(),
+                    FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V4);
+        }
+
+        for (TrafficSelector selector : new TrafficSelector[]{selector1, selector2}) {
+            FlowRule rule = DefaultFlowRule.builder()
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .fromApp(fwd.appId())
+                    .withPriority(0)
+                    .makePermanent()
+                    .forDevice(deviceId)
+                    .forTable(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4)
+                    .build();
+
+            resultBuilder.addFlowRule(rule);
+        }
+    }
+
     private void processMplsRule(MplsCriterion mplsCriterion, ForwardingObjective fwd,
                                  PipelinerTranslationResult.Builder resultBuilder) {
         checkNotNull(mplsCriterion, "Mpls criterion should not be null");