ONOS-6464 interfaces for protocol-independence (PI)
And also ONOS-6553, implementation of table entry classes
Change-Id: Ia7146b1bb0aac794e19b3fd8150c042e7ec70535
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
index a8aba57..f4ea830 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
@@ -21,7 +21,7 @@
*/
public interface Criterion {
- static final String SEPARATOR = ":";
+ String SEPARATOR = ":";
/**
* Types of fields to which the selection criterion may apply.
@@ -217,6 +217,9 @@
/** ODU (Optical channel Data Unit) signal type. */
ODU_SIGTYPE,
+ /** Protocol-independent. */
+ PROTOCOL_INDEPENDENT,
+
/** Extension criterion. */
EXTENSION,
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/PiCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/PiCriterion.java
new file mode 100644
index 0000000..ab05f26
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/PiCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.criteria;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.runtime.PiFieldMatch;
+
+import java.util.Collection;
+import java.util.StringJoiner;
+
+/**
+ * Protocol-indepedent criterion.
+ */
+@Beta
+public final class PiCriterion implements Criterion {
+
+ private final Collection<PiFieldMatch> fieldMatches;
+
+ /**
+ * Creates a new protocol-independent criterion for the given match fields.
+ *
+ * @param fieldMatches fields to match
+ */
+ PiCriterion(Collection<PiFieldMatch> fieldMatches) {
+ this.fieldMatches = fieldMatches;
+ }
+
+ /**
+ * Returns the match parameters map of this selector.
+ *
+ * @return a match parameter map
+ */
+ public Collection<PiFieldMatch> fieldMatches() {
+ return fieldMatches;
+ }
+
+ @Override
+ public Type type() {
+ return Type.PROTOCOL_INDEPENDENT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiCriterion that = (PiCriterion) o;
+ return Objects.equal(fieldMatches, that.fieldMatches);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(fieldMatches);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "{", "}");
+ fieldMatches.forEach(f -> stringParams.add(f.toString()));
+ return stringParams.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
index 5c0353a..1aeb1d2 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
@@ -89,6 +89,11 @@
L4MODIFICATION,
/**
+ * Signifies that a protocol-independent instruction will be used.
+ */
+ PROTOCOL_INDEPENDENT,
+
+ /**
* Signifies that an extension instruction will be used.
*/
EXTENSION
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/PiInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/PiInstruction.java
new file mode 100644
index 0000000..da6230a
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/PiInstruction.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.instructions;
+
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.runtime.PiTableAction;
+
+/**
+ * Representation of a protocol-independent instruction.
+ */
+@Beta
+public final class PiInstruction implements Instruction {
+
+ private final PiTableAction tableAction;
+
+ /**
+ * Creates a new instruction with the given protocol-independent table action.
+ *
+ * @param tableAction a protocol-independent action
+ */
+ PiInstruction(PiTableAction tableAction) {
+ this.tableAction = tableAction;
+ }
+
+ /**
+ * Returns the protocol-independent table action defined by this instruction.
+ *
+ * @return an action
+ */
+ public PiTableAction action() {
+ return tableAction;
+ }
+
+ @Override
+ public Type type() {
+ return Type.PROTOCOL_INDEPENDENT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiInstruction that = (PiInstruction) o;
+ return Objects.equal(tableAction, that.tableAction);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(tableAction);
+ }
+
+ @Override
+ public String toString() {
+ return tableAction.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionModel.java
new file mode 100644
index 0000000..775c3d8
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionModel.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Model of an action with runtime parameters in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiActionModel {
+ /**
+ * Returns the name of this action.
+ *
+ * @return a string value
+ */
+ String name();
+
+ /**
+ * Returns the model of this action's parameter defined by the given name, if present.
+ *
+ * @param name action name
+ * @return action parameter model
+ */
+ Optional<PiActionParamModel> param(String name);
+
+ /**
+ * Returns the list of action parameter models, ordered according to the same action parameters
+ * defined in the pipeline model.
+ *
+ * @return list of action parameter models
+ */
+ List<PiActionParamModel> params();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamModel.java
new file mode 100644
index 0000000..ff6d4de
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamModel.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Model of an action parameter in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiActionParamModel {
+ /**
+ * Returns the name of this action parameter.
+ *
+ * @return a string value
+ */
+ String name();
+
+ /**
+ * Return the bit width of this action parameter.
+ *
+ * @return an integer value
+ */
+ int bitWidth();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldModel.java
new file mode 100644
index 0000000..c52a71d
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldModel.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Model of a header's field instance in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiHeaderFieldModel {
+ /**
+ * Returns the header instance of this field instance.
+ *
+ * @return a header instance
+ */
+ PiHeaderModel header();
+
+ /**
+ * Returns the type of this header's field instance.
+ *
+ * @return a field type value
+ */
+ PiHeaderFieldTypeModel type();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
new file mode 100644
index 0000000..0a3854e
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Model of a header's field type in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiHeaderFieldTypeModel {
+ /**
+ * Returns the name of this header type field.
+ *
+ * @return a string value
+ */
+ String name();
+
+ /**
+ * Returns the bit width of this header type field.
+ *
+ * @return an integer value
+ */
+ int bitWidth();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderModel.java
new file mode 100644
index 0000000..28148c1
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderModel.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Model of a header instance in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiHeaderModel {
+ /**
+ * Returns the type of this header instance.
+ *
+ * @return a header type value
+ */
+ PiHeaderTypeModel type();
+
+ /**
+ * Returns true if this header instance is a metadata, false elsewhere.
+ *
+ * @return a boolean value
+ */
+ boolean isMetadata();
+
+ /**
+ * Returns the index of this header w.r.t. to other headers of the same type.
+ * Index 0 points to the first instance of the header, 1 the second one, etc.
+ * Helpful when dealing with stacked headers. e.g. to match on the second MPLS label.
+ *
+ * @return a non-negative integer value
+ */
+ default int index() {
+ return 0;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderTypeModel.java
new file mode 100644
index 0000000..d35f78a
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderTypeModel.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Model of a header type in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiHeaderTypeModel {
+
+ /**
+ * Returns the name of this header type.
+ *
+ * @return name
+ */
+ String name();
+
+ /**
+ * Returns the field type model defined by the given name, if present.
+ *
+ * @param fieldName field name
+ * @return optional field type model
+ */
+ Optional<PiHeaderFieldTypeModel> field(String fieldName);
+
+ /**
+ * Returns a list of field type models for this header type, ordered according to the same
+ * order of header fields as defined in the pipeline model.
+ *
+ * @return list of field type models
+ */
+ List<PiHeaderFieldTypeModel> fields();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchType.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchType.java
new file mode 100644
index 0000000..d88852b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchType.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Match types in a protocol-independent pipeline.
+ */
+@Beta
+public enum PiMatchType {
+ /**
+ * Exact match type.
+ */
+ EXACT,
+ /**
+ * Ternary match type.
+ */
+ TERNARY,
+ /**
+ * Longest-prefix match type.
+ */
+ LPM,
+ /**
+ * Valid match type.
+ */
+ VALID,
+ /**
+ * Range match type.
+ */
+ RANGE
+}
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
new file mode 100644
index 0000000..385c490
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.Behaviour;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * Configuration of a protocol-independent pipeline that includes a pipeline model, a collection of
+ * pipeline-specific behaviours implementation, and extensions.
+ */
+@Beta
+public interface PiPipeconf {
+
+ /**
+ * Returns the identifier of this pipeline configuration.
+ *
+ * @return a identifier
+ */
+ PiPipeconfId id();
+
+ /**
+ * Returns the pipeline model.
+ *
+ * @return a pipeline model
+ */
+ PiPipelineModel pipelineModel();
+
+ /**
+ * Returns all pipeline-specific behaviours defined by this configuration.
+ *
+ * @return a collection of behaviours
+ */
+ Collection<Class<? extends Behaviour>> behaviours();
+
+ /**
+ * Returns the implementation class for the given behaviour, if present.
+ *
+ * @param behaviour behaviour interface
+ * @return implementation class
+ */
+ Optional<Class<? extends Behaviour>> implementation(Class<? extends Behaviour> behaviour);
+
+ /**
+ * Indicates whether or not the pipeconf supports the specified class of behaviour.
+ *
+ * @param behaviourClass behaviour class
+ * @return true if behaviour is supported
+ */
+ boolean hasBehaviour(Class<? extends Behaviour> behaviourClass);
+
+ /**
+ * Returns, if present, an arbitrary sequence of bytes representing a device-specific or control
+ * protocol-specific extension of this configuration. For example, if requesting a
+ * target-specific P4 binary, this will return the same bytes produced by the P4 compiler.
+ *
+ * @param type extension type
+ * @return extension bytes
+ */
+ // FIXME: this is a sloppy way of handling extensions.
+ Optional<ByteBuffer> extension(ExtensionType type);
+
+ /**
+ * Type of extension of a protocol-independent pipeline configuration.
+ */
+ enum ExtensionType {
+ /**
+ * The P4Info as returned by the p4c compiler (in binary format).
+ */
+ P4_INFO_BINARY,
+
+ /**
+ * BMv2 JSON configuration.
+ */
+ BMV2_JSON
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconfId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconfId.java
new file mode 100644
index 0000000..fccf9a7
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconfId.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+/**
+ * An identifier of a protocol-independent pipeline configuration.
+ */
+@Beta
+public final class PiPipeconfId extends Identifier<String> {
+
+ /**
+ * Creates a pipeline configuration identifier.
+ *
+ * @param pipeconfId configuration identifier
+ */
+ public PiPipeconfId(String pipeconfId) {
+ super(pipeconfId);
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
new file mode 100644
index 0000000..443c15b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.pi.runtime.PiHeaderFieldId;
+import org.onosproject.net.pi.runtime.PiTableAction;
+
+import java.util.Optional;
+
+/**
+ * An interpreter of a protocol-independent pipeline.
+ */
+@Beta
+public interface PiPipelineInterpreter extends HandlerBehaviour {
+
+ /**
+ * Returns the protocol-independent header field identifier that is equivalent to the given
+ * criterion type, if present. If not present, it means that the given criterion type is not
+ * supported by this interpreter.
+ *
+ * @param type criterion type
+ * @return optional header field identifier
+ */
+ Optional<PiHeaderFieldId> mapCriterionType(Criterion.Type type);
+
+ /**
+ * Returns the criterion type that is equivalent to the given protocol-independent header field
+ * identifier, if present. If not present, it means that the given field identifier is not
+ * supported by this interpreter.
+ *
+ * @param headerFieldId header field identifier
+ * @return optional criterion type
+ */
+ Optional<Criterion.Type> mapPiHeaderFieldId(PiHeaderFieldId headerFieldId);
+
+ /**
+ * Returns a table action of a protocol-independent pipeline that is functionally equivalent to
+ * the given ONOS traffic treatment for the given pipeline configuration.
+ *
+ * @param treatment a ONOS traffic treatment
+ * @param pipeconf a pipeline configuration
+ * @return a table action object
+ * @throws PiInterpreterException if the treatment cannot be mapped to any table action
+ */
+ PiTableAction mapTreatment(TrafficTreatment treatment, PiPipeconf pipeconf)
+ throws PiInterpreterException;
+
+ /**
+ * Signals that an error was encountered while executing the interpreter.
+ */
+ @Beta
+ class PiInterpreterException extends Exception {
+ public PiInterpreterException(String message) {
+ super(message);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java
new file mode 100644
index 0000000..7a9b5bf
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * Model of a protocol-independent pipeline.
+ */
+@Beta
+public interface PiPipelineModel {
+
+ /**
+ * Returns the header type associated with the given name, if present.
+ *
+ * @param name string value
+ * @return optional header type model
+ */
+ Optional<PiHeaderTypeModel> headerType(String name);
+
+ /**
+ * Returns the collection of all header types defined by this pipeline model.
+ *
+ * @return collection of header types
+ */
+ Collection<PiHeaderTypeModel> headerTypes();
+
+ /**
+ * Returns the header instance associated with the given name, if present.
+ *
+ * @param name string value
+ * @return optional header instance model
+ */
+ Optional<PiHeaderModel> header(String name);
+
+ /**
+ * Returns the collection of all header instance models defined by this pipeline model.
+ *
+ * @return collection of header types
+ */
+ Collection<PiHeaderModel> headers();
+
+ /**
+ * Returns the action model associated with the given name, if present.
+ *
+ * @param name string value
+ * @return optional action model
+ */
+ Optional<PiActionModel> action(String name);
+
+ /**
+ * Returns the collection of all action models defined by this pipeline model.
+ *
+ * @return collection of actions
+ */
+ Collection<PiActionModel> actions();
+
+ /**
+ * Returns the table model associated with the given name, if present.
+ *
+ * @param name string value
+ * @return optional table model
+ */
+ Optional<PiTableModel> table(String name);
+
+ /**
+ * Returns the collection of all table models defined by this pipeline model.
+ *
+ * @return collection of actions
+ */
+ Collection<PiTableModel> tables();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableMatchFieldModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableMatchFieldModel.java
new file mode 100644
index 0000000..bc69a86
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableMatchFieldModel.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Model of a table match field in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiTableMatchFieldModel {
+ /**
+ * Returns the match type of this key.
+ *
+ * @return a match type
+ */
+ PiMatchType matchType();
+
+ /**
+ * Returns the header field instance matched by this key.
+ *
+ * @return a header field value
+ */
+ PiHeaderFieldModel field();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java
new file mode 100644
index 0000000..420b5f6
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+import java.util.Collection;
+
+/**
+ * Model of a match+action table in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiTableModel {
+
+ /**
+ * Returns the name of this table.
+ *
+ * @return a string value
+ */
+ String name();
+
+ /**
+ * Returns the maximum number of entries supported by this table.
+ *
+ * @return an integer value
+ */
+ int maxSize();
+
+ /**
+ * Returns true if this table has counters, false otherwise.
+ *
+ * @return a boolean value
+ */
+ boolean hasCounters();
+
+ /**
+ * Returns true if this table supports aging, false otherwise.
+ *
+ * @return a boolean value
+ */
+ boolean supportsAging();
+
+ /**
+ * Returns the collection of match fields supported by this table.
+ *
+ * @return a collection of match field models
+ */
+ Collection<PiTableMatchFieldModel> matchFields();
+
+ /**
+ * Returns the actions supported by this table.
+ *
+ * @return a collection of action models
+ */
+ Collection<PiActionModel> actions();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/package-info.java b/core/api/src/main/java/org/onosproject/net/pi/model/package-info.java
new file mode 100644
index 0000000..eabd18d
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Base abstractions of a protocol-independent packet forwarding pipeline.
+ */
+package org.onosproject.net.pi.model;
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiAction.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiAction.java
new file mode 100644
index 0000000..24a7fbe
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiAction.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onlab.util.ImmutableByteSequence;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.StringJoiner;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Instance of an action, and its runtime parameters, of a table entry in a protocol-independent
+ * pipeline.
+ */
+@Beta
+public final class PiAction implements PiTableAction {
+
+ private final PiActionId actionId;
+ private final List<ImmutableByteSequence> runtimeParams;
+
+ /**
+ * Creates a new action instance for the given action identifier and runtime parameters.
+ *
+ * @param actionId action identifier
+ * @param runtimeParams list of runtime parameters
+ */
+ public PiAction(PiActionId actionId, List<ImmutableByteSequence> runtimeParams) {
+ this.actionId = checkNotNull(actionId);
+ this.runtimeParams = ImmutableList.copyOf(checkNotNull(runtimeParams));
+ }
+
+ /**
+ * Creates a new action instance for the given action identifier, with no runtime parameters.
+ *
+ * @param actionId action identifier
+ */
+ public PiAction(PiActionId actionId) {
+ this(actionId, Collections.emptyList());
+ }
+
+ @Override
+ public Type type() {
+ return Type.ACTION;
+ }
+
+ /**
+ * Return the identifier of this action.
+ *
+ * @return action identifier
+ */
+ public PiActionId id() {
+ return actionId;
+ }
+
+ /**
+ * Returns an immutable view of the list of parameters of this action.
+ * Return an empty list if the action doesn't take any runtime parameters.
+ *
+ * @return list of byte sequences
+ */
+ public List<ImmutableByteSequence> parameters() {
+ return runtimeParams;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiAction piAction = (PiAction) o;
+ return Objects.equal(actionId, piAction.actionId) &&
+ Objects.equal(runtimeParams, piAction.runtimeParams);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(actionId, runtimeParams);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.parameters().forEach(p -> stringParams.add(p.toString()));
+ return MoreObjects.toStringHelper(this)
+ .addValue(this.id().toString() + stringParams.toString())
+ .toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiActionId.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiActionId.java
new file mode 100644
index 0000000..ae17071
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiActionId.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+/**
+ * Identifier of an action of a match+action table in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiActionId extends Identifier<String> {
+
+ /**
+ * Creates an action identifier.
+ *
+ * @param name action name
+ */
+ public PiActionId(String name) {
+ super(name);
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiExactFieldMatch.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiExactFieldMatch.java
new file mode 100644
index 0000000..50bffa6
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiExactFieldMatch.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchType;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Exact field match in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiExactFieldMatch extends PiFieldMatch {
+
+ private final ImmutableByteSequence value;
+
+ /**
+ * Creates an exact field match.
+ *
+ * @param fieldId field identifier
+ * @param value value
+ */
+ public PiExactFieldMatch(PiHeaderFieldId fieldId, ImmutableByteSequence value) {
+ super(fieldId);
+ this.value = checkNotNull(value);
+ checkArgument(value.size() > 0, "Value can't have size 0");
+ }
+
+ @Override
+ public PiMatchType type() {
+ return PiMatchType.EXACT;
+ }
+
+ /**
+ * Returns the byte sequence value to be matched.
+ *
+ * @return an immutable byte sequence
+ */
+ public ImmutableByteSequence value() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiExactFieldMatch that = (PiExactFieldMatch) o;
+ return Objects.equal(this.fieldId(), that.fieldId()) &&
+ Objects.equal(value, that.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.fieldId(), value);
+ }
+
+ @Override
+ public String toString() {
+ return this.fieldId().toString() + "=" + value.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiFieldMatch.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiFieldMatch.java
new file mode 100644
index 0000000..04d66c4
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiFieldMatch.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import org.onosproject.net.pi.model.PiMatchType;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Header's field match in a protocol-independent pipeline.
+ */
+public abstract class PiFieldMatch {
+
+ private final PiHeaderFieldId fieldId;
+
+ /**
+ * Creates a new field match for the given header field identifier.
+ *
+ * @param fieldId field identifier.
+ */
+ PiFieldMatch(PiHeaderFieldId fieldId) {
+ this.fieldId = checkNotNull(fieldId);
+ }
+
+
+ /**
+ * Returns the identifier of the field to be matched.
+ *
+ * @return a header field ID value
+ */
+ public final PiHeaderFieldId fieldId() {
+ return fieldId;
+ }
+
+ /**
+ * Returns the type of match to be performed.
+ *
+ * @return a match type value
+ */
+ public abstract PiMatchType type();
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiFlowRuleTranslationService.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiFlowRuleTranslationService.java
new file mode 100644
index 0000000..93d8e0c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiFlowRuleTranslationService.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.pi.model.PiPipeconf;
+
+/**
+ * A service to translate ONOS flow rules to table entries of a protocol-independent pipeline.
+ */
+@Beta
+public interface PiFlowRuleTranslationService {
+
+ /**
+ * Returns a table entry equivalent to the given flow rule for the given protocol-independent
+ * pipeline configuration.
+ *
+ * @param rule a flow rule
+ * @param pipeconf a pipeline configuration
+ * @return a table entry
+ * @throws PiFlowRuleTranslationException if the flow rule cannot be translated
+ */
+ PiTableEntry translate(FlowRule rule, PiPipeconf pipeconf)
+ throws PiFlowRuleTranslationException;
+
+ /**
+ * Signals that an error was encountered while translating flow rule.
+ */
+ class PiFlowRuleTranslationException extends Exception {
+
+ /**
+ * Creates a new exception with the given message.
+ *
+ * @param message a message
+ */
+ public PiFlowRuleTranslationException(String message) {
+ super(message);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiHeaderFieldId.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiHeaderFieldId.java
new file mode 100644
index 0000000..5566202
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiHeaderFieldId.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import org.onlab.util.Identifier;
+
+/**
+ * Identifier of a packet's header field.
+ */
+public final class PiHeaderFieldId extends Identifier<String> {
+
+ private final String headerName;
+ private final String fieldName;
+ private final int index;
+
+ /**
+ * Creates a new header field identifier for the given header name, field name and index.
+ * <p>
+ * Index represents the position of this header in the packet w.r.t. to other headers of the
+ * same type. Index 0 points to the first instance of the header, 1 the second one, etc. Helpful
+ * when dealing with stacked headers, e.g. to match on the second MPLS label.
+ *
+ * @param headerName header name
+ * @param fieldName field name
+ * @param index index
+ */
+ public PiHeaderFieldId(String headerName, String fieldName, int index) {
+ super(headerName +
+ (index > 0 ? "[" + String.valueOf(index) + "]" : "") +
+ "." + fieldName);
+ this.headerName = headerName;
+ this.fieldName = fieldName;
+ this.index = index;
+ }
+
+ /**
+ * Creates a new header field identifier for the given header name and field name.
+ *
+ * @param headerName header name
+ * @param fieldName field name
+ */
+ public PiHeaderFieldId(String headerName, String fieldName) {
+ this(headerName, fieldName, 0);
+ }
+
+ /**
+ * Returns the name of the header.
+ *
+ * @return a string value
+ */
+ public String headerName() {
+ return headerName;
+ }
+
+ /**
+ * Returns the name of the field.
+ *
+ * @return a string value
+ */
+ public String fieldName() {
+ return fieldName;
+ }
+
+ /**
+ * Returns the index of this header.
+ *
+ * @return an integer value.
+ */
+ public int index() {
+ return index;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiLpmFieldMatch.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiLpmFieldMatch.java
new file mode 100644
index 0000000..d97e1d9
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiLpmFieldMatch.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchType;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Longest-prefix field match in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiLpmFieldMatch extends PiFieldMatch {
+
+ private final ImmutableByteSequence value;
+ private final int prefixLength;
+
+ /**
+ * Creates a new LPM field match.
+ *
+ * @param fieldId field identifier
+ * @param value value
+ * @param prefixLength prefix length
+ */
+ public PiLpmFieldMatch(PiHeaderFieldId fieldId, ImmutableByteSequence value, int prefixLength) {
+ super(fieldId);
+ this.value = checkNotNull(value);
+ this.prefixLength = prefixLength;
+ checkArgument(value.size() > 0, "Value must have non-zero size");
+ checkArgument(prefixLength >= 0, "Prefix length must be a non-negative integer");
+ }
+
+ @Override
+ public PiMatchType type() {
+ return PiMatchType.LPM;
+ }
+
+ /**
+ * Returns the value matched by this field.
+ *
+ * @return a byte sequence value
+ */
+ public ImmutableByteSequence value() {
+ return value;
+ }
+
+ /**
+ * Returns the prefix length to be matched.
+ *
+ * @return an integer value
+ */
+ public int prefixLength() {
+ return prefixLength;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiLpmFieldMatch that = (PiLpmFieldMatch) o;
+ return prefixLength == that.prefixLength &&
+ Objects.equal(value, that.value) &&
+ Objects.equal(this.fieldId(), that.fieldId());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.fieldId(), value, prefixLength);
+ }
+
+ @Override
+ public String toString() {
+ return this.fieldId().toString() + '=' + value.toString()
+ + '/' + String.valueOf(prefixLength);
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiPipeconfService.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiPipeconfService.java
new file mode 100644
index 0000000..c037eb6
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiPipeconfService.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.pi.model.PiPipeconf;
+import org.onosproject.net.pi.model.PiPipeconfId;
+
+import java.util.Optional;
+
+/**
+ * A service to manage the configurations of protocol-independent pipelines.
+ */
+@Beta
+public interface PiPipeconfService {
+
+ // TODO: we might want to extend ListenerService to support the broadcasting of PipeconfEvent.
+
+ /**
+ * Registers the given pipeconf.
+ *
+ * @param pipeconf a pipeconf
+ * @throws IllegalStateException if the same pipeconf identifier is already registered.
+ */
+ void register(PiPipeconf pipeconf) throws IllegalStateException;
+
+ /**
+ * Returns all pipeconfs registered.
+ *
+ * @return a collection of pipeconfs
+ */
+ Iterable<PiPipeconf> getPipeconfs();
+
+ /**
+ * Returns the pipeconf instance associated with the given identifier, if present.
+ * If not present, it means that no pipeconf with such identifier has been registered so far.
+ *
+ * @param id a pipeconf identifier
+ * @return an optional pipeconf
+ */
+ Optional<PiPipeconf> getPipeconf(PiPipeconfId id);
+
+ /**
+ * Binds the given pipeconf to the given infrastructure device. As a result of this method call,
+ * if the given pipeconf exposes any pipeline-specific behaviours, those will be merged to the
+ * device's driver.
+ *
+ * @param deviceId a device identifier
+ * @param pipeconf a pipeconf identifier
+ */
+ // TODO: This service doesn't make any effort in deploying the configuration to the device.
+ // Someone else should do that.
+ void bindToDevice(PiPipeconfId pipeconf, DeviceId deviceId);
+
+ /**
+ * Returns the pipeconf identifier currently associated with the given device identifier, if
+ * present. If not present, it means no pipeconf has been associated with that device so far.
+ *
+ * @param deviceId device identifier
+ * @return an optional pipeconf identifier
+ */
+ Optional<PiPipeconfId> ofDevice(DeviceId deviceId);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiRangeFieldMatch.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiRangeFieldMatch.java
new file mode 100644
index 0000000..c4cf8d7
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiRangeFieldMatch.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchType;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Range field match in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiRangeFieldMatch extends PiFieldMatch {
+
+ private final ImmutableByteSequence lowValue;
+ private final ImmutableByteSequence highValue;
+
+ /**
+ * Creates a new range field match for the given low and high value.
+ *
+ * @param fieldId field identifier
+ * @param lowValue low value
+ * @param highValue high value
+ */
+ public PiRangeFieldMatch(PiHeaderFieldId fieldId, ImmutableByteSequence lowValue,
+ ImmutableByteSequence highValue) {
+ super(fieldId);
+ this.lowValue = checkNotNull(lowValue);
+ this.highValue = checkNotNull(highValue);
+ checkArgument(lowValue.size() == highValue.size() && lowValue.size() > 0,
+ "Low and high values must have the same non-zero size.");
+ }
+
+ @Override
+ public PiMatchType type() {
+ return PiMatchType.RANGE;
+ }
+
+ /**
+ * Returns the low value of this range field match.
+ *
+ * @return low value
+ */
+ public ImmutableByteSequence lowValue() {
+ return lowValue;
+ }
+
+ /**
+ * Returns the high value of this range field match.
+ *
+ * @return high value
+ */
+ public ImmutableByteSequence highValue() {
+ return highValue;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiRangeFieldMatch that = (PiRangeFieldMatch) o;
+ return Objects.equal(this.fieldId(), that.fieldId()) &&
+ Objects.equal(lowValue, that.lowValue) &&
+ Objects.equal(highValue, that.highValue);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.fieldId(), lowValue, highValue);
+ }
+
+ @Override
+ public String toString() {
+ return this.fieldId().toString() + '=' + lowValue.toString() + "--" + highValue.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableAction.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableAction.java
new file mode 100644
index 0000000..a4d4038
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableAction.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * An action that can be executed as a consequence of a match in a match+action table of a protocol-independent
+ * pipeline.
+ */
+@Beta
+public interface PiTableAction {
+
+ /**
+ * Type of this action.
+ *
+ * @return a type
+ */
+ Type type();
+
+ enum Type {
+ /**
+ * Simple action with runtime parameters set by the control plane.
+ */
+ ACTION,
+
+ // TODO: in P4Runtime a table action can be any of the following 3.
+ // How to represent action profiles?
+ /* message TableAction {
+ oneof type {
+ Action action = 1;
+ uint32 action_profile_member_id = 2;
+ uint32 action_profile_group_id = 3;
+ }
+ }
+ */
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableEntry.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableEntry.java
new file mode 100644
index 0000000..741fc04
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableEntry.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Table entry in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiTableEntry {
+
+ private static final int NO_PRIORITY = -1;
+ private static final double NO_TIMEOUT = -1;
+
+ private final PiTableId tableId;
+ private final Collection<PiFieldMatch> fieldMatches;
+ private final PiTableAction tableAction;
+ private final long cookie;
+ private final int priority;
+ private final double timeout;
+
+ private PiTableEntry(PiTableId tableId, Map<PiHeaderFieldId, PiFieldMatch> fieldMatches,
+ PiTableAction tableAction, long cookie, int priority, double timeout) {
+ this.tableId = tableId;
+ this.fieldMatches = ImmutableSet.copyOf(fieldMatches.values());
+ this.tableAction = tableAction;
+ this.cookie = cookie;
+ this.priority = priority;
+ this.timeout = timeout;
+ }
+
+ /**
+ * Returns the table where this entry is installed.
+ *
+ * @return table identifier
+ */
+ public PiTableId table() {
+ return tableId;
+ }
+
+ /**
+ * Returns an immutable view of the field matches of this table entry.
+ *
+ * @return collection of field matches
+ */
+ public Collection<PiFieldMatch> fieldMatches() {
+ return fieldMatches;
+ }
+
+ /**
+ * Returns the action of this table entry.
+ *
+ * @return action
+ */
+ public PiTableAction action() {
+ return tableAction;
+ }
+
+ /**
+ * Returns the cookie of this table entry.
+ *
+ * @return cookie
+ */
+ public long cookie() {
+ return cookie;
+ }
+
+ /**
+ * Returns the priority of this table entry, if present.
+ * If the priority value is not present, then this table entry has no explicit priority.
+ *
+ * @return optional priority
+ */
+ public Optional<Integer> priority() {
+ return priority == NO_PRIORITY ? Optional.empty() : Optional.of(priority);
+ }
+
+ /**
+ * Returns the timeout in seconds of this table entry, if present.
+ * If the timeout value is not present, then this table entry is meant to be permanent.
+ *
+ * @return optional timeout value in seconds
+ */
+ public Optional<Double> timeout() {
+ return timeout == NO_TIMEOUT ? Optional.empty() : Optional.of(timeout);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiTableEntry that = (PiTableEntry) o;
+ return priority == that.priority &&
+ Double.compare(that.timeout, timeout) == 0 &&
+ Objects.equal(tableId, that.tableId) &&
+ Objects.equal(fieldMatches, that.fieldMatches) &&
+ Objects.equal(tableAction, that.tableAction);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(tableId, fieldMatches, tableAction, priority, timeout);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("tableId", tableId)
+ .add("fieldMatches", fieldMatches)
+ .add("tableAction", tableAction)
+ .add("priority", priority == NO_PRIORITY ? "N/A" : String.valueOf(priority))
+ .add("timeout", timeout == NO_TIMEOUT ? "PERMANENT" : String.valueOf(timeout))
+ .toString();
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static final class Builder {
+
+ private PiTableId tableId;
+ private Map<PiHeaderFieldId, PiFieldMatch> fieldMatches = Maps.newHashMap();
+ private PiTableAction tableAction;
+ private long cookie = 0;
+ private int priority = NO_PRIORITY;
+ private double timeout = NO_TIMEOUT;
+
+ private Builder() {
+ // Hides constructor.
+ }
+
+ /**
+ * Sets the table identifier for this entry.
+ *
+ * @param tableId table identifier
+ * @return this
+ */
+ Builder forTable(PiTableId tableId) {
+ this.tableId = checkNotNull(tableId);
+ return this;
+ }
+
+ /**
+ * Sets the action of this table entry.
+ *
+ * @param tableAction table action
+ * @return this
+ */
+ Builder withAction(PiTableAction tableAction) {
+ this.tableAction = checkNotNull(tableAction);
+ return this;
+ }
+
+ /**
+ * Adds one field match to this table entry.
+ *
+ * @param fieldMatch field match
+ * @return this
+ */
+ Builder withFieldMatch(PiFieldMatch fieldMatch) {
+ this.fieldMatches.put(fieldMatch.fieldId(), fieldMatch);
+ return this;
+ }
+
+ /**
+ * Adds many field matches to this table entry.
+ *
+ * @param fieldMatches collection of field matches
+ * @return this
+ */
+ Builder withFieldMatches(Collection<PiFieldMatch> fieldMatches) {
+ fieldMatches.forEach(f -> this.fieldMatches.put(f.fieldId(), f));
+ return this;
+ }
+
+ /**
+ * Sets the cookie, i.e. a controller-specific metadata.
+ *
+ * @param cookie cookie
+ * @return this
+ */
+ Builder withCookie(long cookie) {
+ this.cookie = cookie;
+ return this;
+ }
+
+ /**
+ * Sets the priority of this table entry.
+ *
+ * @param priority priority
+ * @return this
+ */
+ Builder withPriority(int priority) {
+ checkArgument(priority >= 0, "Priority must be a positive integer.");
+ this.priority = priority;
+ return this;
+ }
+
+ /**
+ * Sets the timeout of this table entry.
+ *
+ * @param seconds timeout in seconds
+ * @return this
+ */
+ Builder withTimeout(double seconds) {
+ checkArgument(seconds > 0, "Timeout must be greater than zero.");
+ this.timeout = seconds;
+ return this;
+ }
+
+ /**
+ * Builds the table entry.
+ *
+ * @return a new table entry
+ */
+ PiTableEntry build() {
+ checkNotNull(tableId);
+ checkNotNull(tableAction);
+ return new PiTableEntry(tableId, fieldMatches, tableAction, cookie, priority, timeout);
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableId.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableId.java
new file mode 100644
index 0000000..c062500
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTableId.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Identifier of a table in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiTableId extends Identifier<String> {
+
+ private final String scope;
+ private final String name;
+
+ /**
+ * Creates a new table identifier for the given scope and table name.
+ *
+ * @param scope table scope
+ * @param name table name
+ */
+ public PiTableId(String scope, String name) {
+ super(checkNotNull(scope) + '.' + checkNotNull(name));
+ this.scope = scope;
+ this.name = name;
+ }
+
+ /**
+ * Creates a new table identifier for the given table name.
+ *
+ * @param name table name
+ */
+ public PiTableId(String name) {
+ super(checkNotNull(name));
+ this.name = name;
+ this.scope = null;
+ }
+
+
+ /**
+ * Returns the name of this table.
+ *
+ * @return table name
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns the scope of this table, if present.
+ *
+ * @return optional scope
+ */
+ public Optional<String> scope() {
+ return Optional.ofNullable(scope);
+ }
+
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTernaryFieldMatch.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTernaryFieldMatch.java
new file mode 100644
index 0000000..cd98d20
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiTernaryFieldMatch.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchType;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Ternary field match in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiTernaryFieldMatch extends PiFieldMatch {
+
+ private final ImmutableByteSequence value;
+ private final ImmutableByteSequence mask;
+
+ /**
+ * Creates a new ternary field match.
+ *
+ * @param fieldId field identifier
+ * @param value value
+ * @param mask mask
+ */
+ public PiTernaryFieldMatch(PiHeaderFieldId fieldId, ImmutableByteSequence value,
+ ImmutableByteSequence mask) {
+ super(fieldId);
+ this.value = checkNotNull(value);
+ this.mask = checkNotNull(mask);
+ checkArgument(value.size() == mask.size() && value.size() > 0,
+ "Value and mask must have same non-zero size");
+ }
+
+ @Override
+ public PiMatchType type() {
+ return PiMatchType.TERNARY;
+ }
+
+ /**
+ * Returns the value matched by this field.
+ *
+ * @return an immutable byte sequence
+ */
+ public ImmutableByteSequence value() {
+ return value;
+ }
+
+ /**
+ * Returns the mask used to match this field.
+ *
+ * @return an immutable byte sequence
+ */
+ public ImmutableByteSequence mask() {
+ return mask;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiTernaryFieldMatch that = (PiTernaryFieldMatch) o;
+ return Objects.equal(this.fieldId(), that.fieldId()) &&
+ Objects.equal(value, that.value) &&
+ Objects.equal(mask, that.mask);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.fieldId(), value, mask);
+ }
+
+ @Override
+ public String toString() {
+ return this.fieldId().toString() + '=' + value.toString() + "&&&" + mask.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiValidFieldMatch.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiValidFieldMatch.java
new file mode 100644
index 0000000..ef716a2
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiValidFieldMatch.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.pi.runtime;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiMatchType;
+
+/**
+ * A valid field match in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiValidFieldMatch extends PiFieldMatch {
+
+ private final boolean isValid;
+
+ /**
+ * Creates a new valid field match.
+ *
+ * @param fieldId field identifier
+ * @param isValid validity flag
+ */
+ public PiValidFieldMatch(PiHeaderFieldId fieldId, boolean isValid) {
+ super(fieldId);
+ this.isValid = isValid;
+ }
+
+ @Override
+ public final PiMatchType type() {
+ return PiMatchType.VALID;
+ }
+
+ /**
+ * Returns the boolean flag of this valid match parameter.
+ *
+ * @return valid match flag
+ */
+ public boolean isValid() {
+ return isValid;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiValidFieldMatch that = (PiValidFieldMatch) o;
+ return Objects.equal(this.fieldId(), that.fieldId()) &&
+ isValid == that.isValid;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.fieldId(), isValid);
+ }
+
+ @Override
+ public String toString() {
+ return this.fieldId().toString() + '=' + (isValid ? "VALID" : "NOT_VALID");
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/package-info.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/package-info.java
new file mode 100644
index 0000000..f92f905
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Base abstractions fot runtime control of a protocol-independent pipeline.
+ */
+package org.onosproject.net.pi.runtime;
\ No newline at end of file
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
index 4e8f8e3..df98b8d 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
@@ -139,6 +139,7 @@
formatMap.put(Criterion.Type.UDP_DST_MASKED, new FormatUnknown());
formatMap.put(Criterion.Type.SCTP_SRC_MASKED, new FormatUnknown());
formatMap.put(Criterion.Type.SCTP_DST_MASKED, new FormatUnknown());
+ formatMap.put(Criterion.Type.PROTOCOL_INDEPENDENT, new FormatUnknown());
}