Add ability for vRouter to reactively send packets to directly connected hosts.
Change-Id: I652ad33acf95b5ef5806699135382d8be1260781
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/SoftRouterPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/SoftRouterPipeline.java
index 4618bb0..66d0b53 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/SoftRouterPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/SoftRouterPipeline.java
@@ -16,6 +16,7 @@
package org.onosproject.driver.pipeline;
import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.EthType;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.VlanId;
@@ -23,6 +24,7 @@
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.NextGroup;
import org.onosproject.net.behaviour.Pipeliner;
import org.onosproject.net.behaviour.PipelinerContext;
@@ -336,6 +338,16 @@
+ "nextId or Treatment", fwd.selector(), fwd.appId());
return Collections.emptySet();
}
+
+ int tableId = FILTER_TABLE;
+
+ // A punt rule for IP traffic should be directed to the FIB table
+ // so that it only takes effect if the packet misses the FIB rules
+ if (fwd.treatment() != null && containsPunt(fwd.treatment()) &&
+ fwd.selector() != null && matchesIp(fwd.selector())) {
+ tableId = FIB_TABLE;
+ }
+
TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
if (fwd.treatment() != null) {
fwd.treatment().immediate().forEach(ins -> ttBuilder.add(ins));
@@ -363,6 +375,7 @@
FlowRule rule = DefaultFlowRule.builder()
.withSelector(fwd.selector())
.withTreatment(ttBuilder.build())
+ .forTable(tableId)
.makePermanent()
.forDevice(deviceId)
.fromApp(fwd.appId())
@@ -374,6 +387,17 @@
return flowrules;
}
+ private boolean containsPunt(TrafficTreatment treatment) {
+ return treatment.immediate().stream()
+ .anyMatch(i -> i.type().equals(Instruction.Type.OUTPUT)
+ && ((OutputInstruction) i).port().equals(PortNumber.CONTROLLER));
+ }
+
+ private boolean matchesIp(TrafficSelector selector) {
+ EthTypeCriterion c = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
+ return c != null && c.ethType().equals(EthType.EtherType.IPV4.ethType());
+ }
+
/**
* SoftRouter has a single specific table - the FIB Table. It emulates
* LPM matching of dstIP by using higher priority flows for longer prefixes.