Various Bmv2 protocol refactorings in preparation of the flow rule
translator (ONOS-4044)
- Added new classes for different match parameters (exact, ternary, lpm,
valid)
- Divided api package in two sub-packages, model (previously under
drivers) and runtime (old api package)
- Improved Bmv2ThriftClient caching and table entry handling
Change-Id: I23c174cf3e8f9f6ecddb99c2d09dc531e8f1c73f
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2MatchKey.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2MatchKey.java
deleted file mode 100644
index d068328..0000000
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2MatchKey.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 2014-2016 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.bmv2.api;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.Lists;
-import org.p4.bmv2.thrift.BmMatchParam;
-import org.p4.bmv2.thrift.BmMatchParamExact;
-import org.p4.bmv2.thrift.BmMatchParamLPM;
-import org.p4.bmv2.thrift.BmMatchParamTernary;
-import org.p4.bmv2.thrift.BmMatchParamType;
-import org.p4.bmv2.thrift.BmMatchParamValid;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Bmv2 match key representation.
- */
-public final class Bmv2MatchKey {
-
- private final List<BmMatchParam> matchParams;
-
- /**
- * Creates a new match key.
- *
- * @param matchParams The ordered list of match parameters
- */
- private Bmv2MatchKey(List<BmMatchParam> matchParams) {
- this.matchParams = matchParams;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Returns the match parameters defined for this match key (read-only).
- *
- * @return match parameters
- */
- public final List<BmMatchParam> bmMatchParams() {
- return Collections.unmodifiableList(matchParams);
- }
-
- @Override
- public final int hashCode() {
- return Objects.hashCode(matchParams);
- }
-
- @Override
- public final boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Bmv2MatchKey other = (Bmv2MatchKey) obj;
-
- return Objects.equals(this.matchParams, other.matchParams);
- }
-
- @Override
- public final String toString() {
- return MoreObjects.toStringHelper(this)
- .addValue(matchParams)
- .toString();
- }
-
- /**
- * Builder of a Bmv2 match key.
- */
- public static final class Builder {
-
- private List<BmMatchParam> matchParams;
-
- private Builder() {
- this.matchParams = Lists.newArrayList();
- }
-
- /**
- * Adds an exact match parameter.
- *
- * @param key a ByteBuffer value
- * @return this
- */
- public Builder withExact(ByteBuffer key) {
- this.matchParams.add(
- new BmMatchParam(BmMatchParamType.EXACT)
- .setExact(new BmMatchParamExact(key)));
- return this;
- }
-
-
- /**
- * Adds a longest prefix match parameter.
- *
- * @param key a ByteBuffer value
- * @param prefixLength an integer value
- * @return this
- */
- public Builder withLpm(ByteBuffer key, int prefixLength) {
- this.matchParams.add(
- new BmMatchParam(BmMatchParamType.LPM)
- .setLpm(new BmMatchParamLPM(key, prefixLength)));
- return this;
- }
-
- /**
- * Adds a ternary match parameter.
- *
- * @param key a ByteBuffer value
- * @param mask an ByteBuffer value
- * @return this
- */
- public Builder withTernary(ByteBuffer key, ByteBuffer mask) {
- this.matchParams.add(
- new BmMatchParam(BmMatchParamType.TERNARY).
- setTernary(new BmMatchParamTernary(key, mask)));
- return this;
- }
-
- /**
- * Adds a ternary match parameter where all bits are don't-care.
- *
- * @param byteLength an integer value representing the length in byte of the parameter
- * @return this
- */
- public Builder withWildcard(int byteLength) {
- byte[] zeros = new byte[byteLength];
- Arrays.fill(zeros, (byte) 0);
- return this.withTernary(ByteBuffer.wrap(zeros), ByteBuffer.wrap(zeros));
- }
-
- /**
- * Adds a valid match parameter.
- *
- * @param key a boolean value
- * @return this
- */
- public Builder withValid(boolean key) {
- this.matchParams.add(
- new BmMatchParam(BmMatchParamType.VALID)
- .setValid(new BmMatchParamValid(key)));
- return this;
- }
-
- /**
- * Builds a new match key object.
- *
- * @return match key
- */
- public Bmv2MatchKey build() {
- return new Bmv2MatchKey(this.matchParams);
- }
- }
-}
\ No newline at end of file
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2Model.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2Model.java
new file mode 100644
index 0000000..7a5e8a0
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2Model.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.onosproject.bmv2.api.runtime.Bmv2MatchParam;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Partial representation of a packet processing model for BMv2. Such a model is
+ * used to define the way BMv2 should process packets (i.e. it defines the
+ * device ingress/egress pipelines, parser, tables, actions, etc.) and can be
+ * generated (i.e. JSON) by compiling a P4 program using p4c-bm.
+ * <p>
+ * It must be noted that this class exposes only a subset of the full model
+ * properties (only those that are needed for the purpose of mapping ONOS types
+ * to BMv2 types.
+ *
+ * @see <a href="https://github.com/p4lang/p4c-bm">
+ * P4 front-end compiler for BMv2 (p4c-bm)</a>
+ */
+public final class Bmv2Model {
+
+ private final JsonObject json;
+ private final DualKeySortedMap<Bmv2ModelHeaderType> headerTypes = new DualKeySortedMap<>();
+ private final DualKeySortedMap<Bmv2ModelHeader> headers = new DualKeySortedMap<>();
+ private final DualKeySortedMap<Bmv2ModelAction> actions = new DualKeySortedMap<>();
+ private final DualKeySortedMap<Bmv2ModelTable> tables = new DualKeySortedMap<>();
+
+ private Bmv2Model(JsonObject json) {
+ this.json = JsonObject.unmodifiableObject(json);
+ }
+
+ /**
+ * Returns a new BMv2 model object by parsing the passed JSON.
+ *
+ * @param json json
+ * @return a new BMv2 configuration object
+ * @see <a href="https://github.com/p4lang/behavioral-model/blob/master/docs/JSON_format.md">
+ * BMv2 JSON specification</a>
+ */
+ public static Bmv2Model parse(JsonObject json) {
+ checkArgument(json != null, "json cannot be null");
+ // TODO: implement caching, no need to parse a json if we already have the model
+ Bmv2Model model = new Bmv2Model(json);
+ model.doParse();
+ return model;
+ }
+
+ /**
+ * Returns the header type associated with the passed numeric id,
+ * null if there's no such an id in the model.
+ *
+ * @param id integer value
+ * @return header type object or null
+ */
+ public Bmv2ModelHeaderType headerType(int id) {
+ return headerTypes.get(id);
+ }
+
+ /**
+ * Returns the header type associated with the passed name,
+ * null if there's no such a name in the model.
+ *
+ * @param name string value
+ * @return header type object or null
+ */
+ public Bmv2ModelHeaderType headerType(String name) {
+ return headerTypes.get(name);
+ }
+
+ /**
+ * Returns the list of all the header types defined by in this model.
+ * Values returned are sorted in ascending order based on the numeric id.
+ *
+ * @return list of header types
+ */
+ public List<Bmv2ModelHeaderType> headerTypes() {
+ return ImmutableList.copyOf(headerTypes.sortedMap().values());
+ }
+
+ /**
+ * Returns the header associated with the passed numeric id,
+ * null if there's no such an id in the model.
+ *
+ * @param id integer value
+ * @return header object or null
+ */
+ public Bmv2ModelHeader header(int id) {
+ return headers.get(id);
+ }
+
+ /**
+ * Returns the header associated with the passed name,
+ * null if there's no such a name in the model.
+ *
+ * @param name string value
+ * @return header object or null
+ */
+ public Bmv2ModelHeader header(String name) {
+ return headers.get(name);
+ }
+
+ /**
+ * Returns the list of all the header instances defined in this model.
+ * Values returned are sorted in ascending order based on the numeric id.
+ *
+ * @return list of header types
+ */
+ public List<Bmv2ModelHeader> headers() {
+ return ImmutableList.copyOf(headers.sortedMap().values());
+ }
+
+ /**
+ * Returns the action associated with the passed numeric id,
+ * null if there's no such an id in the model.
+ *
+ * @param id integer value
+ * @return action object or null
+ */
+ public Bmv2ModelAction action(int id) {
+ return actions.get(id);
+ }
+
+ /**
+ * Returns the action associated with the passed name,
+ * null if there's no such a name in the model.
+ *
+ * @param name string value
+ * @return action object or null
+ */
+ public Bmv2ModelAction action(String name) {
+ return actions.get(name);
+ }
+
+ /**
+ * Returns the list of all the actions defined by in this model.
+ * Values returned are sorted in ascending order based on the numeric id.
+ *
+ * @return list of actions
+ */
+ public List<Bmv2ModelAction> actions() {
+ return ImmutableList.copyOf(actions.sortedMap().values());
+ }
+
+ /**
+ * Returns the table associated with the passed numeric id,
+ * null if there's no such an id in the model.
+ *
+ * @param id integer value
+ * @return table object or null
+ */
+ public Bmv2ModelTable table(int id) {
+ return tables.get(id);
+ }
+
+ /**
+ * Returns the table associated with the passed name,
+ * null if there's no such a name in the model.
+ *
+ * @param name string value
+ * @return table object or null
+ */
+ public Bmv2ModelTable table(String name) {
+ return tables.get(name);
+ }
+
+ /**
+ * Returns the list of all the tables defined by in this model.
+ * Values returned are sorted in ascending order based on the numeric id.
+ *
+ * @return list of actions
+ */
+ public List<Bmv2ModelTable> tables() {
+ return ImmutableList.copyOf(tables.sortedMap().values());
+ }
+
+ /**
+ * Return an unmodifiable view of the low-level JSON representation of this
+ * model.
+ *
+ * @return a JSON object.
+ */
+ public JsonObject json() {
+ return this.json;
+ }
+
+ /**
+ * Generates a hash code for this BMv2 model. The hash function is based
+ * solely on the low-level JSON representation.
+ */
+ @Override
+ public int hashCode() {
+ return json.hashCode();
+ }
+
+ /**
+ * Indicates whether some other BMv2 model is equal to this one.
+ * Equality is based solely on the low-level JSON representation.
+ *
+ * @param obj other object
+ * @return true if equals, false elsewhere
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2Model other = (Bmv2Model) obj;
+ return Objects.equal(this.json, other.json);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("jsonHash", json.hashCode())
+ .toString();
+ }
+
+ /**
+ * Parse the JSON object and build the corresponding objects.
+ */
+ private void doParse() {
+ // parse header types
+ json.get("header_types").asArray().forEach(val -> {
+
+ JsonObject jHeaderType = val.asObject();
+
+ // populate fields list
+ List<Bmv2ModelFieldType> fieldTypes = Lists.newArrayList();
+
+ jHeaderType.get("fields").asArray().forEach(x -> fieldTypes.add(
+ new Bmv2ModelFieldType(
+ x.asArray().get(0).asString(),
+ x.asArray().get(1).asInt())));
+
+ // add header type instance
+ String name = jHeaderType.get("name").asString();
+ int id = jHeaderType.get("id").asInt();
+
+ Bmv2ModelHeaderType headerType = new Bmv2ModelHeaderType(name,
+ id,
+ fieldTypes);
+
+ headerTypes.put(name, id, headerType);
+ });
+
+ // parse headers
+ json.get("headers").asArray().forEach(val -> {
+
+ JsonObject jHeader = val.asObject();
+
+ String name = jHeader.get("name").asString();
+ int id = jHeader.get("id").asInt();
+ String typeName = jHeader.get("header_type").asString();
+
+ Bmv2ModelHeader header = new Bmv2ModelHeader(name,
+ id,
+ headerTypes.get(typeName),
+ jHeader.get("metadata").asBoolean());
+
+ // add instance
+ headers.put(name, id, header);
+ });
+
+ // parse actions
+ json.get("actions").asArray().forEach(val -> {
+
+ JsonObject jAction = val.asObject();
+
+ // populate runtime data list
+ List<Bmv2ModelRuntimeData> runtimeDatas = Lists.newArrayList();
+
+ jAction.get("runtime_data").asArray().forEach(jData -> runtimeDatas.add(
+ new Bmv2ModelRuntimeData(
+ jData.asObject().get("name").asString(),
+ jData.asObject().get("bitwidth").asInt()
+ )));
+
+ // add action instance
+ String name = jAction.get("name").asString();
+ int id = jAction.get("id").asInt();
+
+ Bmv2ModelAction action = new Bmv2ModelAction(name,
+ id,
+ runtimeDatas);
+
+ actions.put(name, id, action);
+ });
+
+ // parse tables
+ json.get("pipelines").asArray().forEach(pipeline -> {
+
+ pipeline.asObject().get("tables").asArray().forEach(val -> {
+
+ JsonObject jTable = val.asObject();
+
+ // populate keys
+ List<Bmv2ModelTableKey> keys = Lists.newArrayList();
+
+ jTable.get("key").asArray().forEach(jKey -> {
+ JsonArray target = jKey.asObject().get("target").asArray();
+
+ Bmv2ModelHeader header = header(target.get(0).asString());
+ String typeName = target.get(1).asString();
+
+ Bmv2ModelField field = new Bmv2ModelField(
+ header, header.type().field(typeName));
+
+ String matchTypeStr = jKey.asObject().get("match_type").asString();
+
+ Bmv2MatchParam.Type matchType;
+
+ switch (matchTypeStr) {
+ case "ternary":
+ matchType = Bmv2MatchParam.Type.TERNARY;
+ break;
+ case "exact":
+ matchType = Bmv2MatchParam.Type.EXACT;
+ break;
+ case "lpm":
+ matchType = Bmv2MatchParam.Type.LPM;
+ break;
+ case "valid":
+ matchType = Bmv2MatchParam.Type.VALID;
+ break;
+ default:
+ throw new RuntimeException(
+ "Unable to parse match type: " + matchTypeStr);
+ }
+
+ keys.add(new Bmv2ModelTableKey(matchType, field));
+ });
+
+ // populate actions set
+ Set<Bmv2ModelAction> actionzz = Sets.newHashSet();
+ jTable.get("actions").asArray().forEach(
+ jAction -> actionzz.add(action(jAction.asString())));
+
+ // add table instance
+ String name = jTable.get("name").asString();
+ int id = jTable.get("id").asInt();
+
+ Bmv2ModelTable table = new Bmv2ModelTable(name,
+ id,
+ jTable.get("match_type").asString(),
+ jTable.get("type").asString(),
+ jTable.get("max_size").asInt(),
+ jTable.get("with_counters").asBoolean(),
+ jTable.get("support_timeout").asBoolean(),
+ keys,
+ actionzz);
+
+ tables.put(name, id, table);
+ });
+ });
+ }
+
+ /**
+ * Handy class for a map indexed by two keys, a string and an integer.
+ *
+ * @param <T> type of value stored by the map
+ */
+ private class DualKeySortedMap<T> {
+ private final SortedMap<Integer, T> intMap = Maps.newTreeMap();
+ private final Map<String, Integer> strToIntMap = Maps.newHashMap();
+
+ private void put(String name, int id, T object) {
+ strToIntMap.put(name, id);
+ intMap.put(id, object);
+ }
+
+ private T get(int id) {
+ return intMap.get(id);
+ }
+
+ private T get(String name) {
+ return get(strToIntMap.get(name));
+ }
+
+ private SortedMap<Integer, T> sortedMap() {
+ return intMap;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(intMap, strToIntMap);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final DualKeySortedMap other = (DualKeySortedMap) obj;
+ return Objects.equal(this.intMap, other.intMap)
+ && Objects.equal(this.strToIntMap, other.strToIntMap);
+ }
+ }
+}
\ No newline at end of file
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelAction.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelAction.java
new file mode 100644
index 0000000..f53806b
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelAction.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * BMv2 model action.
+ */
+public final class Bmv2ModelAction {
+
+ private final String name;
+ private final int id;
+ private final LinkedHashMap<String, Bmv2ModelRuntimeData> runtimeDatas = Maps.newLinkedHashMap();
+
+ /**
+ * Creates a new action object.
+ *
+ * @param name name
+ * @param id id
+ * @param runtimeDatas list of runtime data
+ */
+ protected Bmv2ModelAction(String name, int id, List<Bmv2ModelRuntimeData> runtimeDatas) {
+ this.name = name;
+ this.id = id;
+ runtimeDatas.forEach(r -> this.runtimeDatas.put(r.name(), r));
+ }
+
+ /**
+ * Returns the name of this action.
+ *
+ * @return a string value
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns the id of this action.
+ *
+ * @return an integer value
+ */
+ public int id() {
+ return id;
+ }
+
+ /**
+ * Returns this action's runtime data defined by the passed name, null
+ * if not present.
+ *
+ * @return runtime data or null
+ */
+ public Bmv2ModelRuntimeData runtimeData(String name) {
+ return runtimeDatas.get(name);
+ }
+
+ /**
+ * Returns an immutable list of runtime data for this action.
+ * The list is ordered according to the values defined in the model.
+ *
+ * @return list of runtime data.
+ */
+ public List<Bmv2ModelRuntimeData> runtimeDatas() {
+ return ImmutableList.copyOf(runtimeDatas.values());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, id, runtimeDatas);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ModelAction other = (Bmv2ModelAction) obj;
+ return Objects.equals(this.name, other.name)
+ && Objects.equals(this.id, other.id)
+ && Objects.equals(this.runtimeDatas, other.runtimeDatas);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("name", name)
+ .add("id", id)
+ .add("runtimeDatas", runtimeDatas)
+ .toString();
+ }
+
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelField.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelField.java
new file mode 100644
index 0000000..f20ae3b
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelField.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.google.common.base.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of a BMv2 model's header field instance.
+ */
+public final class Bmv2ModelField {
+
+ private final Bmv2ModelHeader header;
+ private final Bmv2ModelFieldType type;
+
+ protected Bmv2ModelField(Bmv2ModelHeader header, Bmv2ModelFieldType type) {
+ this.header = header;
+ this.type = type;
+ }
+
+ /**
+ * Returns the header instance of this field instance.
+ *
+ * @return a header instance
+ */
+ public Bmv2ModelHeader header() {
+ return header;
+ }
+
+ /**
+ * Returns the type of this field instance.
+ *
+ * @return a field type value
+ */
+ public Bmv2ModelFieldType type() {
+ return type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(header, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ModelField other = (Bmv2ModelField) obj;
+ return Objects.equal(this.header, other.header)
+ && Objects.equal(this.type, other.type);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("header", header)
+ .add("type", type)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelFieldType.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelFieldType.java
new file mode 100644
index 0000000..c0147bbd
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelFieldType.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.google.common.base.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * BMv2 model header type field.
+ */
+public final class Bmv2ModelFieldType {
+
+ private final String name;
+ private final int bitWidth;
+
+ protected Bmv2ModelFieldType(String name, int bitWidth) {
+ this.name = name;
+ this.bitWidth = bitWidth;
+ }
+
+ /**
+ * Returns the name of this header type field.
+ *
+ * @return a string value
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns the bit width of this header type field.
+ *
+ * @return an integer value
+ */
+ public int bitWidth() {
+ return bitWidth;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, bitWidth);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ModelFieldType other = (Bmv2ModelFieldType) obj;
+ return Objects.equal(this.name, other.name)
+ && Objects.equal(this.bitWidth, other.bitWidth);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("name", name)
+ .add("bitWidth", bitWidth)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelHeader.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelHeader.java
new file mode 100644
index 0000000..abab008
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelHeader.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.google.common.base.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of a BMv2 model header instance.
+ */
+public final class Bmv2ModelHeader {
+
+ private final String name;
+ private final int id;
+ private final Bmv2ModelHeaderType type;
+ private final boolean isMetadata;
+
+ /**
+ * Creates a new header instance.
+ *
+ * @param name name
+ * @param id id
+ * @param type header type
+ * @param metadata if is metadata
+ */
+ protected Bmv2ModelHeader(String name, int id, Bmv2ModelHeaderType type, boolean metadata) {
+ this.name = name;
+ this.id = id;
+ this.type = type;
+ this.isMetadata = metadata;
+ }
+
+ /**
+ * Returns the name of this header instance.
+ *
+ * @return a string value
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Return the id of this header instance.
+ *
+ * @return an integer value
+ */
+ public int id() {
+ return id;
+ }
+
+ /**
+ * Return the type of this header instance.
+ *
+ * @return a header type value
+ */
+ public Bmv2ModelHeaderType type() {
+ return type;
+ }
+
+ /**
+ * Return true if this header instance is a metadata, false elsewhere.
+ *
+ * @return a boolean value
+ */
+ public boolean isMetadata() {
+ return isMetadata;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, id, type, isMetadata);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ModelHeader other = (Bmv2ModelHeader) obj;
+ return Objects.equal(this.name, other.name)
+ && Objects.equal(this.id, other.id)
+ && Objects.equal(this.type, other.type)
+ && Objects.equal(this.isMetadata, other.isMetadata);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("name", name)
+ .add("id", id)
+ .add("type", type)
+ .add("isMetadata", isMetadata)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelHeaderType.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelHeaderType.java
new file mode 100644
index 0000000..3865871
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelHeaderType.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * BMv2 model header type.
+ */
+public final class Bmv2ModelHeaderType {
+
+ private final String name;
+ private final int id;
+ private final LinkedHashMap<String, Bmv2ModelFieldType> fields = Maps.newLinkedHashMap();
+
+ /**
+ * Creates a new header type instance.
+ *
+ * @param name name
+ * @param id id
+ * @param fieldTypes fields
+ */
+ protected Bmv2ModelHeaderType(String name, int id, List<Bmv2ModelFieldType> fieldTypes) {
+ this.name = name;
+ this.id = id;
+ fieldTypes.forEach(f -> this.fields.put(f.name(), f));
+ }
+
+ /**
+ * Returns this header type name.
+ *
+ * @return name
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns this header type id.
+ *
+ * @return id
+ */
+ public int id() {
+ return id;
+ }
+
+ /**
+ * Returns this header type's field defined by the passed name, null if
+ * not present.
+ *
+ * @param fieldName field name
+ * @return field or null
+ */
+ public Bmv2ModelFieldType field(String fieldName) {
+ return fields.get(fieldName);
+ }
+
+ /**
+ * Return and immutable list of header fields for this header
+ * type. The list is ordered according to the values defined in the
+ * model.
+ *
+ * @return list of fields
+ */
+ public List<Bmv2ModelFieldType> fields() {
+ return ImmutableList.copyOf(fields.values());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, id, fields);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ModelHeaderType other = (Bmv2ModelHeaderType) obj;
+ return Objects.equal(this.name, other.name)
+ && Objects.equal(this.id, other.id)
+ && Objects.equal(this.fields, other.fields);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("name", name)
+ .add("id", id)
+ .add("fields", fields)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelRuntimeData.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelRuntimeData.java
new file mode 100644
index 0000000..388c137
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelRuntimeData.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * BMv2 model action runtime data.
+ */
+public final class Bmv2ModelRuntimeData {
+
+ private final String name;
+ private final int bitWidth;
+
+ /**
+ * Creates a new runtime data.
+ *
+ * @param name name
+ * @param bitWidth bitwidth
+ */
+ protected Bmv2ModelRuntimeData(String name, int bitWidth) {
+ this.name = name;
+ this.bitWidth = bitWidth;
+ }
+
+ /**
+ * Return the name of this runtime data.
+ *
+ * @return a string value
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Return the bit width of this runtime data.
+ *
+ * @return an integer value
+ */
+ public int bitWidth() {
+ return bitWidth;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, bitWidth);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ModelRuntimeData other = (Bmv2ModelRuntimeData) obj;
+ return Objects.equals(this.name, other.name)
+ && Objects.equals(this.bitWidth, other.bitWidth);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("name", name)
+ .add("bitWidth", bitWidth)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelTable.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelTable.java
new file mode 100644
index 0000000..2dc7e3f
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelTable.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.google.common.base.Objects;
+
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * BMv2 model table representation.
+ */
+public final class Bmv2ModelTable {
+
+ private final String name;
+ private final int id;
+ private final String matchType;
+ private final String type;
+ private final int maxSize;
+ private final boolean hasCounters;
+ private final boolean hasTimeouts;
+ private final List<Bmv2ModelTableKey> keys;
+ private final Set<Bmv2ModelAction> actions;
+
+ /**
+ * Creates a new table.
+ *
+ * @param name name
+ * @param id id
+ * @param matchType match type
+ * @param type type
+ * @param maxSize max number of entries
+ * @param withCounters if table has counters
+ * @param supportTimeout if table supports aging
+ * @param keys list of match keys
+ * @param actions list of actions
+ */
+ protected Bmv2ModelTable(String name, int id, String matchType, String type,
+ int maxSize, boolean withCounters, boolean supportTimeout,
+ List<Bmv2ModelTableKey> keys, Set<Bmv2ModelAction> actions) {
+ this.name = name;
+ this.id = id;
+ this.matchType = matchType;
+ this.type = type;
+ this.maxSize = maxSize;
+ this.hasCounters = withCounters;
+ this.hasTimeouts = supportTimeout;
+ this.keys = keys;
+ this.actions = actions;
+ }
+
+ /**
+ * Returns the name of this table.
+ *
+ * @return a string value
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns the id of this table.
+ *
+ * @return an integer value
+ */
+ public int id() {
+ return id;
+ }
+
+ /**
+ * Return the match type of this table.
+ *
+ * @return a string value
+ */
+ public String matchType() {
+ return matchType;
+ }
+
+ /**
+ * Return the match type of this table.
+ *
+ * @return a string value
+ */
+ public String type() {
+ return type;
+ }
+
+ /**
+ * Returns the maximum number of entries supported by this table.
+ *
+ * @return an integer value
+ */
+ public int maxSize() {
+ return maxSize;
+ }
+
+ /**
+ * Returns true if this table has counters, false otherwise.
+ *
+ * @return a boolean value
+ */
+ public boolean hasCunters() {
+ return hasCounters;
+ }
+
+ /**
+ * Returns true if this table supports aging, false otherwise.
+ *
+ * @return a boolean value
+ */
+ public boolean hasTimeouts() {
+ return hasTimeouts;
+ }
+
+ /**
+ * Returns the list of match keys supported by this table.
+ * The list is ordered accordingly to the model's table definition.
+ *
+ * @return a list of match keys
+ */
+ public List<Bmv2ModelTableKey> keys() {
+ return keys;
+ }
+
+ /**
+ * Returns the set of actions supported by this table.
+ *
+ * @return a list of actions
+ */
+ public Set<Bmv2ModelAction> actions() {
+ return actions;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, id, matchType, type, maxSize, hasCounters,
+ hasTimeouts, keys, actions);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ModelTable other = (Bmv2ModelTable) obj;
+ return Objects.equal(this.name, other.name)
+ && Objects.equal(this.id, other.id)
+ && Objects.equal(this.matchType, other.matchType)
+ && Objects.equal(this.type, other.type)
+ && Objects.equal(this.maxSize, other.maxSize)
+ && Objects.equal(this.hasCounters, other.hasCounters)
+ && Objects.equal(this.hasTimeouts, other.hasTimeouts)
+ && Objects.equal(this.keys, other.keys)
+ && Objects.equal(this.actions, other.actions);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("name", name)
+ .add("id", id)
+ .add("matchType", matchType)
+ .add("type", type)
+ .add("maxSize", maxSize)
+ .add("hasCounters", hasCounters)
+ .add("hasTimeouts", hasTimeouts)
+ .add("keys", keys)
+ .add("actions", actions)
+ .toString();
+ }
+
+}
\ No newline at end of file
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelTableKey.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelTableKey.java
new file mode 100644
index 0000000..a98a7ec
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/Bmv2ModelTableKey.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.google.common.base.Objects;
+import org.onosproject.bmv2.api.runtime.Bmv2MatchParam;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of a table key.
+ */
+public final class Bmv2ModelTableKey {
+
+ private final Bmv2MatchParam.Type matchType;
+ private final Bmv2ModelField field;
+
+ /**
+ * Creates a new table key.
+ *
+ * @param matchType match type
+ * @param field field instance
+ */
+ protected Bmv2ModelTableKey(Bmv2MatchParam.Type matchType, Bmv2ModelField field) {
+ this.matchType = matchType;
+ this.field = field;
+ }
+
+ /**
+ * Returns the match type of this key.
+ *
+ * @return a string value
+ * TODO returns enum of match type
+ */
+ public Bmv2MatchParam.Type matchType() {
+ return matchType;
+ }
+
+ /**
+ * Returns the header field instance matched by this key.
+ *
+ * @return a header field value
+ */
+ public Bmv2ModelField field() {
+ return field;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(matchType, field);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ModelTableKey other = (Bmv2ModelTableKey) obj;
+ return Objects.equal(this.matchType, other.matchType)
+ && Objects.equal(this.field, other.field);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("matchType", matchType)
+ .add("field", field)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/package-info.java
similarity index 68%
copy from protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java
copy to protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/package-info.java
index a428491..adadced 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/model/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-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.
@@ -14,14 +14,7 @@
* limitations under the License.
*/
-package org.onosproject.bmv2.api;
-
/**
- * General Bmv2 exception.
+ * BMv2 configuration model classes.
*/
-public class Bmv2Exception extends Exception {
-
- public Bmv2Exception(String message, Throwable cause) {
- super(message, cause);
- }
-}
+package org.onosproject.bmv2.api.model;
\ No newline at end of file
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/package-info.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/package-info.java
index d8946e3..4d982ed 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/package-info.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/package-info.java
@@ -16,5 +16,10 @@
/**
* Bmv2 API abstractions.
+ * <p>
+ * Bmv2 APIs are divided in two sub-packages, runtime and model.
+ * Runtime APIs are used to represent operations that can be performed at runtime
+ * on a Bmv2 device, while model APIs are used to describe the Bmv2 packet
+ * processing model.
*/
package org.onosproject.bmv2.api;
\ No newline at end of file
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Action.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java
similarity index 75%
rename from protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Action.java
rename to protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java
index 5bbc50b..9b2a209 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Action.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-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.
@@ -14,27 +14,28 @@
* limitations under the License.
*/
-package org.onosproject.bmv2.api;
+package org.onosproject.bmv2.api.runtime;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;
+import org.onlab.util.ImmutableByteSequence;
-import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
/**
- * Bmv2 Action representation.
+ * Bmv2 action representation.
*/
public final class Bmv2Action {
private final String name;
- private final List<ByteBuffer> parameters;
+ private final List<ImmutableByteSequence> parameters;
- private Bmv2Action(String name, List<ByteBuffer> parameters) {
+ private Bmv2Action(String name, List<ImmutableByteSequence> parameters) {
// hide constructor
this.name = name;
this.parameters = parameters;
@@ -48,7 +49,7 @@
}
/**
- * Get action name.
+ * Return the name of this action.
*
* @return action name
*/
@@ -57,11 +58,12 @@
}
/**
- * Get list of action parameters ordered as per P4 action definition.
+ * Returns an immutable view of the ordered list of parameters of this
+ * action.
*
- * @return List of action parameters
+ * @return list of byte sequence
*/
- public final List<ByteBuffer> parameters() {
+ public final List<ImmutableByteSequence> parameters() {
return Collections.unmodifiableList(parameters);
}
@@ -96,8 +98,8 @@
*/
public static final class Builder {
- private String name;
- private List<ByteBuffer> parameters;
+ private String name = null;
+ private List<ImmutableByteSequence> parameters;
private Builder() {
this.parameters = Lists.newArrayList();
@@ -110,7 +112,7 @@
* @return this
*/
public Builder withName(String actionName) {
- this.name = actionName;
+ this.name = checkNotNull(actionName);
return this;
}
@@ -120,8 +122,8 @@
* @param parameter a ByteBuffer value
* @return this
*/
- public Builder addParameter(ByteBuffer parameter) {
- parameters.add(parameter);
+ public Builder addParameter(ImmutableByteSequence parameter) {
+ parameters.add(checkNotNull(parameter));
return this;
}
@@ -131,7 +133,7 @@
* @return a Bmv2 action
*/
public Bmv2Action build() {
- checkNotNull(name, "Action name not set");
+ checkState(name != null, "action name not set");
return new Bmv2Action(name, parameters);
}
}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java
new file mode 100644
index 0000000..d23bfc6
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2016-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.bmv2.api.runtime;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Representation of a Bmv2 exact match parameter.
+ */
+public class Bmv2ExactMatchParam implements Bmv2MatchParam {
+
+ private final ImmutableByteSequence value;
+
+ /**
+ * Creates a new match parameter object that matches exactly on the
+ * given byte sequence.
+ *
+ * @param value a byte sequence value
+ */
+ public Bmv2ExactMatchParam(ImmutableByteSequence value) {
+ this.value = checkNotNull(value, "value cannot be null");
+ }
+
+ @Override
+ public Type type() {
+ return Type.EXACT;
+ }
+
+ /**
+ * Return the byte sequence value matched by this parameter.
+ *
+ * @return an immutable byte buffer value
+ */
+ public ImmutableByteSequence value() {
+ return this.value;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ExactMatchParam other = (Bmv2ExactMatchParam) obj;
+ return Objects.equal(this.value, other.value);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("value", value)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2ExtensionSelector.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java
similarity index 89%
rename from protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2ExtensionSelector.java
rename to protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java
index 1bd9f1c..bf44a0e 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2ExtensionSelector.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-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.
@@ -14,13 +14,16 @@
* limitations under the License.
*/
-package org.onosproject.bmv2.api;
+package org.onosproject.bmv2.api.runtime;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+/**
+ * Extension selector for Bmv2 used as a wrapper for a {@link Bmv2MatchKey}.
+ */
public class Bmv2ExtensionSelector extends AbstractExtension implements ExtensionSelector {
private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2ExtensionTreatment.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java
similarity index 89%
rename from protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2ExtensionTreatment.java
rename to protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java
index cf48e38..12ab1e3 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2ExtensionTreatment.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-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.
@@ -14,13 +14,16 @@
* limitations under the License.
*/
-package org.onosproject.bmv2.api;
+package org.onosproject.bmv2.api.runtime;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+/**
+ * Extension treatment for Bmv2 used as a wrapper for a {@link Bmv2Action}.
+ */
public class Bmv2ExtensionTreatment extends AbstractExtension implements ExtensionTreatment {
private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java
new file mode 100644
index 0000000..29d5279
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2016-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.bmv2.api.runtime;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Representation of a Bmv2 longest prefix match (LPM) parameter.
+ */
+public class Bmv2LpmMatchParam implements Bmv2MatchParam {
+
+ private final ImmutableByteSequence value;
+ private final int prefixLength;
+
+ /**
+ * Creates a new LPM parameter using the given byte sequence value and
+ * prefix length.
+ *
+ * @param value a byte sequence value
+ * @param prefixLength an integer value
+ */
+ public Bmv2LpmMatchParam(ImmutableByteSequence value, int prefixLength) {
+ checkArgument(prefixLength >= 0, "prefix length cannot be negative");
+ this.value = checkNotNull(value);
+ this.prefixLength = prefixLength;
+ }
+
+ @Override
+ public Bmv2MatchParam.Type type() {
+ return Type.LPM;
+ }
+
+ /**
+ * Returns the byte sequence value of this parameter.
+ *
+ * @return a byte sequence value
+ */
+ public ImmutableByteSequence value() {
+ return this.value;
+ }
+
+ /**
+ * Returns the prefix length of this parameter.
+ *
+ * @return an integer value
+ */
+ public int prefixLength() {
+ return this.prefixLength;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(value, prefixLength);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2LpmMatchParam other = (Bmv2LpmMatchParam) obj;
+ return Objects.equal(this.value, other.value)
+ && Objects.equal(this.prefixLength, other.prefixLength);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("value", value)
+ .add("prefixLength", prefixLength)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java
new file mode 100644
index 0000000..cdcfcd9
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2016-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.bmv2.api.runtime;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Lists;
+import org.onlab.util.ImmutableByteSequence;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Bmv2 match key representation.
+ */
+public final class Bmv2MatchKey {
+
+ private final List<Bmv2MatchParam> matchParams;
+
+ private Bmv2MatchKey(List<Bmv2MatchParam> matchParams) {
+ // ban constructor
+ this.matchParams = matchParams;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns an immutable view of the ordered list of match parameters of this
+ * match key.
+ *
+ * @return list match parameters
+ */
+ public final List<Bmv2MatchParam> matchParams() {
+ return Collections.unmodifiableList(matchParams);
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hashCode(matchParams);
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2MatchKey other = (Bmv2MatchKey) obj;
+
+ return Objects.equals(this.matchParams, other.matchParams);
+ }
+
+ @Override
+ public final String toString() {
+ return MoreObjects.toStringHelper(this)
+ .addValue(matchParams)
+ .toString();
+ }
+
+ /**
+ * Builder of a Bmv2 match key.
+ */
+ public static final class Builder {
+
+ private List<Bmv2MatchParam> matchParams;
+
+ private Builder() {
+ this.matchParams = Lists.newArrayList();
+ }
+
+ public Builder add(Bmv2MatchParam param) {
+ this.matchParams.add(checkNotNull(param));
+ return this;
+ }
+
+ /**
+ * Adds a ternary match parameter where all bits are don't-care.
+ *
+ * @param byteLength length in bytes of the parameter
+ * @return this
+ */
+ public Builder withWildcard(int byteLength) {
+ checkArgument(byteLength > 0, "length must be a positive integer");
+ return add(new Bmv2TernaryMatchParam(
+ ImmutableByteSequence.ofZeros(byteLength),
+ ImmutableByteSequence.ofZeros(byteLength)));
+ }
+
+ /**
+ * Builds a new match key object.
+ *
+ * @return match key
+ */
+ public Bmv2MatchKey build() {
+ return new Bmv2MatchKey(this.matchParams);
+ }
+ }
+}
\ No newline at end of file
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java
new file mode 100644
index 0000000..35bac79
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016-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.bmv2.api.runtime;
+
+/**
+ * Representation of a Bmv2 match parameter.
+ */
+public interface Bmv2MatchParam {
+
+ /**
+ * Returns the match type of this parameter.
+ *
+ * @return a match type value
+ */
+ Type type();
+
+ /**
+ * Bmv2 match types.
+ */
+ enum Type {
+ /**
+ * Exact match type.
+ */
+ EXACT,
+ /**
+ * Ternary match type.
+ */
+ TERNARY,
+ /**
+ * Longest-prefix match type.
+ */
+ LPM,
+ /**
+ * Valid match type.
+ */
+ VALID;
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2PortInfo.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java
similarity index 93%
rename from protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2PortInfo.java
rename to protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java
index 3f36ade..c6be426 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2PortInfo.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.onosproject.bmv2.api;
+package org.onosproject.bmv2.api.runtime;
import com.google.common.base.MoreObjects;
import org.p4.bmv2.thrift.DevMgrPortInfo;
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java
similarity index 63%
copy from protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java
copy to protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java
index a428491..f7153c5 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-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.
@@ -14,14 +14,18 @@
* limitations under the License.
*/
-package org.onosproject.bmv2.api;
+package org.onosproject.bmv2.api.runtime;
/**
- * General Bmv2 exception.
+ * General exception of the Bmv2 runtime APIs.
*/
-public class Bmv2Exception extends Exception {
+public class Bmv2RuntimeException extends Exception {
- public Bmv2Exception(String message, Throwable cause) {
+ public Bmv2RuntimeException(String message, Throwable cause) {
super(message, cause);
}
+
+ public Bmv2RuntimeException(String message) {
+ super(message);
+ }
}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2TableEntry.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java
similarity index 87%
rename from protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2TableEntry.java
rename to protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java
index 4bf0291..96adadd 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2TableEntry.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-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.
@@ -14,12 +14,13 @@
* limitations under the License.
*/
-package org.onosproject.bmv2.api;
-
-import com.google.common.base.Preconditions;
+package org.onosproject.bmv2.api.runtime;
import java.util.Objects;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Bmv2 representation of a table entry.
*/
@@ -43,6 +44,11 @@
this.timeout = timeout;
}
+ /**
+ * Returns a new Bmv2 table entry builder.
+ *
+ * @return a new builder.
+ */
public static Builder builder() {
return new Builder();
}
@@ -159,7 +165,7 @@
* @return this
*/
public Builder withTableName(String tableName) {
- this.tableName = tableName;
+ this.tableName = checkNotNull(tableName, "table name cannot be null");
return this;
}
@@ -170,7 +176,7 @@
* @return this
*/
public Builder withMatchKey(Bmv2MatchKey matchKey) {
- this.matchKey = matchKey;
+ this.matchKey = checkNotNull(matchKey, "match key cannot be null");
return this;
}
@@ -181,11 +187,12 @@
* @return this
*/
public Builder withAction(Bmv2Action action) {
- this.action = action;
+ this.action = checkNotNull(action, "action cannot be null");
return this;
}
public Builder withPriority(int priority) {
+ checkArgument(priority >= 0, "priority cannot be negative");
this.priority = priority;
return this;
}
@@ -197,6 +204,7 @@
* @return this
*/
public Builder withTimeout(double timeout) {
+ checkArgument(timeout > 0, "timeout must be a positive non-zero value");
this.timeout = timeout;
return this;
}
@@ -207,10 +215,6 @@
* @return a new table entry object
*/
public Bmv2TableEntry build() {
- Preconditions.checkNotNull(tableName);
- Preconditions.checkNotNull(matchKey);
- Preconditions.checkNotNull(action);
-
return new Bmv2TableEntry(tableName, matchKey, action, priority,
timeout);
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java
new file mode 100644
index 0000000..76d42c3
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2016-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.bmv2.api.runtime;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Representation of a Bmv2 ternary match parameter.
+ */
+public class Bmv2TernaryMatchParam implements Bmv2MatchParam {
+
+ private final ImmutableByteSequence value;
+ private final ImmutableByteSequence mask;
+
+ /**
+ * Creates a new ternary match parameter using the given byte sequences of
+ * value and mask.
+ *
+ * @param value a byte sequence value
+ * @param mask a byte sequence value
+ */
+ public Bmv2TernaryMatchParam(ImmutableByteSequence value,
+ ImmutableByteSequence mask) {
+ this.value = checkNotNull(value, "value cannot be null");
+ this.mask = checkNotNull(mask, "value cannot be null");
+ checkState(value.size() == mask.size(),
+ "value and mask must have equal size");
+ }
+
+ @Override
+ public Type type() {
+ return Type.TERNARY;
+ }
+
+ /**
+ * Returns the byte sequence value of by this parameter.
+ *
+ * @return a byte sequence value
+ */
+ public ImmutableByteSequence value() {
+ return this.value;
+ }
+
+ /**
+ * Returns the byte sequence mask of by this parameter.
+ *
+ * @return a byte sequence value
+ */
+ public ImmutableByteSequence mask() {
+ return this.mask;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(value, mask);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2TernaryMatchParam other = (Bmv2TernaryMatchParam) obj;
+ return Objects.equal(this.value, other.value)
+ && Objects.equal(this.mask, other.mask);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("value", value)
+ .add("mask", mask)
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java
new file mode 100644
index 0000000..31080d5
--- /dev/null
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2016-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.bmv2.api.runtime;
+
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Representation of a Bmv2 valid match parameter.
+ */
+public class Bmv2ValidMatchParam implements Bmv2MatchParam {
+
+ private final boolean flag;
+
+ /**
+ * Creates a new valid match parameter using the given boolean flag.
+ *
+ * @param flag a boolean value
+ */
+ public Bmv2ValidMatchParam(boolean flag) {
+ this.flag = flag;
+ }
+
+ @Override
+ public Type type() {
+ return Type.VALID;
+ }
+
+ /**
+ * Returns the boolean flag of this parameter.
+ *
+ * @return a boolean value
+ */
+ public boolean flag() {
+ return flag;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(flag);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final Bmv2ValidMatchParam other = (Bmv2ValidMatchParam) obj;
+ return this.flag == other.flag;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("flag", flag)
+ .toString();
+ }
+}
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/package-info.java
similarity index 68%
rename from protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java
rename to protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/package-info.java
index a428491..8c11944 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/Bmv2Exception.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/api/runtime/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-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.
@@ -14,14 +14,7 @@
* limitations under the License.
*/
-package org.onosproject.bmv2.api;
-
/**
- * General Bmv2 exception.
+ * Bmv2 runtime APIs.
*/
-public class Bmv2Exception extends Exception {
-
- public Bmv2Exception(String message, Throwable cause) {
- super(message, cause);
- }
-}
+package org.onosproject.bmv2.api.runtime;
\ No newline at end of file
diff --git a/protocols/bmv2/src/main/java/org/onosproject/bmv2/ctl/Bmv2ThriftClient.java b/protocols/bmv2/src/main/java/org/onosproject/bmv2/ctl/Bmv2ThriftClient.java
index c3c86c1..eb6687a 100644
--- a/protocols/bmv2/src/main/java/org/onosproject/bmv2/ctl/Bmv2ThriftClient.java
+++ b/protocols/bmv2/src/main/java/org/onosproject/bmv2/ctl/Bmv2ThriftClient.java
@@ -31,15 +31,28 @@
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
-import org.onosproject.bmv2.api.Bmv2Action;
-import org.onosproject.bmv2.api.Bmv2Exception;
-import org.onosproject.bmv2.api.Bmv2PortInfo;
-import org.onosproject.bmv2.api.Bmv2TableEntry;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.bmv2.api.runtime.Bmv2Action;
+import org.onosproject.bmv2.api.runtime.Bmv2ExactMatchParam;
+import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException;
+import org.onosproject.bmv2.api.runtime.Bmv2LpmMatchParam;
+import org.onosproject.bmv2.api.runtime.Bmv2MatchKey;
+import org.onosproject.bmv2.api.runtime.Bmv2PortInfo;
+import org.onosproject.bmv2.api.runtime.Bmv2TableEntry;
+import org.onosproject.bmv2.api.runtime.Bmv2TernaryMatchParam;
+import org.onosproject.bmv2.api.runtime.Bmv2ValidMatchParam;
import org.onosproject.net.DeviceId;
import org.p4.bmv2.thrift.BmAddEntryOptions;
+import org.p4.bmv2.thrift.BmMatchParam;
+import org.p4.bmv2.thrift.BmMatchParamExact;
+import org.p4.bmv2.thrift.BmMatchParamLPM;
+import org.p4.bmv2.thrift.BmMatchParamTernary;
+import org.p4.bmv2.thrift.BmMatchParamType;
+import org.p4.bmv2.thrift.BmMatchParamValid;
import org.p4.bmv2.thrift.DevMgrPortInfo;
import org.p4.bmv2.thrift.Standard;
+import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
@@ -63,31 +76,37 @@
- avoids opening a new transport session when there's one already open
- close the connection after a predefined timeout of 5 seconds
*/
- private static LoadingCache<DeviceId, Pair<TTransport, Standard.Iface>>
+ private static LoadingCache<DeviceId, Bmv2ThriftClient>
clientCache = CacheBuilder.newBuilder()
.expireAfterAccess(5, TimeUnit.SECONDS)
.removalListener(new ClientRemovalListener())
.build(new ClientLoader());
private final Standard.Iface stdClient;
+ private final TTransport transport;
// ban constructor
- private Bmv2ThriftClient(Standard.Iface stdClient) {
+ private Bmv2ThriftClient(TTransport transport, Standard.Iface stdClient) {
+ this.transport = transport;
this.stdClient = stdClient;
}
+ private void closeTransport() {
+ this.transport.close();
+ }
+
/**
* Returns a client object to control the passed device.
*
* @param deviceId device id
* @return bmv2 client object
- * @throws Bmv2Exception if a connection to the device cannot be established
+ * @throws Bmv2RuntimeException if a connection to the device cannot be established
*/
- public static Bmv2ThriftClient of(DeviceId deviceId) throws Bmv2Exception {
+ public static Bmv2ThriftClient of(DeviceId deviceId) throws Bmv2RuntimeException {
try {
checkNotNull(deviceId, "deviceId cannot be null");
- return new Bmv2ThriftClient(clientCache.get(deviceId).getValue());
+ return clientCache.get(deviceId);
} catch (ExecutionException e) {
- throw new Bmv2Exception(e.getMessage(), e.getCause());
+ throw new Bmv2RuntimeException(e.getMessage(), e.getCause());
}
}
@@ -103,7 +122,7 @@
try {
of(deviceId).stdClient.bm_dev_mgr_show_ports();
return true;
- } catch (TException | Bmv2Exception e) {
+ } catch (TException | Bmv2RuntimeException e) {
return false;
}
}
@@ -129,13 +148,70 @@
}
/**
+ * Builds a list of Bmv2/Thrift compatible match parameters.
+ *
+ * @param matchKey a bmv2 matchKey
+ * @return list of thrift-compatible bm match parameters
+ */
+ private static List<BmMatchParam> buildMatchParamsList(Bmv2MatchKey matchKey) {
+ List<BmMatchParam> paramsList = Lists.newArrayList();
+ matchKey.matchParams().forEach(x -> {
+ switch (x.type()) {
+ case EXACT:
+ paramsList.add(
+ new BmMatchParam(BmMatchParamType.EXACT)
+ .setExact(new BmMatchParamExact(
+ ((Bmv2ExactMatchParam) x).value().asReadOnlyBuffer())));
+ break;
+ case TERNARY:
+ paramsList.add(
+ new BmMatchParam(BmMatchParamType.TERNARY)
+ .setTernary(new BmMatchParamTernary(
+ ((Bmv2TernaryMatchParam) x).value().asReadOnlyBuffer(),
+ ((Bmv2TernaryMatchParam) x).mask().asReadOnlyBuffer())));
+ break;
+ case LPM:
+ paramsList.add(
+ new BmMatchParam(BmMatchParamType.LPM)
+ .setLpm(new BmMatchParamLPM(
+ ((Bmv2LpmMatchParam) x).value().asReadOnlyBuffer(),
+ ((Bmv2LpmMatchParam) x).prefixLength())));
+ break;
+ case VALID:
+ paramsList.add(
+ new BmMatchParam(BmMatchParamType.VALID)
+ .setValid(new BmMatchParamValid(
+ ((Bmv2ValidMatchParam) x).flag())));
+ break;
+ default:
+ // should never be here
+ throw new RuntimeException("Unknown match param type " + x.type().name());
+ }
+ });
+ return paramsList;
+ }
+
+ /**
+ * Build a list of Bmv2/Thrift compatible action parameters.
+ *
+ * @param action an action object
+ * @return list of ByteBuffers
+ */
+ private static List<ByteBuffer> buildActionParamsList(Bmv2Action action) {
+ return action.parameters()
+ .stream()
+ .map(ImmutableByteSequence::asReadOnlyBuffer)
+ .collect(Collectors.toList());
+ }
+
+ /**
* Adds a new table entry.
*
* @param entry a table entry value
* @return table-specific entry ID
- * @throws Bmv2Exception if any error occurs
+ * @throws Bmv2RuntimeException if any error occurs
*/
- public final long addTableEntry(Bmv2TableEntry entry) throws Bmv2Exception {
+ public final long addTableEntry(Bmv2TableEntry entry) throws Bmv2RuntimeException {
long entryId = -1;
@@ -149,9 +225,9 @@
entryId = stdClient.bm_mt_add_entry(
CONTEXT_ID,
entry.tableName(),
- entry.matchKey().bmMatchParams(),
+ buildMatchParamsList(entry.matchKey()),
entry.action().name(),
- entry.action().parameters(),
+ buildActionParamsList(entry.action()),
options);
if (entry.hasTimeout()) {
@@ -170,10 +246,10 @@
CONTEXT_ID, entry.tableName(), entryId);
} catch (TException e1) {
// this should never happen as we know the entry is there
- throw new Bmv2Exception(e1.getMessage(), e1);
+ throw new Bmv2RuntimeException(e1.getMessage(), e1);
}
}
- throw new Bmv2Exception(e.getMessage(), e);
+ throw new Bmv2RuntimeException(e.getMessage(), e);
}
}
@@ -183,11 +259,11 @@
* @param tableName string value of table name
* @param entryId long value of entry ID
* @param action an action value
- * @throws Bmv2Exception if any error occurs
+ * @throws Bmv2RuntimeException if any error occurs
*/
public final void modifyTableEntry(String tableName,
long entryId, Bmv2Action action)
- throws Bmv2Exception {
+ throws Bmv2RuntimeException {
try {
stdClient.bm_mt_modify_entry(
@@ -195,10 +271,9 @@
tableName,
entryId,
action.name(),
- action.parameters()
- );
+ buildActionParamsList(action));
} catch (TException e) {
- throw new Bmv2Exception(e.getMessage(), e);
+ throw new Bmv2RuntimeException(e.getMessage(), e);
}
}
@@ -207,15 +282,15 @@
*
* @param tableName string value of table name
* @param entryId long value of entry ID
- * @throws Bmv2Exception if any error occurs
+ * @throws Bmv2RuntimeException if any error occurs
*/
public final void deleteTableEntry(String tableName,
- long entryId) throws Bmv2Exception {
+ long entryId) throws Bmv2RuntimeException {
try {
stdClient.bm_mt_delete_entry(CONTEXT_ID, tableName, entryId);
} catch (TException e) {
- throw new Bmv2Exception(e.getMessage(), e);
+ throw new Bmv2RuntimeException(e.getMessage(), e);
}
}
@@ -224,19 +299,19 @@
*
* @param tableName string value of table name
* @param action an action value
- * @throws Bmv2Exception if any error occurs
+ * @throws Bmv2RuntimeException if any error occurs
*/
public final void setTableDefaultAction(String tableName, Bmv2Action action)
- throws Bmv2Exception {
+ throws Bmv2RuntimeException {
try {
stdClient.bm_mt_set_default_action(
CONTEXT_ID,
tableName,
action.name(),
- action.parameters());
+ buildActionParamsList(action));
} catch (TException e) {
- throw new Bmv2Exception(e.getMessage(), e);
+ throw new Bmv2RuntimeException(e.getMessage(), e);
}
}
@@ -244,9 +319,9 @@
* Returns information of the ports currently configured in the switch.
*
* @return collection of port information
- * @throws Bmv2Exception if any error occurs
+ * @throws Bmv2RuntimeException if any error occurs
*/
- public Collection<Bmv2PortInfo> getPortsInfo() throws Bmv2Exception {
+ public Collection<Bmv2PortInfo> getPortsInfo() throws Bmv2RuntimeException {
try {
List<DevMgrPortInfo> portInfos = stdClient.bm_dev_mgr_show_ports();
@@ -261,7 +336,7 @@
return bmv2PortInfos;
} catch (TException e) {
- throw new Bmv2Exception(e.getMessage(), e);
+ throw new Bmv2RuntimeException(e.getMessage(), e);
}
}
@@ -270,28 +345,28 @@
*
* @param tableName string value of table name
* @return table string dump
- * @throws Bmv2Exception if any error occurs
+ * @throws Bmv2RuntimeException if any error occurs
*/
- public String dumpTable(String tableName) throws Bmv2Exception {
+ public String dumpTable(String tableName) throws Bmv2RuntimeException {
try {
return stdClient.bm_dump_table(CONTEXT_ID, tableName);
} catch (TException e) {
- throw new Bmv2Exception(e.getMessage(), e);
+ throw new Bmv2RuntimeException(e.getMessage(), e);
}
}
/**
* Reset the state of the switch (e.g. delete all entries, etc.).
*
- * @throws Bmv2Exception if any error occurs
+ * @throws Bmv2RuntimeException if any error occurs
*/
- public void resetState() throws Bmv2Exception {
+ public void resetState() throws Bmv2RuntimeException {
try {
stdClient.bm_reset_state();
} catch (TException e) {
- throw new Bmv2Exception(e.getMessage(), e);
+ throw new Bmv2RuntimeException(e.getMessage(), e);
}
}
@@ -299,10 +374,10 @@
* Transport/client cache loader.
*/
private static class ClientLoader
- extends CacheLoader<DeviceId, Pair<TTransport, Standard.Iface>> {
+ extends CacheLoader<DeviceId, Bmv2ThriftClient> {
@Override
- public Pair<TTransport, Standard.Iface> load(DeviceId deviceId)
+ public Bmv2ThriftClient load(DeviceId deviceId)
throws TTransportException {
Pair<String, Integer> info = parseDeviceId(deviceId);
//make the expensive call
@@ -314,7 +389,7 @@
transport.open();
- return ImmutablePair.of(transport, stdClient);
+ return new Bmv2ThriftClient(transport, stdClient);
}
}
@@ -322,14 +397,13 @@
* Client cache removal listener. Close the connection on cache removal.
*/
private static class ClientRemovalListener implements
- RemovalListener<DeviceId, Pair<TTransport, Standard.Iface>> {
+ RemovalListener<DeviceId, Bmv2ThriftClient> {
@Override
public void onRemoval(
- RemovalNotification<DeviceId, Pair<TTransport, Standard.Iface>>
- notification) {
+ RemovalNotification<DeviceId, Bmv2ThriftClient> notification) {
// close the transport connection
- notification.getValue().getKey().close();
+ notification.getValue().closeTransport();
}
}
}
diff --git a/protocols/bmv2/src/test/java/org/onosproject/bmv2/api/model/Bmv2ModelTest.java b/protocols/bmv2/src/test/java/org/onosproject/bmv2/api/model/Bmv2ModelTest.java
new file mode 100644
index 0000000..6550ee9
--- /dev/null
+++ b/protocols/bmv2/src/test/java/org/onosproject/bmv2/api/model/Bmv2ModelTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2016-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.bmv2.api.model;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.testing.EqualsTester;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.bmv2.api.runtime.Bmv2MatchParam;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+/**
+ * BMv2 model parser test suite.
+ */
+public class Bmv2ModelTest {
+
+ private JsonObject json;
+ private JsonObject json2;
+
+ @Before
+ public void setUp() throws Exception {
+ json = Json.parse(new BufferedReader(new InputStreamReader(
+ this.getClass().getResourceAsStream("/simple_pipeline.json")))).asObject();
+ json2 = Json.parse(new BufferedReader(new InputStreamReader(
+ this.getClass().getResourceAsStream("/simple_pipeline.json")))).asObject();
+ }
+
+ @Test
+ public void testParse() throws Exception {
+ Bmv2Model model = Bmv2Model.parse(json);
+ Bmv2Model model2 = Bmv2Model.parse(json);
+
+ new EqualsTester()
+ .addEqualityGroup(model, model2)
+ .testEquals();
+
+ /* Check header types */
+ Bmv2ModelHeaderType stdMetaT = model.headerType("standard_metadata_t");
+ Bmv2ModelHeaderType ethernetT = model.headerType("ethernet_t");
+ Bmv2ModelHeaderType intrinsicMetaT = model.headerType("intrinsic_metadata_t");
+
+ Bmv2ModelHeaderType stdMetaT2 = model2.headerType("standard_metadata_t");
+ Bmv2ModelHeaderType ethernetT2 = model2.headerType("ethernet_t");
+ Bmv2ModelHeaderType intrinsicMetaT2 = model2.headerType("intrinsic_metadata_t");
+
+ new EqualsTester()
+ .addEqualityGroup(stdMetaT, stdMetaT2)
+ .addEqualityGroup(ethernetT, ethernetT2)
+ .addEqualityGroup(intrinsicMetaT, intrinsicMetaT2)
+ .testEquals();
+
+ // existence
+ assertThat("Json parsed value is null", stdMetaT, notNullValue());
+ assertThat("Json parsed value is null", ethernetT, notNullValue());
+ assertThat("Json parsed value is null", intrinsicMetaT, notNullValue());
+
+ // fields size
+ assertThat("Incorrect size for header type fields",
+ stdMetaT.fields(), hasSize(8));
+ assertThat("Incorrect size for header type fields",
+ ethernetT.fields(), hasSize(3));
+ assertThat("Incorrect size for header type fields",
+ intrinsicMetaT.fields(), hasSize(4));
+
+ // check that fields are in order
+ assertThat("Incorrect order for header type fields",
+ stdMetaT.fields(), contains(
+ stdMetaT.field("ingress_port"),
+ stdMetaT.field("packet_length"),
+ stdMetaT.field("egress_spec"),
+ stdMetaT.field("egress_port"),
+ stdMetaT.field("egress_instance"),
+ stdMetaT.field("instance_type"),
+ stdMetaT.field("clone_spec"),
+ stdMetaT.field("_padding")));
+
+ /* Check actions */
+ Bmv2ModelAction floodAction = model.action("flood");
+ Bmv2ModelAction dropAction = model.action("_drop");
+ Bmv2ModelAction fwdAction = model.action("fwd");
+
+ Bmv2ModelAction floodAction2 = model2.action("flood");
+ Bmv2ModelAction dropAction2 = model2.action("_drop");
+ Bmv2ModelAction fwdAction2 = model2.action("fwd");
+
+ new EqualsTester()
+ .addEqualityGroup(floodAction, floodAction2)
+ .addEqualityGroup(dropAction, dropAction2)
+ .addEqualityGroup(fwdAction, fwdAction2)
+ .testEquals();
+
+ // existence
+ assertThat("Json parsed value is null", floodAction, notNullValue());
+ assertThat("Json parsed value is null", dropAction, notNullValue());
+ assertThat("Json parsed value is null", fwdAction, notNullValue());
+
+ // runtime data size
+ assertThat("Incorrect size for action runtime data",
+ floodAction.runtimeDatas().size(), is(equalTo(0)));
+ assertThat("Incorrect size for action runtime data",
+ dropAction.runtimeDatas().size(), is(equalTo(0)));
+ assertThat("Incorrect size for action runtime data",
+ fwdAction.runtimeDatas().size(), is(equalTo(1)));
+
+ // runtime data existence and parsing
+ assertThat("Parsed Json value is null",
+ fwdAction.runtimeData("port"), notNullValue());
+ assertThat("Incorrect value for action runtime data bitwidth",
+ fwdAction.runtimeData("port").bitWidth(), is(equalTo(9)));
+
+ /* Check tables */
+ Bmv2ModelTable table0 = model.table(0);
+ Bmv2ModelTable table02 = model2.table(0);
+
+ new EqualsTester()
+ .addEqualityGroup(table0, table02)
+ .testEquals();
+
+ // existence
+ assertThat("Parsed Json value is null", table0, notNullValue());
+
+ // id and name correspondence
+ assertThat("Incorrect value for table name",
+ table0.name(), is(equalTo("table0")));
+
+ // keys size
+ assertThat("Incorrect size for table keys",
+ table0.keys().size(), is(equalTo(4)));
+
+ // key match type
+ assertThat("Incorrect value for table key match type",
+ table0.keys().get(0).matchType(), is(equalTo(Bmv2MatchParam.Type.TERNARY)));
+
+ // header type
+ assertThat("Incorrect value for table key header type",
+ table0.keys().get(0).field().header().type(), is(equalTo(stdMetaT)));
+ }
+}
\ No newline at end of file
diff --git a/protocols/bmv2/src/test/resources/simple_pipeline.json b/protocols/bmv2/src/test/resources/simple_pipeline.json
new file mode 100644
index 0000000..372bdcd
--- /dev/null
+++ b/protocols/bmv2/src/test/resources/simple_pipeline.json
@@ -0,0 +1,505 @@
+{
+ "header_types": [
+ {
+ "name": "standard_metadata_t",
+ "id": 0,
+ "fields": [
+ [
+ "ingress_port",
+ 9
+ ],
+ [
+ "packet_length",
+ 32
+ ],
+ [
+ "egress_spec",
+ 9
+ ],
+ [
+ "egress_port",
+ 9
+ ],
+ [
+ "egress_instance",
+ 32
+ ],
+ [
+ "instance_type",
+ 32
+ ],
+ [
+ "clone_spec",
+ 32
+ ],
+ [
+ "_padding",
+ 5
+ ]
+ ],
+ "length_exp": null,
+ "max_length": null
+ },
+ {
+ "name": "ethernet_t",
+ "id": 1,
+ "fields": [
+ [
+ "dstAddr",
+ 48
+ ],
+ [
+ "srcAddr",
+ 48
+ ],
+ [
+ "etherType",
+ 16
+ ]
+ ],
+ "length_exp": null,
+ "max_length": null
+ },
+ {
+ "name": "intrinsic_metadata_t",
+ "id": 2,
+ "fields": [
+ [
+ "ingress_global_timestamp",
+ 32
+ ],
+ [
+ "lf_field_list",
+ 32
+ ],
+ [
+ "mcast_grp",
+ 16
+ ],
+ [
+ "egress_rid",
+ 16
+ ]
+ ],
+ "length_exp": null,
+ "max_length": null
+ },
+ {
+ "name": "cpu_header_t",
+ "id": 3,
+ "fields": [
+ [
+ "device",
+ 8
+ ],
+ [
+ "reason",
+ 8
+ ]
+ ],
+ "length_exp": null,
+ "max_length": null
+ }
+ ],
+ "headers": [
+ {
+ "name": "standard_metadata",
+ "id": 0,
+ "header_type": "standard_metadata_t",
+ "metadata": true
+ },
+ {
+ "name": "ethernet",
+ "id": 1,
+ "header_type": "ethernet_t",
+ "metadata": false
+ },
+ {
+ "name": "intrinsic_metadata",
+ "id": 2,
+ "header_type": "intrinsic_metadata_t",
+ "metadata": true
+ },
+ {
+ "name": "cpu_header",
+ "id": 3,
+ "header_type": "cpu_header_t",
+ "metadata": false
+ }
+ ],
+ "header_stacks": [],
+ "parsers": [
+ {
+ "name": "parser",
+ "id": 0,
+ "init_state": "start",
+ "parse_states": [
+ {
+ "name": "start",
+ "id": 0,
+ "parser_ops": [],
+ "transition_key": [
+ {
+ "type": "lookahead",
+ "value": [
+ 0,
+ 64
+ ]
+ }
+ ],
+ "transitions": [
+ {
+ "value": "0x0000000000000000",
+ "mask": null,
+ "next_state": "parse_cpu_header"
+ },
+ {
+ "value": "default",
+ "mask": null,
+ "next_state": "parse_ethernet"
+ }
+ ]
+ },
+ {
+ "name": "parse_cpu_header",
+ "id": 1,
+ "parser_ops": [
+ {
+ "op": "extract",
+ "parameters": [
+ {
+ "type": "regular",
+ "value": "cpu_header"
+ }
+ ]
+ }
+ ],
+ "transition_key": [],
+ "transitions": [
+ {
+ "value": "default",
+ "mask": null,
+ "next_state": "parse_ethernet"
+ }
+ ]
+ },
+ {
+ "name": "parse_ethernet",
+ "id": 2,
+ "parser_ops": [
+ {
+ "op": "extract",
+ "parameters": [
+ {
+ "type": "regular",
+ "value": "ethernet"
+ }
+ ]
+ }
+ ],
+ "transition_key": [],
+ "transitions": [
+ {
+ "value": "default",
+ "mask": null,
+ "next_state": null
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "deparsers": [
+ {
+ "name": "deparser",
+ "id": 0,
+ "order": [
+ "cpu_header",
+ "ethernet"
+ ]
+ }
+ ],
+ "meter_arrays": [],
+ "actions": [
+ {
+ "name": "flood",
+ "id": 0,
+ "runtime_data": [],
+ "primitives": [
+ {
+ "op": "modify_field",
+ "parameters": [
+ {
+ "type": "field",
+ "value": [
+ "intrinsic_metadata",
+ "mcast_grp"
+ ]
+ },
+ {
+ "type": "field",
+ "value": [
+ "standard_metadata",
+ "ingress_port"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "_drop",
+ "id": 1,
+ "runtime_data": [],
+ "primitives": [
+ {
+ "op": "modify_field",
+ "parameters": [
+ {
+ "type": "field",
+ "value": [
+ "standard_metadata",
+ "egress_spec"
+ ]
+ },
+ {
+ "type": "hexstr",
+ "value": "0x1ff"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "fwd",
+ "id": 2,
+ "runtime_data": [
+ {
+ "name": "port",
+ "bitwidth": 9
+ }
+ ],
+ "primitives": [
+ {
+ "op": "modify_field",
+ "parameters": [
+ {
+ "type": "field",
+ "value": [
+ "standard_metadata",
+ "egress_spec"
+ ]
+ },
+ {
+ "type": "runtime_data",
+ "value": 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "send_to_cpu",
+ "id": 3,
+ "runtime_data": [
+ {
+ "name": "device",
+ "bitwidth": 8
+ },
+ {
+ "name": "reason",
+ "bitwidth": 8
+ }
+ ],
+ "primitives": [
+ {
+ "op": "add_header",
+ "parameters": [
+ {
+ "type": "header",
+ "value": "cpu_header"
+ }
+ ]
+ },
+ {
+ "op": "modify_field",
+ "parameters": [
+ {
+ "type": "field",
+ "value": [
+ "cpu_header",
+ "device"
+ ]
+ },
+ {
+ "type": "runtime_data",
+ "value": 0
+ }
+ ]
+ },
+ {
+ "op": "modify_field",
+ "parameters": [
+ {
+ "type": "field",
+ "value": [
+ "cpu_header",
+ "reason"
+ ]
+ },
+ {
+ "type": "runtime_data",
+ "value": 1
+ }
+ ]
+ },
+ {
+ "op": "modify_field",
+ "parameters": [
+ {
+ "type": "field",
+ "value": [
+ "standard_metadata",
+ "egress_spec"
+ ]
+ },
+ {
+ "type": "hexstr",
+ "value": "0xfa"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "pipelines": [
+ {
+ "name": "ingress",
+ "id": 0,
+ "init_table": "table0",
+ "tables": [
+ {
+ "name": "table0",
+ "id": 0,
+ "match_type": "ternary",
+ "type": "simple",
+ "max_size": 16384,
+ "with_counters": false,
+ "direct_meters": null,
+ "support_timeout": false,
+ "key": [
+ {
+ "match_type": "ternary",
+ "target": [
+ "standard_metadata",
+ "ingress_port"
+ ],
+ "mask": null
+ },
+ {
+ "match_type": "ternary",
+ "target": [
+ "ethernet",
+ "dstAddr"
+ ],
+ "mask": null
+ },
+ {
+ "match_type": "ternary",
+ "target": [
+ "ethernet",
+ "srcAddr"
+ ],
+ "mask": null
+ },
+ {
+ "match_type": "ternary",
+ "target": [
+ "ethernet",
+ "etherType"
+ ],
+ "mask": null
+ }
+ ],
+ "actions": [
+ "fwd",
+ "flood",
+ "send_to_cpu",
+ "_drop"
+ ],
+ "next_tables": {
+ "fwd": null,
+ "flood": null,
+ "send_to_cpu": null,
+ "_drop": null
+ },
+ "default_action": null
+ }
+ ],
+ "conditionals": []
+ },
+ {
+ "name": "egress",
+ "id": 1,
+ "init_table": null,
+ "tables": [],
+ "conditionals": []
+ }
+ ],
+ "calculations": [],
+ "checksums": [],
+ "learn_lists": [],
+ "field_lists": [],
+ "counter_arrays": [],
+ "register_arrays": [],
+ "force_arith": [
+ [
+ "standard_metadata",
+ "ingress_port"
+ ],
+ [
+ "standard_metadata",
+ "packet_length"
+ ],
+ [
+ "standard_metadata",
+ "egress_spec"
+ ],
+ [
+ "standard_metadata",
+ "egress_port"
+ ],
+ [
+ "standard_metadata",
+ "egress_instance"
+ ],
+ [
+ "standard_metadata",
+ "instance_type"
+ ],
+ [
+ "standard_metadata",
+ "clone_spec"
+ ],
+ [
+ "standard_metadata",
+ "_padding"
+ ],
+ [
+ "intrinsic_metadata",
+ "ingress_global_timestamp"
+ ],
+ [
+ "intrinsic_metadata",
+ "lf_field_list"
+ ],
+ [
+ "intrinsic_metadata",
+ "mcast_grp"
+ ],
+ [
+ "intrinsic_metadata",
+ "egress_rid"
+ ]
+ ]
+}
\ No newline at end of file