ONOS-4175 Implemented BMv2 configuration model parser
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.
Change-Id: Ic08df68bed5a0261cb50b27dc7dbfe9d35e1fb71
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2Model.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2Model.java
new file mode 100644
index 0000000..433fd95
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2Model.java
@@ -0,0 +1,411 @@
+/*
+ * 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.drivers.bmv2.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 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");
+ 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 matchType = jKey.asObject().get("match_type").asString();
+
+ 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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelAction.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelAction.java
new file mode 100644
index 0000000..be073a1
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelAction.java
@@ -0,0 +1,116 @@
+/*
+ * 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.drivers.bmv2.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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelField.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelField.java
new file mode 100644
index 0000000..63cdcce
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelField.java
@@ -0,0 +1,79 @@
+/*
+ * 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.drivers.bmv2.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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelFieldType.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelFieldType.java
new file mode 100644
index 0000000..0cd1f11
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelFieldType.java
@@ -0,0 +1,79 @@
+/*
+ * 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.drivers.bmv2.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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelHeader.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelHeader.java
new file mode 100644
index 0000000..5aa2f39
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelHeader.java
@@ -0,0 +1,113 @@
+/*
+ * 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.drivers.bmv2.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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelHeaderType.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelHeaderType.java
new file mode 100644
index 0000000..e70fd92
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelHeaderType.java
@@ -0,0 +1,117 @@
+/*
+ * 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.drivers.bmv2.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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelRuntimeData.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelRuntimeData.java
new file mode 100644
index 0000000..0de1d09
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelRuntimeData.java
@@ -0,0 +1,85 @@
+/*
+ * 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.drivers.bmv2.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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelTable.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelTable.java
new file mode 100644
index 0000000..2351f49
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelTable.java
@@ -0,0 +1,191 @@
+/*
+ * 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.drivers.bmv2.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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelTableKey.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelTableKey.java
new file mode 100644
index 0000000..a65b578
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/Bmv2ModelTableKey.java
@@ -0,0 +1,86 @@
+/*
+ * 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.drivers.bmv2.model;
+
+import com.google.common.base.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of a table key.
+ */
+public final class Bmv2ModelTableKey {
+
+ private final String matchType;
+ private final Bmv2ModelField field;
+
+ /**
+ * Creates a new table key.
+ *
+ * @param matchType match type
+ * @param field field instance
+ */
+ protected Bmv2ModelTableKey(String 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 String 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/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/package-info.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/package-info.java
new file mode 100644
index 0000000..7e585dd
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/model/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * BMv2 configuration model classes.
+ */
+package org.onosproject.drivers.bmv2.model;
\ No newline at end of file