Carmelo Cascone

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
/*
* 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();
}
}
/*
* 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();
}
}
/*
* 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();
}
}
/*
* 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();
}
}
/*
* 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();
}
}
/*
* 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();
}
}
/*
* 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
/*
* 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();
}
}
/*
* 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
/*
* 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;
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.drivers.bmv2.model.Bmv2Model;
import org.onosproject.drivers.bmv2.model.Bmv2ModelAction;
import org.onosproject.drivers.bmv2.model.Bmv2ModelHeaderType;
import org.onosproject.drivers.bmv2.model.Bmv2ModelTable;
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("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
{
"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