Update spectrum pipeline config
Change-Id: I6d663e1a2851d812ab64cf6cb268c20914520570
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
index e3664e1..c7142bf 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
@@ -100,6 +100,11 @@
BMV2_JSON,
/**
+ * Mellanox Spectrum configuration binary.
+ */
+ SPECTRUM_BIN,
+
+ /**
* Barefoot's Tofino configuration binary.
*/
TOFINO_BIN,
diff --git a/drivers/mellanox/src/main/java/org/onosproject/drivers/mellanox/SpectrumPipelineProgrammable.java b/drivers/mellanox/src/main/java/org/onosproject/drivers/mellanox/SpectrumPipelineProgrammable.java
index c13ab77..d421be4 100644
--- a/drivers/mellanox/src/main/java/org/onosproject/drivers/mellanox/SpectrumPipelineProgrammable.java
+++ b/drivers/mellanox/src/main/java/org/onosproject/drivers/mellanox/SpectrumPipelineProgrammable.java
@@ -16,17 +16,21 @@
package org.onosproject.drivers.mellanox;
+import org.apache.commons.io.IOUtils;
import org.onosproject.drivers.p4runtime.AbstractP4RuntimePipelineProgrammable;
import org.onosproject.net.behaviour.PiPipelineProgrammable;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipeconfId;
+import org.onosproject.net.pi.model.PiPipeconf.ExtensionType;
import org.onosproject.net.pi.service.PiPipeconfService;
+import java.io.IOException;
+
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.Optional;
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.lang.String.format;
+import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.SPECTRUM_BIN;
/**
* Implementation of the PiPipelineProgrammable behaviour for a Spectrum-based
@@ -36,23 +40,48 @@
extends AbstractP4RuntimePipelineProgrammable
implements PiPipelineProgrammable {
- private static final PiPipeconfId FABRIC_PIPECONF_ID =
- new PiPipeconfId("org.onosproject.pipelines.fabric");
+ private static final PiPipeconfId MLNX_FABRIC_PIPECONF_ID =
+ new PiPipeconfId("org.onosproject.pipelines.fabric-mlnx");
@Override
public ByteBuffer createDeviceDataBuffer(PiPipeconf pipeconf) {
- checkArgument(pipeconf.id().equals(FABRIC_PIPECONF_ID),
- format("Cannot program Spectrum device with a pipeconf " +
- "other than '%s' (found '%s')",
- FABRIC_PIPECONF_ID, pipeconf.id()));
- // Dummy value.
- // We assume switch to be already configured with fabric.p4 profile.
- return ByteBuffer.allocate(1).put((byte) 1);
+ log.debug("Creating device data buffer for {} in pipeconf {}", SPECTRUM_BIN, pipeconf.id());
+ ByteBuffer deviceData;
+ try {
+ deviceData = extensionBuffer(pipeconf, SPECTRUM_BIN);
+ } catch (ExtensionException e) {
+ log.error("Failed to create device data buffer for {} in pipeconf {}", SPECTRUM_BIN, pipeconf.id());
+ return null;
+ }
+ // flip buffer data so they can be read
+ deviceData.flip();
+ return deviceData.asReadOnlyBuffer();
}
@Override
public Optional<PiPipeconf> getDefaultPipeconf() {
return handler().get(PiPipeconfService.class)
- .getPipeconf(FABRIC_PIPECONF_ID);
+ .getPipeconf(MLNX_FABRIC_PIPECONF_ID);
+ }
+
+ private ByteBuffer extensionBuffer(PiPipeconf pipeconf, ExtensionType extType) {
+ if (!pipeconf.extension(extType).isPresent()) {
+ log.warn("Missing extension {} in pipeconf {}", extType, pipeconf.id());
+ throw new ExtensionException();
+ }
+ try {
+ byte[] bytes = IOUtils.toByteArray(pipeconf.extension(extType).get());
+ // Length of the extension + bytes.
+ return ByteBuffer.allocate(bytes.length)
+ .order(ByteOrder.LITTLE_ENDIAN)
+ .put(bytes);
+ } catch (IOException ex) {
+ log.warn("Unable to read extension {} from pipeconf {}: {}",
+ extType, pipeconf.id(), ex.getMessage());
+ throw new ExtensionException();
+ }
+ }
+
+ private static class ExtensionException extends IllegalArgumentException {
}
}
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/PipeconfLoader.java b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/PipeconfLoader.java
index 1609794..cac245c 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/PipeconfLoader.java
+++ b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/PipeconfLoader.java
@@ -71,12 +71,14 @@
private static final String P4C_RES_BASE_PATH = P4C_OUT_PATH + "/%s/%s/%s/";
private static final String SEP = File.separator;
+ private static final String SPECTRUM = "spectrum";
private static final String TOFINO = "tofino";
private static final String BMV2 = "bmv2";
private static final String DEFAULT_PLATFORM = "default";
private static final String BMV2_JSON = "bmv2.json";
private static final String P4INFO_TXT = "p4info.txt";
private static final String CPU_PORT_TXT = "cpu_port.txt";
+ private static final String SPECTRUM_BIN = "spectrum.bin";
private static final String TOFINO_BIN = "tofino.bin";
private static final String TOFINO_CTX_JSON = "context.json";
private static final String INT_PROFILE_SUFFIX = "-int";
@@ -133,6 +135,9 @@
case BMV2:
pipeconfBuilder = bmv2Pipeconf(profile, platform);
break;
+ case SPECTRUM:
+ pipeconfBuilder = spectrumPipeconf(profile, platform);
+ break;
case TOFINO:
pipeconfBuilder = tofinoPipeconf(profile, platform);
break;
@@ -177,6 +182,28 @@
.addExtension(ExtensionType.BMV2_JSON, bmv2JsonUrl);
}
+ private static DefaultPiPipeconf.Builder spectrumPipeconf(String profile, String platform)
+ throws FileNotFoundException {
+ final URL spectrumBinUrl = PipeconfLoader.class.getResource(format(
+ P4C_RES_BASE_PATH + SPECTRUM_BIN, profile, SPECTRUM, platform));
+ final URL p4InfoUrl = PipeconfLoader.class.getResource(format(
+ P4C_RES_BASE_PATH + P4INFO_TXT, profile, SPECTRUM, platform));
+ final URL cpuPortUrl = PipeconfLoader.class.getResource(format(
+ P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, SPECTRUM, platform));
+ if (spectrumBinUrl == null) {
+ throw new FileNotFoundException(SPECTRUM_BIN);
+ }
+ if (p4InfoUrl == null) {
+ throw new FileNotFoundException(P4INFO_TXT);
+ }
+ if (cpuPortUrl == null) {
+ throw new FileNotFoundException(CPU_PORT_TXT);
+ }
+ return basePipeconfBuilder(
+ profile, platform, p4InfoUrl, cpuPortUrl)
+ .addExtension(ExtensionType.SPECTRUM_BIN, spectrumBinUrl);
+ }
+
private static DefaultPiPipeconf.Builder tofinoPipeconf(
String profile, String platform)
throws FileNotFoundException {
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-mlnx/spectrum/default/README.md b/pipelines/fabric/src/main/resources/p4c-out/fabric-mlnx/spectrum/default/README.md
new file mode 100644
index 0000000..b3611d3
--- /dev/null
+++ b/pipelines/fabric/src/main/resources/p4c-out/fabric-mlnx/spectrum/default/README.md
@@ -0,0 +1,18 @@
+# Running ONOS with Mellanox Spectrum/Spectrum2 Switches
+
+## Spectrum and Fabric.p4
+The Spectrum architecture supports the fabric.p4 pipeline, but using the spectrum_model.p4 instead of the v1model.p4.
+The folder location p4c-out/fabric-mlnx/spectrum/default is where the P4 compiler artifacts should be placed for
+ONOS to properly load and configure the pipeline for the Spectrum switch.
+These files include:
+
+* cpu_port.txt: defines the SDN port number to be used when sending a packet to the controller
+* p4info.txt: the P4Runtime output file, in protobuf text format, when compiling fabric.p4
+* spectrum.bin: The "binary blob" P4 compiler output, which contains all the data necessary to reconfigure the
+ switch pipeline (P4 device config, as described in the P4Runtime specification)
+
+Since at this time the Mellanox P4 compiler backend is under active development and is not currently open sourced,
+please contact your Mellanox representative for access to the compiler and/or the compiler artifacts described above.
+
+For the latest details, please take a look at the wiki page instructions:
+https://wiki.onosproject.org/display/ONOS/Controlling+P4Runtime-enabled+Mellanox+Spectrum+switch+with+ONOS