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
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import com.eclipsesource.json.JsonArray;
20 +import com.eclipsesource.json.JsonObject;
21 +import com.google.common.base.MoreObjects;
22 +import com.google.common.base.Objects;
23 +import com.google.common.collect.ImmutableList;
24 +import com.google.common.collect.Lists;
25 +import com.google.common.collect.Maps;
26 +import com.google.common.collect.Sets;
27 +
28 +import java.util.List;
29 +import java.util.Map;
30 +import java.util.Set;
31 +import java.util.SortedMap;
32 +
33 +import static com.google.common.base.Preconditions.checkArgument;
34 +
35 +/**
36 + * Partial representation of a packet processing model for BMv2. Such a model is
37 + * used to define the way BMv2 should process packets (i.e. it defines the
38 + * device ingress/egress pipelines, parser, tables, actions, etc.) and can be
39 + * generated (i.e. JSON) by compiling a P4 program using p4c-bm.
40 + * <p>
41 + * It must be noted that this class exposes only a subset of the full model
42 + * properties (only those that are needed for the purpose of mapping ONOS types
43 + * to BMv2 types.
44 + *
45 + * @see <a href="https://github.com/p4lang/p4c-bm">
46 + * P4 front-end compiler for BMv2 (p4c-bm)</a>
47 + */
48 +public final class Bmv2Model {
49 +
50 + private final JsonObject json;
51 + private final DualKeySortedMap<Bmv2ModelHeaderType> headerTypes = new DualKeySortedMap<>();
52 + private final DualKeySortedMap<Bmv2ModelHeader> headers = new DualKeySortedMap<>();
53 + private final DualKeySortedMap<Bmv2ModelAction> actions = new DualKeySortedMap<>();
54 + private final DualKeySortedMap<Bmv2ModelTable> tables = new DualKeySortedMap<>();
55 +
56 + private Bmv2Model(JsonObject json) {
57 + this.json = JsonObject.unmodifiableObject(json);
58 + }
59 +
60 + /**
61 + * Returns a new BMv2 model object by parsing the passed JSON.
62 + *
63 + * @param json json
64 + * @return a new BMv2 configuration object
65 + * @see <a href="https://github.com/p4lang/behavioral-model/blob/master/docs/JSON_format.md">
66 + * BMv2 JSON specification</a>
67 + */
68 + public static Bmv2Model parse(JsonObject json) {
69 + checkArgument(json != null, "json cannot be null");
70 + Bmv2Model model = new Bmv2Model(json);
71 + model.doParse();
72 + return model;
73 + }
74 +
75 + /**
76 + * Returns the header type associated with the passed numeric id,
77 + * null if there's no such an id in the model.
78 + *
79 + * @param id integer value
80 + * @return header type object or null
81 + */
82 + public Bmv2ModelHeaderType headerType(int id) {
83 + return headerTypes.get(id);
84 + }
85 +
86 + /**
87 + * Returns the header type associated with the passed name,
88 + * null if there's no such a name in the model.
89 + *
90 + * @param name string value
91 + * @return header type object or null
92 + */
93 + public Bmv2ModelHeaderType headerType(String name) {
94 + return headerTypes.get(name);
95 + }
96 +
97 + /**
98 + * Returns the list of all the header types defined by in this model.
99 + * Values returned are sorted in ascending order based on the numeric id.
100 + *
101 + * @return list of header types
102 + */
103 + public List<Bmv2ModelHeaderType> headerTypes() {
104 + return ImmutableList.copyOf(headerTypes.sortedMap().values());
105 + }
106 +
107 + /**
108 + * Returns the header associated with the passed numeric id,
109 + * null if there's no such an id in the model.
110 + *
111 + * @param id integer value
112 + * @return header object or null
113 + */
114 + public Bmv2ModelHeader header(int id) {
115 + return headers.get(id);
116 + }
117 +
118 + /**
119 + * Returns the header associated with the passed name,
120 + * null if there's no such a name in the model.
121 + *
122 + * @param name string value
123 + * @return header object or null
124 + */
125 + public Bmv2ModelHeader header(String name) {
126 + return headers.get(name);
127 + }
128 +
129 + /**
130 + * Returns the list of all the header instances defined in this model.
131 + * Values returned are sorted in ascending order based on the numeric id.
132 + *
133 + * @return list of header types
134 + */
135 + public List<Bmv2ModelHeader> headers() {
136 + return ImmutableList.copyOf(headers.sortedMap().values());
137 + }
138 +
139 + /**
140 + * Returns the action associated with the passed numeric id,
141 + * null if there's no such an id in the model.
142 + *
143 + * @param id integer value
144 + * @return action object or null
145 + */
146 + public Bmv2ModelAction action(int id) {
147 + return actions.get(id);
148 + }
149 +
150 + /**
151 + * Returns the action associated with the passed name,
152 + * null if there's no such a name in the model.
153 + *
154 + * @param name string value
155 + * @return action object or null
156 + */
157 + public Bmv2ModelAction action(String name) {
158 + return actions.get(name);
159 + }
160 +
161 + /**
162 + * Returns the list of all the actions defined by in this model.
163 + * Values returned are sorted in ascending order based on the numeric id.
164 + *
165 + * @return list of actions
166 + */
167 + public List<Bmv2ModelAction> actions() {
168 + return ImmutableList.copyOf(actions.sortedMap().values());
169 + }
170 +
171 + /**
172 + * Returns the table associated with the passed numeric id,
173 + * null if there's no such an id in the model.
174 + *
175 + * @param id integer value
176 + * @return table object or null
177 + */
178 + public Bmv2ModelTable table(int id) {
179 + return tables.get(id);
180 + }
181 +
182 + /**
183 + * Returns the table associated with the passed name,
184 + * null if there's no such a name in the model.
185 + *
186 + * @param name string value
187 + * @return table object or null
188 + */
189 + public Bmv2ModelTable table(String name) {
190 + return tables.get(name);
191 + }
192 +
193 + /**
194 + * Returns the list of all the tables defined by in this model.
195 + * Values returned are sorted in ascending order based on the numeric id.
196 + *
197 + * @return list of actions
198 + */
199 + public List<Bmv2ModelTable> tables() {
200 + return ImmutableList.copyOf(tables.sortedMap().values());
201 + }
202 +
203 + /**
204 + * Return an unmodifiable view of the low-level JSON representation of this
205 + * model.
206 + *
207 + * @return a JSON object.
208 + */
209 + public JsonObject json() {
210 + return this.json;
211 + }
212 +
213 + /**
214 + * Generates a hash code for this BMv2 model. The hash function is based
215 + * solely on the low-level JSON representation.
216 + */
217 + @Override
218 + public int hashCode() {
219 + return json.hashCode();
220 + }
221 +
222 + /**
223 + * Indicates whether some other BMv2 model is equal to this one.
224 + * Equality is based solely on the low-level JSON representation.
225 + *
226 + * @param obj other object
227 + * @return true if equals, false elsewhere
228 + */
229 + @Override
230 + public boolean equals(Object obj) {
231 + if (this == obj) {
232 + return true;
233 + }
234 + if (obj == null || getClass() != obj.getClass()) {
235 + return false;
236 + }
237 + final Bmv2Model other = (Bmv2Model) obj;
238 + return Objects.equal(this.json, other.json);
239 + }
240 +
241 + @Override
242 + public String toString() {
243 + return MoreObjects.toStringHelper(this)
244 + .add("jsonHash", json.hashCode())
245 + .toString();
246 + }
247 +
248 + /**
249 + * Parse the JSON object and build the corresponding objects.
250 + */
251 + private void doParse() {
252 + // parse header types
253 + json.get("header_types").asArray().forEach(val -> {
254 +
255 + JsonObject jHeaderType = val.asObject();
256 +
257 + // populate fields list
258 + List<Bmv2ModelFieldType> fieldTypes = Lists.newArrayList();
259 +
260 + jHeaderType.get("fields").asArray().forEach(x -> fieldTypes.add(
261 + new Bmv2ModelFieldType(
262 + x.asArray().get(0).asString(),
263 + x.asArray().get(1).asInt())));
264 +
265 + // add header type instance
266 + String name = jHeaderType.get("name").asString();
267 + int id = jHeaderType.get("id").asInt();
268 +
269 + Bmv2ModelHeaderType headerType = new Bmv2ModelHeaderType(name,
270 + id,
271 + fieldTypes);
272 +
273 + headerTypes.put(name, id, headerType);
274 + });
275 +
276 + // parse headers
277 + json.get("headers").asArray().forEach(val -> {
278 +
279 + JsonObject jHeader = val.asObject();
280 +
281 + String name = jHeader.get("name").asString();
282 + int id = jHeader.get("id").asInt();
283 + String typeName = jHeader.get("header_type").asString();
284 +
285 + Bmv2ModelHeader header = new Bmv2ModelHeader(name,
286 + id,
287 + headerTypes.get(typeName),
288 + jHeader.get("metadata").asBoolean());
289 +
290 + // add instance
291 + headers.put(name, id, header);
292 + });
293 +
294 + // parse actions
295 + json.get("actions").asArray().forEach(val -> {
296 +
297 + JsonObject jAction = val.asObject();
298 +
299 + // populate runtime data list
300 + List<Bmv2ModelRuntimeData> runtimeDatas = Lists.newArrayList();
301 +
302 + jAction.get("runtime_data").asArray().forEach(jData -> runtimeDatas.add(
303 + new Bmv2ModelRuntimeData(
304 + jData.asObject().get("name").asString(),
305 + jData.asObject().get("bitwidth").asInt()
306 + )));
307 +
308 + // add action instance
309 + String name = jAction.get("name").asString();
310 + int id = jAction.get("id").asInt();
311 +
312 + Bmv2ModelAction action = new Bmv2ModelAction(name,
313 + id,
314 + runtimeDatas);
315 +
316 + actions.put(name, id, action);
317 + });
318 +
319 + // parse tables
320 + json.get("pipelines").asArray().forEach(pipeline -> {
321 +
322 + pipeline.asObject().get("tables").asArray().forEach(val -> {
323 +
324 + JsonObject jTable = val.asObject();
325 +
326 + // populate keys
327 + List<Bmv2ModelTableKey> keys = Lists.newArrayList();
328 +
329 + jTable.get("key").asArray().forEach(jKey -> {
330 + JsonArray target = jKey.asObject().get("target").asArray();
331 +
332 + Bmv2ModelHeader header = header(target.get(0).asString());
333 + String typeName = target.get(1).asString();
334 +
335 + Bmv2ModelField field = new Bmv2ModelField(
336 + header, header.type().field(typeName));
337 +
338 + String matchType = jKey.asObject().get("match_type").asString();
339 +
340 + keys.add(new Bmv2ModelTableKey(matchType, field));
341 + });
342 +
343 + // populate actions set
344 + Set<Bmv2ModelAction> actionzz = Sets.newHashSet();
345 + jTable.get("actions").asArray().forEach(
346 + jAction -> actionzz.add(action(jAction.asString())));
347 +
348 + // add table instance
349 + String name = jTable.get("name").asString();
350 + int id = jTable.get("id").asInt();
351 +
352 + Bmv2ModelTable table = new Bmv2ModelTable(name,
353 + id,
354 + jTable.get("match_type").asString(),
355 + jTable.get("type").asString(),
356 + jTable.get("max_size").asInt(),
357 + jTable.get("with_counters").asBoolean(),
358 + jTable.get("support_timeout").asBoolean(),
359 + keys,
360 + actionzz);
361 +
362 + tables.put(name, id, table);
363 + });
364 + });
365 + }
366 +
367 + /**
368 + * Handy class for a map indexed by two keys, a string and an integer.
369 + *
370 + * @param <T> type of value stored by the map
371 + */
372 + private class DualKeySortedMap<T> {
373 + private final SortedMap<Integer, T> intMap = Maps.newTreeMap();
374 + private final Map<String, Integer> strToIntMap = Maps.newHashMap();
375 +
376 + private void put(String name, int id, T object) {
377 + strToIntMap.put(name, id);
378 + intMap.put(id, object);
379 + }
380 +
381 + private T get(int id) {
382 + return intMap.get(id);
383 + }
384 +
385 + private T get(String name) {
386 + return get(strToIntMap.get(name));
387 + }
388 +
389 + private SortedMap<Integer, T> sortedMap() {
390 + return intMap;
391 + }
392 +
393 + @Override
394 + public int hashCode() {
395 + return Objects.hashCode(intMap, strToIntMap);
396 + }
397 +
398 + @Override
399 + public boolean equals(Object obj) {
400 + if (this == obj) {
401 + return true;
402 + }
403 + if (obj == null || getClass() != obj.getClass()) {
404 + return false;
405 + }
406 + final DualKeySortedMap other = (DualKeySortedMap) obj;
407 + return Objects.equal(this.intMap, other.intMap)
408 + && Objects.equal(this.strToIntMap, other.strToIntMap);
409 + }
410 + }
411 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import com.google.common.collect.ImmutableList;
20 +import com.google.common.collect.Maps;
21 +
22 +import java.util.LinkedHashMap;
23 +import java.util.List;
24 +import java.util.Objects;
25 +
26 +import static com.google.common.base.MoreObjects.toStringHelper;
27 +
28 +/**
29 + * BMv2 model action.
30 + */
31 +public final class Bmv2ModelAction {
32 +
33 + private final String name;
34 + private final int id;
35 + private final LinkedHashMap<String, Bmv2ModelRuntimeData> runtimeDatas = Maps.newLinkedHashMap();
36 +
37 + /**
38 + * Creates a new action object.
39 + *
40 + * @param name name
41 + * @param id id
42 + * @param runtimeDatas list of runtime data
43 + */
44 + protected Bmv2ModelAction(String name, int id, List<Bmv2ModelRuntimeData> runtimeDatas) {
45 + this.name = name;
46 + this.id = id;
47 + runtimeDatas.forEach(r -> this.runtimeDatas.put(r.name(), r));
48 + }
49 +
50 + /**
51 + * Returns the name of this action.
52 + *
53 + * @return a string value
54 + */
55 + public String name() {
56 + return name;
57 + }
58 +
59 + /**
60 + * Returns the id of this action.
61 + *
62 + * @return an integer value
63 + */
64 + public int id() {
65 + return id;
66 + }
67 +
68 + /**
69 + * Returns this action's runtime data defined by the passed name, null
70 + * if not present.
71 + *
72 + * @return runtime data or null
73 + */
74 + public Bmv2ModelRuntimeData runtimeData(String name) {
75 + return runtimeDatas.get(name);
76 + }
77 +
78 + /**
79 + * Returns an immutable list of runtime data for this action.
80 + * The list is ordered according to the values defined in the model.
81 + *
82 + * @return list of runtime data.
83 + */
84 + public List<Bmv2ModelRuntimeData> runtimeDatas() {
85 + return ImmutableList.copyOf(runtimeDatas.values());
86 + }
87 +
88 + @Override
89 + public int hashCode() {
90 + return Objects.hash(name, id, runtimeDatas);
91 + }
92 +
93 + @Override
94 + public boolean equals(Object obj) {
95 + if (this == obj) {
96 + return true;
97 + }
98 + if (obj == null || getClass() != obj.getClass()) {
99 + return false;
100 + }
101 + final Bmv2ModelAction other = (Bmv2ModelAction) obj;
102 + return Objects.equals(this.name, other.name)
103 + && Objects.equals(this.id, other.id)
104 + && Objects.equals(this.runtimeDatas, other.runtimeDatas);
105 + }
106 +
107 + @Override
108 + public String toString() {
109 + return toStringHelper(this)
110 + .add("name", name)
111 + .add("id", id)
112 + .add("runtimeDatas", runtimeDatas)
113 + .toString();
114 + }
115 +
116 +}
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import com.google.common.base.Objects;
20 +
21 +import static com.google.common.base.MoreObjects.toStringHelper;
22 +
23 +/**
24 + * Representation of a BMv2 model's header field instance.
25 + */
26 +public final class Bmv2ModelField {
27 +
28 + private final Bmv2ModelHeader header;
29 + private final Bmv2ModelFieldType type;
30 +
31 + protected Bmv2ModelField(Bmv2ModelHeader header, Bmv2ModelFieldType type) {
32 + this.header = header;
33 + this.type = type;
34 + }
35 +
36 + /**
37 + * Returns the header instance of this field instance.
38 + *
39 + * @return a header instance
40 + */
41 + public Bmv2ModelHeader header() {
42 + return header;
43 + }
44 +
45 + /**
46 + * Returns the type of this field instance.
47 + *
48 + * @return a field type value
49 + */
50 + public Bmv2ModelFieldType type() {
51 + return type;
52 + }
53 +
54 + @Override
55 + public int hashCode() {
56 + return Objects.hashCode(header, type);
57 + }
58 +
59 + @Override
60 + public boolean equals(Object obj) {
61 + if (this == obj) {
62 + return true;
63 + }
64 + if (obj == null || getClass() != obj.getClass()) {
65 + return false;
66 + }
67 + final Bmv2ModelField other = (Bmv2ModelField) obj;
68 + return Objects.equal(this.header, other.header)
69 + && Objects.equal(this.type, other.type);
70 + }
71 +
72 + @Override
73 + public String toString() {
74 + return toStringHelper(this)
75 + .add("header", header)
76 + .add("type", type)
77 + .toString();
78 + }
79 +}
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import com.google.common.base.Objects;
20 +
21 +import static com.google.common.base.MoreObjects.toStringHelper;
22 +
23 +/**
24 + * BMv2 model header type field.
25 + */
26 +public final class Bmv2ModelFieldType {
27 +
28 + private final String name;
29 + private final int bitWidth;
30 +
31 + protected Bmv2ModelFieldType(String name, int bitWidth) {
32 + this.name = name;
33 + this.bitWidth = bitWidth;
34 + }
35 +
36 + /**
37 + * Returns the name of this header type field.
38 + *
39 + * @return a string value
40 + */
41 + public String name() {
42 + return name;
43 + }
44 +
45 + /**
46 + * Returns the bit width of this header type field.
47 + *
48 + * @return an integer value
49 + */
50 + public int bitWidth() {
51 + return bitWidth;
52 + }
53 +
54 + @Override
55 + public int hashCode() {
56 + return Objects.hashCode(name, bitWidth);
57 + }
58 +
59 + @Override
60 + public boolean equals(Object obj) {
61 + if (this == obj) {
62 + return true;
63 + }
64 + if (obj == null || getClass() != obj.getClass()) {
65 + return false;
66 + }
67 + final Bmv2ModelFieldType other = (Bmv2ModelFieldType) obj;
68 + return Objects.equal(this.name, other.name)
69 + && Objects.equal(this.bitWidth, other.bitWidth);
70 + }
71 +
72 + @Override
73 + public String toString() {
74 + return toStringHelper(this)
75 + .add("name", name)
76 + .add("bitWidth", bitWidth)
77 + .toString();
78 + }
79 +}
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import com.google.common.base.Objects;
20 +
21 +import static com.google.common.base.MoreObjects.toStringHelper;
22 +
23 +/**
24 + * Representation of a BMv2 model header instance.
25 + */
26 +public final class Bmv2ModelHeader {
27 +
28 + private final String name;
29 + private final int id;
30 + private final Bmv2ModelHeaderType type;
31 + private final boolean isMetadata;
32 +
33 + /**
34 + * Creates a new header instance.
35 + *
36 + * @param name name
37 + * @param id id
38 + * @param type header type
39 + * @param metadata if is metadata
40 + */
41 + protected Bmv2ModelHeader(String name, int id, Bmv2ModelHeaderType type, boolean metadata) {
42 + this.name = name;
43 + this.id = id;
44 + this.type = type;
45 + this.isMetadata = metadata;
46 + }
47 +
48 + /**
49 + * Returns the name of this header instance.
50 + *
51 + * @return a string value
52 + */
53 + public String name() {
54 + return name;
55 + }
56 +
57 + /**
58 + * Return the id of this header instance.
59 + *
60 + * @return an integer value
61 + */
62 + public int id() {
63 + return id;
64 + }
65 +
66 + /**
67 + * Return the type of this header instance.
68 + *
69 + * @return a header type value
70 + */
71 + public Bmv2ModelHeaderType type() {
72 + return type;
73 + }
74 +
75 + /**
76 + * Return true if this header instance is a metadata, false elsewhere.
77 + *
78 + * @return a boolean value
79 + */
80 + public boolean isMetadata() {
81 + return isMetadata;
82 + }
83 +
84 + @Override
85 + public int hashCode() {
86 + return Objects.hashCode(name, id, type, isMetadata);
87 + }
88 +
89 + @Override
90 + public boolean equals(Object obj) {
91 + if (this == obj) {
92 + return true;
93 + }
94 + if (obj == null || getClass() != obj.getClass()) {
95 + return false;
96 + }
97 + final Bmv2ModelHeader other = (Bmv2ModelHeader) obj;
98 + return Objects.equal(this.name, other.name)
99 + && Objects.equal(this.id, other.id)
100 + && Objects.equal(this.type, other.type)
101 + && Objects.equal(this.isMetadata, other.isMetadata);
102 + }
103 +
104 + @Override
105 + public String toString() {
106 + return toStringHelper(this)
107 + .add("name", name)
108 + .add("id", id)
109 + .add("type", type)
110 + .add("isMetadata", isMetadata)
111 + .toString();
112 + }
113 +}
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import com.google.common.base.Objects;
20 +import com.google.common.collect.ImmutableList;
21 +import com.google.common.collect.Maps;
22 +
23 +import java.util.LinkedHashMap;
24 +import java.util.List;
25 +
26 +import static com.google.common.base.MoreObjects.toStringHelper;
27 +
28 +/**
29 + * BMv2 model header type.
30 + */
31 +public final class Bmv2ModelHeaderType {
32 +
33 + private final String name;
34 + private final int id;
35 + private final LinkedHashMap<String, Bmv2ModelFieldType> fields = Maps.newLinkedHashMap();
36 +
37 + /**
38 + * Creates a new header type instance.
39 + *
40 + * @param name name
41 + * @param id id
42 + * @param fieldTypes fields
43 + */
44 + protected Bmv2ModelHeaderType(String name, int id, List<Bmv2ModelFieldType> fieldTypes) {
45 + this.name = name;
46 + this.id = id;
47 + fieldTypes.forEach(f -> this.fields.put(f.name(), f));
48 + }
49 +
50 + /**
51 + * Returns this header type name.
52 + *
53 + * @return name
54 + */
55 + public String name() {
56 + return name;
57 + }
58 +
59 + /**
60 + * Returns this header type id.
61 + *
62 + * @return id
63 + */
64 + public int id() {
65 + return id;
66 + }
67 +
68 + /**
69 + * Returns this header type's field defined by the passed name, null if
70 + * not present.
71 + *
72 + * @param fieldName field name
73 + * @return field or null
74 + */
75 + public Bmv2ModelFieldType field(String fieldName) {
76 + return fields.get(fieldName);
77 + }
78 +
79 + /**
80 + * Return and immutable list of header fields for this header
81 + * type. The list is ordered according to the values defined in the
82 + * model.
83 + *
84 + * @return list of fields
85 + */
86 + public List<Bmv2ModelFieldType> fields() {
87 + return ImmutableList.copyOf(fields.values());
88 + }
89 +
90 + @Override
91 + public int hashCode() {
92 + return Objects.hashCode(name, id, fields);
93 + }
94 +
95 + @Override
96 + public boolean equals(Object obj) {
97 + if (this == obj) {
98 + return true;
99 + }
100 + if (obj == null || getClass() != obj.getClass()) {
101 + return false;
102 + }
103 + final Bmv2ModelHeaderType other = (Bmv2ModelHeaderType) obj;
104 + return Objects.equal(this.name, other.name)
105 + && Objects.equal(this.id, other.id)
106 + && Objects.equal(this.fields, other.fields);
107 + }
108 +
109 + @Override
110 + public String toString() {
111 + return toStringHelper(this)
112 + .add("name", name)
113 + .add("id", id)
114 + .add("fields", fields)
115 + .toString();
116 + }
117 +}
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import java.util.Objects;
20 +
21 +import static com.google.common.base.MoreObjects.toStringHelper;
22 +
23 +/**
24 + * BMv2 model action runtime data.
25 + */
26 +public final class Bmv2ModelRuntimeData {
27 +
28 + private final String name;
29 + private final int bitWidth;
30 +
31 + /**
32 + * Creates a new runtime data.
33 + *
34 + * @param name name
35 + * @param bitWidth bitwidth
36 + */
37 + protected Bmv2ModelRuntimeData(String name, int bitWidth) {
38 + this.name = name;
39 + this.bitWidth = bitWidth;
40 + }
41 +
42 + /**
43 + * Return the name of this runtime data.
44 + *
45 + * @return a string value
46 + */
47 + public String name() {
48 + return name;
49 + }
50 +
51 + /**
52 + * Return the bit width of this runtime data.
53 + *
54 + * @return an integer value
55 + */
56 + public int bitWidth() {
57 + return bitWidth;
58 + }
59 +
60 + @Override
61 + public int hashCode() {
62 + return Objects.hash(name, bitWidth);
63 + }
64 +
65 + @Override
66 + public boolean equals(Object obj) {
67 + if (this == obj) {
68 + return true;
69 + }
70 + if (obj == null || getClass() != obj.getClass()) {
71 + return false;
72 + }
73 + final Bmv2ModelRuntimeData other = (Bmv2ModelRuntimeData) obj;
74 + return Objects.equals(this.name, other.name)
75 + && Objects.equals(this.bitWidth, other.bitWidth);
76 + }
77 +
78 + @Override
79 + public String toString() {
80 + return toStringHelper(this)
81 + .add("name", name)
82 + .add("bitWidth", bitWidth)
83 + .toString();
84 + }
85 +}
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import com.google.common.base.Objects;
20 +
21 +import java.util.List;
22 +import java.util.Set;
23 +
24 +import static com.google.common.base.MoreObjects.toStringHelper;
25 +
26 +/**
27 + * BMv2 model table representation.
28 + */
29 +public final class Bmv2ModelTable {
30 +
31 + private final String name;
32 + private final int id;
33 + private final String matchType;
34 + private final String type;
35 + private final int maxSize;
36 + private final boolean hasCounters;
37 + private final boolean hasTimeouts;
38 + private final List<Bmv2ModelTableKey> keys;
39 + private final Set<Bmv2ModelAction> actions;
40 +
41 + /**
42 + * Creates a new table.
43 + *
44 + * @param name name
45 + * @param id id
46 + * @param matchType match type
47 + * @param type type
48 + * @param maxSize max number of entries
49 + * @param withCounters if table has counters
50 + * @param supportTimeout if table supports aging
51 + * @param keys list of match keys
52 + * @param actions list of actions
53 + */
54 + protected Bmv2ModelTable(String name, int id, String matchType, String type,
55 + int maxSize, boolean withCounters, boolean supportTimeout,
56 + List<Bmv2ModelTableKey> keys, Set<Bmv2ModelAction> actions) {
57 + this.name = name;
58 + this.id = id;
59 + this.matchType = matchType;
60 + this.type = type;
61 + this.maxSize = maxSize;
62 + this.hasCounters = withCounters;
63 + this.hasTimeouts = supportTimeout;
64 + this.keys = keys;
65 + this.actions = actions;
66 + }
67 +
68 + /**
69 + * Returns the name of this table.
70 + *
71 + * @return a string value
72 + */
73 + public String name() {
74 + return name;
75 + }
76 +
77 + /**
78 + * Returns the id of this table.
79 + *
80 + * @return an integer value
81 + */
82 + public int id() {
83 + return id;
84 + }
85 +
86 + /**
87 + * Return the match type of this table.
88 + *
89 + * @return a string value
90 + */
91 + public String matchType() {
92 + return matchType;
93 + }
94 +
95 + /**
96 + * Return the match type of this table.
97 + *
98 + * @return a string value
99 + */
100 + public String type() {
101 + return type;
102 + }
103 +
104 + /**
105 + * Returns the maximum number of entries supported by this table.
106 + *
107 + * @return an integer value
108 + */
109 + public int maxSize() {
110 + return maxSize;
111 + }
112 +
113 + /**
114 + * Returns true if this table has counters, false otherwise.
115 + *
116 + * @return a boolean value
117 + */
118 + public boolean hasCunters() {
119 + return hasCounters;
120 + }
121 +
122 + /**
123 + * Returns true if this table supports aging, false otherwise.
124 + *
125 + * @return a boolean value
126 + */
127 + public boolean hasTimeouts() {
128 + return hasTimeouts;
129 + }
130 +
131 + /**
132 + * Returns the list of match keys supported by this table.
133 + * The list is ordered accordingly to the model's table definition.
134 + *
135 + * @return a list of match keys
136 + */
137 + public List<Bmv2ModelTableKey> keys() {
138 + return keys;
139 + }
140 +
141 + /**
142 + * Returns the set of actions supported by this table.
143 + *
144 + * @return a list of actions
145 + */
146 + public Set<Bmv2ModelAction> actions() {
147 + return actions;
148 + }
149 +
150 + @Override
151 + public int hashCode() {
152 + return Objects.hashCode(name, id, matchType, type, maxSize, hasCounters,
153 + hasTimeouts, keys, actions);
154 + }
155 +
156 + @Override
157 + public boolean equals(Object obj) {
158 + if (this == obj) {
159 + return true;
160 + }
161 + if (obj == null || getClass() != obj.getClass()) {
162 + return false;
163 + }
164 + final Bmv2ModelTable other = (Bmv2ModelTable) obj;
165 + return Objects.equal(this.name, other.name)
166 + && Objects.equal(this.id, other.id)
167 + && Objects.equal(this.matchType, other.matchType)
168 + && Objects.equal(this.type, other.type)
169 + && Objects.equal(this.maxSize, other.maxSize)
170 + && Objects.equal(this.hasCounters, other.hasCounters)
171 + && Objects.equal(this.hasTimeouts, other.hasTimeouts)
172 + && Objects.equal(this.keys, other.keys)
173 + && Objects.equal(this.actions, other.actions);
174 + }
175 +
176 + @Override
177 + public String toString() {
178 + return toStringHelper(this)
179 + .add("name", name)
180 + .add("id", id)
181 + .add("matchType", matchType)
182 + .add("type", type)
183 + .add("maxSize", maxSize)
184 + .add("hasCounters", hasCounters)
185 + .add("hasTimeouts", hasTimeouts)
186 + .add("keys", keys)
187 + .add("actions", actions)
188 + .toString();
189 + }
190 +
191 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2.model;
18 +
19 +import com.google.common.base.Objects;
20 +
21 +import static com.google.common.base.MoreObjects.toStringHelper;
22 +
23 +/**
24 + * Representation of a table key.
25 + */
26 +public final class Bmv2ModelTableKey {
27 +
28 + private final String matchType;
29 + private final Bmv2ModelField field;
30 +
31 + /**
32 + * Creates a new table key.
33 + *
34 + * @param matchType match type
35 + * @param field field instance
36 + */
37 + protected Bmv2ModelTableKey(String matchType, Bmv2ModelField field) {
38 + this.matchType = matchType;
39 + this.field = field;
40 + }
41 +
42 + /**
43 + * Returns the match type of this key.
44 + *
45 + * @return a string value
46 + * TODO returns enum of match type
47 + */
48 + public String matchType() {
49 + return matchType;
50 + }
51 +
52 + /**
53 + * Returns the header field instance matched by this key.
54 + *
55 + * @return a header field value
56 + */
57 + public Bmv2ModelField field() {
58 + return field;
59 + }
60 +
61 + @Override
62 + public int hashCode() {
63 + return Objects.hashCode(matchType, field);
64 + }
65 +
66 + @Override
67 + public boolean equals(Object obj) {
68 + if (this == obj) {
69 + return true;
70 + }
71 + if (obj == null || getClass() != obj.getClass()) {
72 + return false;
73 + }
74 + final Bmv2ModelTableKey other = (Bmv2ModelTableKey) obj;
75 + return Objects.equal(this.matchType, other.matchType)
76 + && Objects.equal(this.field, other.field);
77 + }
78 +
79 + @Override
80 + public String toString() {
81 + return toStringHelper(this)
82 + .add("matchType", matchType)
83 + .add("field", field)
84 + .toString();
85 + }
86 +}
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/**
18 + * BMv2 configuration model classes.
19 + */
20 +package org.onosproject.drivers.bmv2.model;
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2014-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.drivers.bmv2;
18 +
19 +import com.eclipsesource.json.Json;
20 +import com.eclipsesource.json.JsonObject;
21 +import com.google.common.testing.EqualsTester;
22 +import org.junit.Before;
23 +import org.junit.Test;
24 +import org.onosproject.drivers.bmv2.model.Bmv2Model;
25 +import org.onosproject.drivers.bmv2.model.Bmv2ModelAction;
26 +import org.onosproject.drivers.bmv2.model.Bmv2ModelHeaderType;
27 +import org.onosproject.drivers.bmv2.model.Bmv2ModelTable;
28 +
29 +import java.io.BufferedReader;
30 +import java.io.InputStreamReader;
31 +
32 +import static org.hamcrest.CoreMatchers.notNullValue;
33 +import static org.hamcrest.MatcherAssert.assertThat;
34 +import static org.hamcrest.Matchers.hasSize;
35 +import static org.hamcrest.Matchers.is;
36 +import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
37 +import static org.hamcrest.core.IsEqual.equalTo;
38 +
39 +/**
40 + * BMv2 model parser test suite.
41 + */
42 +public class Bmv2ModelTest {
43 +
44 + private JsonObject json;
45 + private JsonObject json2;
46 +
47 + @Before
48 + public void setUp() throws Exception {
49 + json = Json.parse(new BufferedReader(new InputStreamReader(
50 + this.getClass().getResourceAsStream("/simple_pipeline.json")))).asObject();
51 + json2 = Json.parse(new BufferedReader(new InputStreamReader(
52 + this.getClass().getResourceAsStream("/simple_pipeline.json")))).asObject();
53 + }
54 +
55 + @Test
56 + public void testParse() throws Exception {
57 + Bmv2Model model = Bmv2Model.parse(json);
58 + Bmv2Model model2 = Bmv2Model.parse(json);
59 +
60 + new EqualsTester()
61 + .addEqualityGroup(model, model2)
62 + .testEquals();
63 +
64 + /* Check header types */
65 + Bmv2ModelHeaderType stdMetaT = model.headerType("standard_metadata_t");
66 + Bmv2ModelHeaderType ethernetT = model.headerType("ethernet_t");
67 + Bmv2ModelHeaderType intrinsicMetaT = model.headerType("intrinsic_metadata_t");
68 +
69 + Bmv2ModelHeaderType stdMetaT2 = model2.headerType("standard_metadata_t");
70 + Bmv2ModelHeaderType ethernetT2 = model2.headerType("ethernet_t");
71 + Bmv2ModelHeaderType intrinsicMetaT2 = model2.headerType("intrinsic_metadata_t");
72 +
73 + new EqualsTester()
74 + .addEqualityGroup(stdMetaT, stdMetaT2)
75 + .addEqualityGroup(ethernetT, ethernetT2)
76 + .addEqualityGroup(intrinsicMetaT, intrinsicMetaT2)
77 + .testEquals();
78 +
79 + // existence
80 + assertThat("Json parsed value is null", stdMetaT, notNullValue());
81 + assertThat("Json parsed value is null", ethernetT, notNullValue());
82 + assertThat("Json parsed value is null", intrinsicMetaT, notNullValue());
83 +
84 + // fields size
85 + assertThat("Incorrect size for header type fields",
86 + stdMetaT.fields(), hasSize(8));
87 + assertThat("Incorrect size for header type fields",
88 + ethernetT.fields(), hasSize(3));
89 + assertThat("Incorrect size for header type fields",
90 + intrinsicMetaT.fields(), hasSize(4));
91 +
92 + // check that fields are in order
93 + assertThat("Incorrect order for header type fields",
94 + stdMetaT.fields(), contains(
95 + stdMetaT.field("ingress_port"),
96 + stdMetaT.field("packet_length"),
97 + stdMetaT.field("egress_spec"),
98 + stdMetaT.field("egress_port"),
99 + stdMetaT.field("egress_instance"),
100 + stdMetaT.field("instance_type"),
101 + stdMetaT.field("clone_spec"),
102 + stdMetaT.field("_padding")));
103 +
104 + /* Check actions */
105 + Bmv2ModelAction floodAction = model.action("flood");
106 + Bmv2ModelAction dropAction = model.action("_drop");
107 + Bmv2ModelAction fwdAction = model.action("fwd");
108 +
109 + Bmv2ModelAction floodAction2 = model2.action("flood");
110 + Bmv2ModelAction dropAction2 = model2.action("_drop");
111 + Bmv2ModelAction fwdAction2 = model2.action("fwd");
112 +
113 + new EqualsTester()
114 + .addEqualityGroup(floodAction, floodAction2)
115 + .addEqualityGroup(dropAction, dropAction2)
116 + .addEqualityGroup(fwdAction, fwdAction2)
117 + .testEquals();
118 +
119 + // existence
120 + assertThat("Json parsed value is null", floodAction, notNullValue());
121 + assertThat("Json parsed value is null", dropAction, notNullValue());
122 + assertThat("Json parsed value is null", fwdAction, notNullValue());
123 +
124 + // runtime data size
125 + assertThat("Incorrect size for action runtime data",
126 + floodAction.runtimeDatas().size(), is(equalTo(0)));
127 + assertThat("Incorrect size for action runtime data",
128 + dropAction.runtimeDatas().size(), is(equalTo(0)));
129 + assertThat("Incorrect size for action runtime data",
130 + fwdAction.runtimeDatas().size(), is(equalTo(1)));
131 +
132 + // runtime data existence and parsing
133 + assertThat("Parsed Json value is null",
134 + fwdAction.runtimeData("port"), notNullValue());
135 + assertThat("Incorrect value for action runtime data bitwidth",
136 + fwdAction.runtimeData("port").bitWidth(), is(equalTo(9)));
137 +
138 + /* Check tables */
139 + Bmv2ModelTable table0 = model.table(0);
140 + Bmv2ModelTable table02 = model2.table(0);
141 +
142 + new EqualsTester()
143 + .addEqualityGroup(table0, table02)
144 + .testEquals();
145 +
146 + // existence
147 + assertThat("Parsed Json value is null", table0, notNullValue());
148 +
149 + // id and name correspondence
150 + assertThat("Incorrect value for table name",
151 + table0.name(), is(equalTo("table0")));
152 +
153 + // keys size
154 + assertThat("Incorrect size for table keys",
155 + table0.keys().size(), is(equalTo(4)));
156 +
157 + // key match type
158 + assertThat("Incorrect value for table key match type",
159 + table0.keys().get(0).matchType(), is(equalTo("ternary")));
160 +
161 + // header type
162 + assertThat("Incorrect value for table key header type",
163 + table0.keys().get(0).field().header().type(), is(equalTo(stdMetaT)));
164 + }
165 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "header_types": [
3 + {
4 + "name": "standard_metadata_t",
5 + "id": 0,
6 + "fields": [
7 + [
8 + "ingress_port",
9 + 9
10 + ],
11 + [
12 + "packet_length",
13 + 32
14 + ],
15 + [
16 + "egress_spec",
17 + 9
18 + ],
19 + [
20 + "egress_port",
21 + 9
22 + ],
23 + [
24 + "egress_instance",
25 + 32
26 + ],
27 + [
28 + "instance_type",
29 + 32
30 + ],
31 + [
32 + "clone_spec",
33 + 32
34 + ],
35 + [
36 + "_padding",
37 + 5
38 + ]
39 + ],
40 + "length_exp": null,
41 + "max_length": null
42 + },
43 + {
44 + "name": "ethernet_t",
45 + "id": 1,
46 + "fields": [
47 + [
48 + "dstAddr",
49 + 48
50 + ],
51 + [
52 + "srcAddr",
53 + 48
54 + ],
55 + [
56 + "etherType",
57 + 16
58 + ]
59 + ],
60 + "length_exp": null,
61 + "max_length": null
62 + },
63 + {
64 + "name": "intrinsic_metadata_t",
65 + "id": 2,
66 + "fields": [
67 + [
68 + "ingress_global_timestamp",
69 + 32
70 + ],
71 + [
72 + "lf_field_list",
73 + 32
74 + ],
75 + [
76 + "mcast_grp",
77 + 16
78 + ],
79 + [
80 + "egress_rid",
81 + 16
82 + ]
83 + ],
84 + "length_exp": null,
85 + "max_length": null
86 + },
87 + {
88 + "name": "cpu_header_t",
89 + "id": 3,
90 + "fields": [
91 + [
92 + "device",
93 + 8
94 + ],
95 + [
96 + "reason",
97 + 8
98 + ]
99 + ],
100 + "length_exp": null,
101 + "max_length": null
102 + }
103 + ],
104 + "headers": [
105 + {
106 + "name": "standard_metadata",
107 + "id": 0,
108 + "header_type": "standard_metadata_t",
109 + "metadata": true
110 + },
111 + {
112 + "name": "ethernet",
113 + "id": 1,
114 + "header_type": "ethernet_t",
115 + "metadata": false
116 + },
117 + {
118 + "name": "intrinsic_metadata",
119 + "id": 2,
120 + "header_type": "intrinsic_metadata_t",
121 + "metadata": true
122 + },
123 + {
124 + "name": "cpu_header",
125 + "id": 3,
126 + "header_type": "cpu_header_t",
127 + "metadata": false
128 + }
129 + ],
130 + "header_stacks": [],
131 + "parsers": [
132 + {
133 + "name": "parser",
134 + "id": 0,
135 + "init_state": "start",
136 + "parse_states": [
137 + {
138 + "name": "start",
139 + "id": 0,
140 + "parser_ops": [],
141 + "transition_key": [
142 + {
143 + "type": "lookahead",
144 + "value": [
145 + 0,
146 + 64
147 + ]
148 + }
149 + ],
150 + "transitions": [
151 + {
152 + "value": "0x0000000000000000",
153 + "mask": null,
154 + "next_state": "parse_cpu_header"
155 + },
156 + {
157 + "value": "default",
158 + "mask": null,
159 + "next_state": "parse_ethernet"
160 + }
161 + ]
162 + },
163 + {
164 + "name": "parse_cpu_header",
165 + "id": 1,
166 + "parser_ops": [
167 + {
168 + "op": "extract",
169 + "parameters": [
170 + {
171 + "type": "regular",
172 + "value": "cpu_header"
173 + }
174 + ]
175 + }
176 + ],
177 + "transition_key": [],
178 + "transitions": [
179 + {
180 + "value": "default",
181 + "mask": null,
182 + "next_state": "parse_ethernet"
183 + }
184 + ]
185 + },
186 + {
187 + "name": "parse_ethernet",
188 + "id": 2,
189 + "parser_ops": [
190 + {
191 + "op": "extract",
192 + "parameters": [
193 + {
194 + "type": "regular",
195 + "value": "ethernet"
196 + }
197 + ]
198 + }
199 + ],
200 + "transition_key": [],
201 + "transitions": [
202 + {
203 + "value": "default",
204 + "mask": null,
205 + "next_state": null
206 + }
207 + ]
208 + }
209 + ]
210 + }
211 + ],
212 + "deparsers": [
213 + {
214 + "name": "deparser",
215 + "id": 0,
216 + "order": [
217 + "cpu_header",
218 + "ethernet"
219 + ]
220 + }
221 + ],
222 + "meter_arrays": [],
223 + "actions": [
224 + {
225 + "name": "flood",
226 + "id": 0,
227 + "runtime_data": [],
228 + "primitives": [
229 + {
230 + "op": "modify_field",
231 + "parameters": [
232 + {
233 + "type": "field",
234 + "value": [
235 + "intrinsic_metadata",
236 + "mcast_grp"
237 + ]
238 + },
239 + {
240 + "type": "field",
241 + "value": [
242 + "standard_metadata",
243 + "ingress_port"
244 + ]
245 + }
246 + ]
247 + }
248 + ]
249 + },
250 + {
251 + "name": "_drop",
252 + "id": 1,
253 + "runtime_data": [],
254 + "primitives": [
255 + {
256 + "op": "modify_field",
257 + "parameters": [
258 + {
259 + "type": "field",
260 + "value": [
261 + "standard_metadata",
262 + "egress_spec"
263 + ]
264 + },
265 + {
266 + "type": "hexstr",
267 + "value": "0x1ff"
268 + }
269 + ]
270 + }
271 + ]
272 + },
273 + {
274 + "name": "fwd",
275 + "id": 2,
276 + "runtime_data": [
277 + {
278 + "name": "port",
279 + "bitwidth": 9
280 + }
281 + ],
282 + "primitives": [
283 + {
284 + "op": "modify_field",
285 + "parameters": [
286 + {
287 + "type": "field",
288 + "value": [
289 + "standard_metadata",
290 + "egress_spec"
291 + ]
292 + },
293 + {
294 + "type": "runtime_data",
295 + "value": 0
296 + }
297 + ]
298 + }
299 + ]
300 + },
301 + {
302 + "name": "send_to_cpu",
303 + "id": 3,
304 + "runtime_data": [
305 + {
306 + "name": "device",
307 + "bitwidth": 8
308 + },
309 + {
310 + "name": "reason",
311 + "bitwidth": 8
312 + }
313 + ],
314 + "primitives": [
315 + {
316 + "op": "add_header",
317 + "parameters": [
318 + {
319 + "type": "header",
320 + "value": "cpu_header"
321 + }
322 + ]
323 + },
324 + {
325 + "op": "modify_field",
326 + "parameters": [
327 + {
328 + "type": "field",
329 + "value": [
330 + "cpu_header",
331 + "device"
332 + ]
333 + },
334 + {
335 + "type": "runtime_data",
336 + "value": 0
337 + }
338 + ]
339 + },
340 + {
341 + "op": "modify_field",
342 + "parameters": [
343 + {
344 + "type": "field",
345 + "value": [
346 + "cpu_header",
347 + "reason"
348 + ]
349 + },
350 + {
351 + "type": "runtime_data",
352 + "value": 1
353 + }
354 + ]
355 + },
356 + {
357 + "op": "modify_field",
358 + "parameters": [
359 + {
360 + "type": "field",
361 + "value": [
362 + "standard_metadata",
363 + "egress_spec"
364 + ]
365 + },
366 + {
367 + "type": "hexstr",
368 + "value": "0xfa"
369 + }
370 + ]
371 + }
372 + ]
373 + }
374 + ],
375 + "pipelines": [
376 + {
377 + "name": "ingress",
378 + "id": 0,
379 + "init_table": "table0",
380 + "tables": [
381 + {
382 + "name": "table0",
383 + "id": 0,
384 + "match_type": "ternary",
385 + "type": "simple",
386 + "max_size": 16384,
387 + "with_counters": false,
388 + "direct_meters": null,
389 + "support_timeout": false,
390 + "key": [
391 + {
392 + "match_type": "ternary",
393 + "target": [
394 + "standard_metadata",
395 + "ingress_port"
396 + ],
397 + "mask": null
398 + },
399 + {
400 + "match_type": "ternary",
401 + "target": [
402 + "ethernet",
403 + "dstAddr"
404 + ],
405 + "mask": null
406 + },
407 + {
408 + "match_type": "ternary",
409 + "target": [
410 + "ethernet",
411 + "srcAddr"
412 + ],
413 + "mask": null
414 + },
415 + {
416 + "match_type": "ternary",
417 + "target": [
418 + "ethernet",
419 + "etherType"
420 + ],
421 + "mask": null
422 + }
423 + ],
424 + "actions": [
425 + "fwd",
426 + "flood",
427 + "send_to_cpu",
428 + "_drop"
429 + ],
430 + "next_tables": {
431 + "fwd": null,
432 + "flood": null,
433 + "send_to_cpu": null,
434 + "_drop": null
435 + },
436 + "default_action": null
437 + }
438 + ],
439 + "conditionals": []
440 + },
441 + {
442 + "name": "egress",
443 + "id": 1,
444 + "init_table": null,
445 + "tables": [],
446 + "conditionals": []
447 + }
448 + ],
449 + "calculations": [],
450 + "checksums": [],
451 + "learn_lists": [],
452 + "field_lists": [],
453 + "counter_arrays": [],
454 + "register_arrays": [],
455 + "force_arith": [
456 + [
457 + "standard_metadata",
458 + "ingress_port"
459 + ],
460 + [
461 + "standard_metadata",
462 + "packet_length"
463 + ],
464 + [
465 + "standard_metadata",
466 + "egress_spec"
467 + ],
468 + [
469 + "standard_metadata",
470 + "egress_port"
471 + ],
472 + [
473 + "standard_metadata",
474 + "egress_instance"
475 + ],
476 + [
477 + "standard_metadata",
478 + "instance_type"
479 + ],
480 + [
481 + "standard_metadata",
482 + "clone_spec"
483 + ],
484 + [
485 + "standard_metadata",
486 + "_padding"
487 + ],
488 + [
489 + "intrinsic_metadata",
490 + "ingress_global_timestamp"
491 + ],
492 + [
493 + "intrinsic_metadata",
494 + "lf_field_list"
495 + ],
496 + [
497 + "intrinsic_metadata",
498 + "mcast_grp"
499 + ],
500 + [
501 + "intrinsic_metadata",
502 + "egress_rid"
503 + ]
504 + ]
505 +}
...\ No newline at end of file ...\ No newline at end of file