[ONOS-7236] Supports simple IPv4 routing on fabric.p4
Change-Id: Ie92b26361b1d646491bd382f698c0f8f61a058a1
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractCriterionTranslator.java b/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractCriterionTranslator.java
index d403ec1..4bbb123 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractCriterionTranslator.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractCriterionTranslator.java
@@ -127,6 +127,7 @@
break;
case LPM:
mask = getMaskFromPrefixLength(prefixLength, value.size());
+ break;
default:
throw new RuntimeException("Unrecognized init type " + initType.name());
}
@@ -163,8 +164,7 @@
* @return a byte sequence
*/
private ImmutableByteSequence getMaskFromPrefixLength(int prefixLength, int maskSize) {
- // TODO: implement.
- throw new RuntimeException("getMaskFromPrefixLength() not implemented yet.");
+ return ImmutableByteSequence.prefixOnes(maskSize, prefixLength);
}
/**
@@ -175,7 +175,32 @@
* @return optional prefix length
*/
private Optional<Integer> getPrefixLengthFromMask(ImmutableByteSequence mask) {
- // TODO: implement.
- throw new RuntimeException("getPrefixLengthFromMask() not implemented yet.");
+ Integer prefixLength = 0;
+
+ byte[] byteArray = mask.asArray();
+ int byteArrayIndex = 0;
+ while (byteArrayIndex < byteArray.length && byteArray[byteArrayIndex] == (byte) 0xff) {
+ prefixLength += Byte.SIZE;
+ byteArrayIndex++;
+ }
+
+ byte byteVal = byteArray[byteArrayIndex];
+ while (byteVal != 0) {
+ if ((byteVal & Integer.MIN_VALUE) != Integer.MIN_VALUE) {
+ return Optional.empty();
+ }
+ prefixLength++;
+ byteVal <<= 1;
+ }
+
+ byteArrayIndex++;
+ while (byteArrayIndex < byteArray.length) {
+ if (byteArray[byteArrayIndex] != 0) {
+ return Optional.empty();
+ }
+ byteArrayIndex++;
+ }
+
+ return Optional.of(prefixLength);
}
}
diff --git a/core/net/src/test/java/org/onosproject/net/pi/impl/PiCriterionTranslatorsTest.java b/core/net/src/test/java/org/onosproject/net/pi/impl/PiCriterionTranslatorsTest.java
index 1938c05..ee27ef2 100644
--- a/core/net/src/test/java/org/onosproject/net/pi/impl/PiCriterionTranslatorsTest.java
+++ b/core/net/src/test/java/org/onosproject/net/pi/impl/PiCriterionTranslatorsTest.java
@@ -25,6 +25,7 @@
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
+import org.onlab.util.ImmutableByteSequence;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.criteria.ArpHaCriterion;
import org.onosproject.net.flow.criteria.ArpOpCriterion;
@@ -482,4 +483,35 @@
assertThat(exactMatch.value().asReadOnlyBuffer().get(), is(criterion.ipEcn()));
}
+
+ @Test
+ public void testLpmToTernaryTranslation() throws Exception {
+ IpPrefix ipPrefix = IpPrefix.valueOf("10.0.0.1/23");
+ int bitWidth = ipPrefix.address().toOctets().length * Byte.SIZE;
+
+ IPCriterion criterion = (IPCriterion) Criteria.matchIPDst(ipPrefix);
+ PiTernaryFieldMatch ternaryMatch =
+ (PiTernaryFieldMatch) translateCriterion(criterion, fieldId, TERNARY, bitWidth);
+
+ ImmutableByteSequence expectedMask = ImmutableByteSequence.prefixOnes(Integer.BYTES, 23);
+ ImmutableByteSequence expectedValue = ImmutableByteSequence.copyFrom(ipPrefix.address().toOctets());
+
+ assertThat(ternaryMatch.mask(), is(expectedMask));
+ assertThat(ternaryMatch.value(), is(expectedValue));
+ }
+
+ @Test
+ public void testTernaryToLpmTranslation() throws Exception {
+ EthCriterion criterion =
+ (EthCriterion) Criteria.matchEthDstMasked(MacAddress.ONOS,
+ MacAddress.IPV4_MULTICAST_MASK);
+
+ PiLpmFieldMatch lpmMatch =
+ (PiLpmFieldMatch) translateCriterion(criterion, fieldId, LPM,
+ MacAddress.MAC_ADDRESS_LENGTH * Byte.SIZE);
+ ImmutableByteSequence expectedValue = ImmutableByteSequence.copyFrom(MacAddress.ONOS.toBytes());
+
+ assertThat(lpmMatch.prefixLength(), is(25));
+ assertThat(lpmMatch.value(), is(expectedValue));
+ }
}
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 d37402d..dfd8d85 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
@@ -29,6 +29,7 @@
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.ObjectiveError;
@@ -95,6 +96,7 @@
VlanIdCriterion vlanIdCriterion = null;
EthCriterion ethDstCriterion = null;
+ IPCriterion ipDstCriterion = null;
for (Criterion criterion : criteria) {
switch (criterion.type()) {
@@ -104,6 +106,9 @@
case VLAN_VID:
vlanIdCriterion = (VlanIdCriterion) criterion;
break;
+ case IPV4_DST:
+ ipDstCriterion = (IPCriterion) criterion;
+ break;
default:
log.warn("Unsupported criterion {}", criterion);
break;
@@ -120,6 +125,8 @@
processL2BroadcastRule(vlanIdCriterion, fwd, resultBuilder);
break;
case IPV4_UNICAST:
+ processIpv4UnicastRule(ipDstCriterion, fwd, resultBuilder);
+ break;
case IPV4_MULTICAST:
case IPV6_UNICAST:
case IPV6_MULTICAST:
@@ -195,6 +202,32 @@
resultBuilder.addFlowRule(flowRule);
}
+ private void processIpv4UnicastRule(IPCriterion ipDstCriterion, ForwardingObjective fwd,
+ PipelinerTranslationResult.Builder resultBuilder) {
+ checkNotNull(ipDstCriterion, "IP dst criterion should not be null");
+ if (fwd.nextId() == null) {
+ log.warn("Forwarding objective for IPv4 unicast should contains next id");
+ resultBuilder.setError(ObjectiveError.BADPARAMS);
+ return;
+ }
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchIPDst(ipDstCriterion.ip())
+ .build();
+
+ TrafficTreatment treatment = buildSetNextIdTreatment(fwd.nextId());
+ FlowRule flowRule = DefaultFlowRule.builder()
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .fromApp(fwd.appId())
+ .withPriority(fwd.priority())
+ .makePermanent()
+ .forDevice(deviceId)
+ .forTable(FabricConstants.TBL_UNICAST_V4_ID)
+ .build();
+
+ resultBuilder.addFlowRule(flowRule);
+ }
+
private static TrafficTreatment buildSetNextIdTreatment(Integer nextId) {
PiActionParam nextIdParam = new PiActionParam(FabricConstants.ACT_PRM_NEXT_ID_ID,
ImmutableByteSequence.copyFrom(nextId.byteValue()));
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipelineTest.java b/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipelineTest.java
index d580827..0332e63 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipelineTest.java
+++ b/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipelineTest.java
@@ -157,7 +157,6 @@
}
@Test
- @Ignore
public void testIPv4Unicast() {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricNextPipelinerTest.java b/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricNextPipelinerTest.java
index 107752c..3fe196b 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricNextPipelinerTest.java
+++ b/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricNextPipelinerTest.java
@@ -66,6 +66,19 @@
testSimple(treatment);
}
+ /**
+ * Test program set mac and output rule for Simple table.
+ */
+ @Test
+ public void testSimpleOutputWithMacTranslation() {
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setEthSrc(ROUTER_MAC)
+ .setEthDst(HOST_MAC)
+ .setOutput(PORT_1)
+ .build();
+ testSimple(treatment);
+ }
+
private void testSimple(TrafficTreatment treatment) {
NextObjective nextObjective = DefaultNextObjective.builder()
.withId(NEXT_ID_1)
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeTest.java b/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeTest.java
index 9c68cd6..44ec9bc 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeTest.java
+++ b/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeTest.java
@@ -67,7 +67,6 @@
}
@Test
- @Ignore
public void testIpv4Unicast() {
selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)