Carmelo Cascone
Committed by Jonathan Hart

Removed hardcoded model from BMv2 driver

Now it uses the model stored in device annotations. Also refactored flow
rule translator classes to reflect this change.

Change-Id: I46541bcc2ab5a267eef4becb6250b9a99684056a
...@@ -16,10 +16,15 @@ ...@@ -16,10 +16,15 @@
16 16
17 package org.onosproject.drivers.bmv2; 17 package org.onosproject.drivers.bmv2;
18 18
19 +import com.eclipsesource.json.Json;
20 +import com.google.common.cache.CacheBuilder;
21 +import com.google.common.cache.CacheLoader;
22 +import com.google.common.cache.LoadingCache;
19 import com.google.common.collect.Lists; 23 import com.google.common.collect.Lists;
20 import com.google.common.collect.Maps; 24 import com.google.common.collect.Maps;
21 import org.apache.commons.lang3.tuple.Pair; 25 import org.apache.commons.lang3.tuple.Pair;
22 import org.apache.commons.lang3.tuple.Triple; 26 import org.apache.commons.lang3.tuple.Triple;
27 +import org.onosproject.bmv2.api.model.Bmv2Model;
23 import org.onosproject.bmv2.api.runtime.Bmv2Client; 28 import org.onosproject.bmv2.api.runtime.Bmv2Client;
24 import org.onosproject.bmv2.api.runtime.Bmv2MatchKey; 29 import org.onosproject.bmv2.api.runtime.Bmv2MatchKey;
25 import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; 30 import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException;
...@@ -28,7 +33,10 @@ import org.onosproject.bmv2.ctl.Bmv2ThriftClient; ...@@ -28,7 +33,10 @@ import org.onosproject.bmv2.ctl.Bmv2ThriftClient;
28 import org.onosproject.drivers.bmv2.translators.Bmv2DefaultFlowRuleTranslator; 33 import org.onosproject.drivers.bmv2.translators.Bmv2DefaultFlowRuleTranslator;
29 import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslator; 34 import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslator;
30 import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslatorException; 35 import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslatorException;
36 +import org.onosproject.drivers.bmv2.translators.Bmv2SimpleTranslatorConfig;
37 +import org.onosproject.net.Device;
31 import org.onosproject.net.DeviceId; 38 import org.onosproject.net.DeviceId;
39 +import org.onosproject.net.device.DeviceService;
32 import org.onosproject.net.driver.AbstractHandlerBehaviour; 40 import org.onosproject.net.driver.AbstractHandlerBehaviour;
33 import org.onosproject.net.flow.DefaultFlowEntry; 41 import org.onosproject.net.flow.DefaultFlowEntry;
34 import org.onosproject.net.flow.FlowEntry; 42 import org.onosproject.net.flow.FlowEntry;
...@@ -41,6 +49,8 @@ import java.util.Collection; ...@@ -41,6 +49,8 @@ import java.util.Collection;
41 import java.util.Collections; 49 import java.util.Collections;
42 import java.util.List; 50 import java.util.List;
43 import java.util.concurrent.ConcurrentMap; 51 import java.util.concurrent.ConcurrentMap;
52 +import java.util.concurrent.ExecutionException;
53 +import java.util.concurrent.TimeUnit;
44 54
45 /** 55 /**
46 * Flow rule programmable device behaviour implementation for BMv2. 56 * Flow rule programmable device behaviour implementation for BMv2.
...@@ -50,10 +60,21 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour ...@@ -50,10 +60,21 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour
50 60
51 private static final Logger LOG = 61 private static final Logger LOG =
52 LoggerFactory.getLogger(Bmv2FlowRuleProgrammable.class); 62 LoggerFactory.getLogger(Bmv2FlowRuleProgrammable.class);
53 - // There's no Bmv2 client method to poll flow entries from the device device. gitNeed a local store. 63 +
64 + // There's no Bmv2 client method to poll flow entries from the device device. Need a local store.
54 private static final ConcurrentMap<Triple<DeviceId, String, Bmv2MatchKey>, Pair<Long, FlowEntry>> 65 private static final ConcurrentMap<Triple<DeviceId, String, Bmv2MatchKey>, Pair<Long, FlowEntry>>
55 ENTRIES_MAP = Maps.newConcurrentMap(); 66 ENTRIES_MAP = Maps.newConcurrentMap();
56 - private static final Bmv2FlowRuleTranslator TRANSLATOR = new Bmv2DefaultFlowRuleTranslator(); 67 +
68 + // Cache model objects instead of parsing the JSON each time.
69 + private static final LoadingCache<String, Bmv2Model> MODEL_CACHE = CacheBuilder.newBuilder()
70 + .expireAfterAccess(60, TimeUnit.SECONDS)
71 + .build(new CacheLoader<String, Bmv2Model>() {
72 + @Override
73 + public Bmv2Model load(String jsonString) throws Exception {
74 + // Expensive call.
75 + return Bmv2Model.parse(Json.parse(jsonString).asObject());
76 + }
77 + });
57 78
58 @Override 79 @Override
59 public Collection<FlowEntry> getFlowEntries() { 80 public Collection<FlowEntry> getFlowEntries() {
...@@ -96,6 +117,8 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour ...@@ -96,6 +117,8 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour
96 return Collections.emptyList(); 117 return Collections.emptyList();
97 } 118 }
98 119
120 + Bmv2FlowRuleTranslator translator = getTranslator(deviceId);
121 +
99 List<FlowRule> processedFlowRules = Lists.newArrayList(); 122 List<FlowRule> processedFlowRules = Lists.newArrayList();
100 123
101 for (FlowRule rule : rules) { 124 for (FlowRule rule : rules) {
...@@ -103,7 +126,7 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour ...@@ -103,7 +126,7 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour
103 Bmv2TableEntry bmv2Entry; 126 Bmv2TableEntry bmv2Entry;
104 127
105 try { 128 try {
106 - bmv2Entry = TRANSLATOR.translate(rule); 129 + bmv2Entry = translator.translate(rule);
107 } catch (Bmv2FlowRuleTranslatorException e) { 130 } catch (Bmv2FlowRuleTranslatorException e) {
108 LOG.error("Unable to translate flow rule: {}", e.getMessage()); 131 LOG.error("Unable to translate flow rule: {}", e.getMessage());
109 continue; 132 continue;
...@@ -159,6 +182,46 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour ...@@ -159,6 +182,46 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour
159 return processedFlowRules; 182 return processedFlowRules;
160 } 183 }
161 184
185 + /**
186 + * Gets the appropriate flow rule translator based on the device running configuration.
187 + *
188 + * @param deviceId a device id
189 + * @return a flow rule translator
190 + */
191 + private Bmv2FlowRuleTranslator getTranslator(DeviceId deviceId) {
192 +
193 + DeviceService deviceService = handler().get(DeviceService.class);
194 + if (deviceService == null) {
195 + LOG.error("Unable to get device service");
196 + return null;
197 + }
198 +
199 + Device device = deviceService.getDevice(deviceId);
200 + if (device == null) {
201 + LOG.error("Unable to get device {}", deviceId);
202 + return null;
203 + }
204 +
205 + String jsonString = device.annotations().value("bmv2JsonConfigValue");
206 + if (jsonString == null) {
207 + LOG.error("Unable to read bmv2 JSON config from device {}", deviceId);
208 + return null;
209 + }
210 +
211 + Bmv2Model model;
212 + try {
213 + model = MODEL_CACHE.get(jsonString);
214 + } catch (ExecutionException e) {
215 + LOG.error("Unable to parse bmv2 JSON config for device {}:", deviceId, e.getCause());
216 + return null;
217 + }
218 +
219 + // TODO: get translator config dynamically.
220 + // Now it's hardcoded, selection should be based on the device bmv2 model.
221 + Bmv2FlowRuleTranslator.TranslatorConfig translatorConfig = new Bmv2SimpleTranslatorConfig(model);
222 + return new Bmv2DefaultFlowRuleTranslator(translatorConfig);
223 + }
224 +
162 private enum Operation { 225 private enum Operation {
163 APPLY, REMOVE 226 APPLY, REMOVE
164 } 227 }
......
...@@ -18,7 +18,6 @@ package org.onosproject.drivers.bmv2.translators; ...@@ -18,7 +18,6 @@ package org.onosproject.drivers.bmv2.translators;
18 18
19 import com.google.common.annotations.Beta; 19 import com.google.common.annotations.Beta;
20 import org.onlab.util.ImmutableByteSequence; 20 import org.onlab.util.ImmutableByteSequence;
21 -import org.onosproject.bmv2.api.model.Bmv2Model;
22 import org.onosproject.bmv2.api.model.Bmv2ModelField; 21 import org.onosproject.bmv2.api.model.Bmv2ModelField;
23 import org.onosproject.bmv2.api.model.Bmv2ModelTable; 22 import org.onosproject.bmv2.api.model.Bmv2ModelTable;
24 import org.onosproject.bmv2.api.model.Bmv2ModelTableKey; 23 import org.onosproject.bmv2.api.model.Bmv2ModelTableKey;
...@@ -66,9 +65,11 @@ import org.onosproject.net.flow.instructions.Instructions.ExtensionInstructionWr ...@@ -66,9 +65,11 @@ import org.onosproject.net.flow.instructions.Instructions.ExtensionInstructionWr
66 @Beta 65 @Beta
67 public class Bmv2DefaultFlowRuleTranslator implements Bmv2FlowRuleTranslator { 66 public class Bmv2DefaultFlowRuleTranslator implements Bmv2FlowRuleTranslator {
68 67
69 - // TODO: config is harcoded now, instead it should be selected based on device model 68 + private final TranslatorConfig config;
70 - private final TranslatorConfig config = new Bmv2SimpleTranslatorConfig(); 69 +
71 - private final Bmv2Model model = config.model(); 70 + public Bmv2DefaultFlowRuleTranslator(TranslatorConfig config) {
71 + this.config = config;
72 + }
72 73
73 private static Bmv2TernaryMatchParam buildTernaryParam(Bmv2ModelField field, Criterion criterion, int byteWidth) 74 private static Bmv2TernaryMatchParam buildTernaryParam(Bmv2ModelField field, Criterion criterion, int byteWidth)
74 throws Bmv2FlowRuleTranslatorException { 75 throws Bmv2FlowRuleTranslatorException {
...@@ -201,7 +202,7 @@ public class Bmv2DefaultFlowRuleTranslator implements Bmv2FlowRuleTranslator { ...@@ -201,7 +202,7 @@ public class Bmv2DefaultFlowRuleTranslator implements Bmv2FlowRuleTranslator {
201 202
202 int tableId = rule.tableId(); 203 int tableId = rule.tableId();
203 204
204 - Bmv2ModelTable table = model.table(tableId); 205 + Bmv2ModelTable table = config.model().table(tableId);
205 206
206 if (table == null) { 207 if (table == null) {
207 throw new Bmv2FlowRuleTranslatorException("Unknown table ID: " + tableId); 208 throw new Bmv2FlowRuleTranslatorException("Unknown table ID: " + tableId);
......
1 +/*
2 + * Copyright 2016-present 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.translators;
18 +
19 +import com.google.common.annotations.Beta;
20 +import org.onosproject.bmv2.api.model.Bmv2Model;
21 +import org.onosproject.net.flow.criteria.Criterion;
22 +
23 +import java.util.Map;
24 +
25 +import static org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslator.TranslatorConfig;
26 +
27 +/**
28 + * Default implementation of a BMv2 flow rule translator configuration.
29 + */
30 +@Beta
31 +public abstract class Bmv2DefaultTranslatorConfig implements TranslatorConfig {
32 +
33 + private final Bmv2Model model;
34 + private final Map<String, Criterion.Type> fieldMap;
35 +
36 + /**
37 + * Creates a new translator configuration.
38 + *
39 + * @param model a BMv2 packet processing model
40 + * @param fieldMap a field-to-criterion type map
41 + */
42 + protected Bmv2DefaultTranslatorConfig(Bmv2Model model, Map<String, Criterion.Type> fieldMap) {
43 + this.model = model;
44 + this.fieldMap = fieldMap;
45 + }
46 +
47 + @Override
48 + public Bmv2Model model() {
49 + return this.model;
50 + }
51 +
52 + @Override
53 + public Map<String, Criterion.Type> fieldToCriterionTypeMap() {
54 + return this.fieldMap;
55 + }
56 +}
...@@ -16,10 +16,8 @@ ...@@ -16,10 +16,8 @@
16 16
17 package org.onosproject.drivers.bmv2.translators; 17 package org.onosproject.drivers.bmv2.translators;
18 18
19 -import com.eclipsesource.json.Json;
20 -import com.eclipsesource.json.JsonObject;
21 import com.google.common.annotations.Beta; 19 import com.google.common.annotations.Beta;
22 -import com.google.common.collect.Maps; 20 +import com.google.common.collect.ImmutableMap;
23 import org.onlab.util.ImmutableByteSequence; 21 import org.onlab.util.ImmutableByteSequence;
24 import org.onosproject.bmv2.api.model.Bmv2Model; 22 import org.onosproject.bmv2.api.model.Bmv2Model;
25 import org.onosproject.bmv2.api.runtime.Bmv2Action; 23 import org.onosproject.bmv2.api.runtime.Bmv2Action;
...@@ -29,10 +27,6 @@ import org.onosproject.net.flow.criteria.Criterion; ...@@ -29,10 +27,6 @@ import org.onosproject.net.flow.criteria.Criterion;
29 import org.onosproject.net.flow.instructions.Instruction; 27 import org.onosproject.net.flow.instructions.Instruction;
30 import org.onosproject.net.flow.instructions.Instructions; 28 import org.onosproject.net.flow.instructions.Instructions;
31 29
32 -import java.io.BufferedReader;
33 -import java.io.IOException;
34 -import java.io.InputStream;
35 -import java.io.InputStreamReader;
36 import java.util.Map; 30 import java.util.Map;
37 31
38 /** 32 /**
...@@ -40,24 +34,21 @@ import java.util.Map; ...@@ -40,24 +34,21 @@ import java.util.Map;
40 * simple.p4 model. 34 * simple.p4 model.
41 */ 35 */
42 @Beta 36 @Beta
43 -public class Bmv2SimpleTranslatorConfig implements Bmv2FlowRuleTranslator.TranslatorConfig { 37 +public class Bmv2SimpleTranslatorConfig extends Bmv2DefaultTranslatorConfig {
44 38
45 - private static final String JSON_CONFIG_PATH = "/simple.json"; 39 + // Lazily populate field map.
46 - private final Map<String, Criterion.Type> fieldMap = Maps.newHashMap(); 40 + private static final Map<String, Criterion.Type> FIELD_MAP = ImmutableMap.of(
47 - private final Bmv2Model model; 41 + "standard_metadata.ingress_port", Criterion.Type.IN_PORT,
42 + "ethernet.dstAddr", Criterion.Type.ETH_DST,
43 + "ethernet.srcAddr", Criterion.Type.ETH_SRC,
44 + "ethernet.etherType", Criterion.Type.ETH_TYPE);
48 45
49 /** 46 /**
50 * Creates a new simple pipeline translator configuration. 47 * Creates a new simple pipeline translator configuration.
51 */ 48 */
52 - public Bmv2SimpleTranslatorConfig() { 49 + public Bmv2SimpleTranslatorConfig(Bmv2Model model) {
53 - 50 + // Populate fieldMap.
54 - this.model = getModel(); 51 + super(model, FIELD_MAP);
55 -
56 - // populate fieldMap
57 - fieldMap.put("standard_metadata.ingress_port", Criterion.Type.IN_PORT);
58 - fieldMap.put("ethernet.dstAddr", Criterion.Type.ETH_DST);
59 - fieldMap.put("ethernet.srcAddr", Criterion.Type.ETH_SRC);
60 - fieldMap.put("ethernet.etherType", Criterion.Type.ETH_TYPE);
61 } 52 }
62 53
63 private static Bmv2Action buildDropAction() { 54 private static Bmv2Action buildDropAction() {
...@@ -94,41 +85,16 @@ public class Bmv2SimpleTranslatorConfig implements Bmv2FlowRuleTranslator.Transl ...@@ -94,41 +85,16 @@ public class Bmv2SimpleTranslatorConfig implements Bmv2FlowRuleTranslator.Transl
94 return actionBuilder.build(); 85 return actionBuilder.build();
95 } 86 }
96 87
97 - private static Bmv2Model getModel() {
98 - InputStream inputStream = Bmv2SimpleTranslatorConfig.class
99 - .getResourceAsStream(JSON_CONFIG_PATH);
100 - InputStreamReader reader = new InputStreamReader(inputStream);
101 - BufferedReader bufReader = new BufferedReader(reader);
102 - JsonObject json = null;
103 - try {
104 - json = Json.parse(bufReader).asObject();
105 - } catch (IOException e) {
106 - throw new RuntimeException("Unable to parse JSON file: " + e.getMessage());
107 - }
108 -
109 - return Bmv2Model.parse(json);
110 - }
111 -
112 - @Override
113 - public Bmv2Model model() {
114 - return this.model;
115 - }
116 -
117 - @Override
118 - public Map<String, Criterion.Type> fieldToCriterionTypeMap() {
119 - return fieldMap;
120 - }
121 -
122 @Override 88 @Override
123 public Bmv2Action buildAction(TrafficTreatment treatment) 89 public Bmv2Action buildAction(TrafficTreatment treatment)
124 throws Bmv2FlowRuleTranslatorException { 90 throws Bmv2FlowRuleTranslatorException {
125 91
126 92
127 if (treatment.allInstructions().size() == 0) { 93 if (treatment.allInstructions().size() == 0) {
128 - // no instructions means drop 94 + // No instructions means drop.
129 return buildDropAction(); 95 return buildDropAction();
130 } else if (treatment.allInstructions().size() > 1) { 96 } else if (treatment.allInstructions().size() > 1) {
131 - // otherwise, we understand treatments with only 1 instruction 97 + // Otherwise, we understand treatments with only 1 instruction.
132 throw new Bmv2FlowRuleTranslatorException( 98 throw new Bmv2FlowRuleTranslatorException(
133 "Treatment not supported, more than 1 instructions found: " 99 "Treatment not supported, more than 1 instructions found: "
134 + treatment.toString()); 100 + treatment.toString());
......
...@@ -16,7 +16,10 @@ ...@@ -16,7 +16,10 @@
16 16
17 package org.onosproject.drivers.bmv2; 17 package org.onosproject.drivers.bmv2;
18 18
19 +import com.eclipsesource.json.Json;
20 +import com.eclipsesource.json.JsonObject;
19 import com.google.common.testing.EqualsTester; 21 import com.google.common.testing.EqualsTester;
22 +import org.junit.Before;
20 import org.junit.Test; 23 import org.junit.Test;
21 import org.onlab.packet.MacAddress; 24 import org.onlab.packet.MacAddress;
22 import org.onosproject.bmv2.api.model.Bmv2Model; 25 import org.onosproject.bmv2.api.model.Bmv2Model;
...@@ -26,6 +29,7 @@ import org.onosproject.core.ApplicationId; ...@@ -26,6 +29,7 @@ import org.onosproject.core.ApplicationId;
26 import org.onosproject.core.DefaultApplicationId; 29 import org.onosproject.core.DefaultApplicationId;
27 import org.onosproject.drivers.bmv2.translators.Bmv2DefaultFlowRuleTranslator; 30 import org.onosproject.drivers.bmv2.translators.Bmv2DefaultFlowRuleTranslator;
28 import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslator; 31 import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslator;
32 +import org.onosproject.drivers.bmv2.translators.Bmv2SimpleTranslatorConfig;
29 import org.onosproject.net.DeviceId; 33 import org.onosproject.net.DeviceId;
30 import org.onosproject.net.PortNumber; 34 import org.onosproject.net.PortNumber;
31 import org.onosproject.net.flow.DefaultFlowRule; 35 import org.onosproject.net.flow.DefaultFlowRule;
...@@ -35,6 +39,10 @@ import org.onosproject.net.flow.FlowRule; ...@@ -35,6 +39,10 @@ import org.onosproject.net.flow.FlowRule;
35 import org.onosproject.net.flow.TrafficSelector; 39 import org.onosproject.net.flow.TrafficSelector;
36 import org.onosproject.net.flow.TrafficTreatment; 40 import org.onosproject.net.flow.TrafficTreatment;
37 41
42 +import java.io.BufferedReader;
43 +import java.io.IOException;
44 +import java.io.InputStream;
45 +import java.io.InputStreamReader;
38 import java.util.Random; 46 import java.util.Random;
39 47
40 import static org.hamcrest.CoreMatchers.equalTo; 48 import static org.hamcrest.CoreMatchers.equalTo;
...@@ -46,9 +54,30 @@ import static org.hamcrest.MatcherAssert.assertThat; ...@@ -46,9 +54,30 @@ import static org.hamcrest.MatcherAssert.assertThat;
46 */ 54 */
47 public class Bmv2DefaultFlowRuleTranslatorTest { 55 public class Bmv2DefaultFlowRuleTranslatorTest {
48 56
57 + private static final String JSON_CONFIG_PATH = "/simple.json";
49 private Random random = new Random(); 58 private Random random = new Random();
50 - private Bmv2FlowRuleTranslator translator = new Bmv2DefaultFlowRuleTranslator(); 59 + private Bmv2Model model;
51 - private Bmv2Model model = translator.config().model(); 60 + private Bmv2FlowRuleTranslator.TranslatorConfig config;
61 + private Bmv2FlowRuleTranslator translator;
62 +
63 + @Before
64 + public void setUp() throws Exception {
65 + InputStream inputStream = Bmv2SimpleTranslatorConfig.class
66 + .getResourceAsStream(JSON_CONFIG_PATH);
67 + InputStreamReader reader = new InputStreamReader(inputStream);
68 + BufferedReader bufReader = new BufferedReader(reader);
69 + JsonObject json = null;
70 + try {
71 + json = Json.parse(bufReader).asObject();
72 + } catch (IOException e) {
73 + throw new RuntimeException("Unable to parse JSON file: " + e.getMessage());
74 + }
75 +
76 + this.model = Bmv2Model.parse(json);
77 + this.config = new Bmv2SimpleTranslatorConfig(model);
78 + this.translator = new Bmv2DefaultFlowRuleTranslator(config);
79 +
80 + }
52 81
53 82
54 @Test 83 @Test
......
1 { 1 {
2 - "header_types": [ 2 + "header_types": [
3 - { 3 + {
4 - "name": "standard_metadata_t", 4 + "name": "standard_metadata_t",
5 - "id": 0, 5 + "id": 0,
6 - "fields": [ 6 + "fields": [
7 - [ 7 + [
8 - "ingress_port", 8 + "ingress_port",
9 - 9 9 + 9
10 - ], 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 + "headers": [
89 + {
90 + "name": "standard_metadata",
91 + "id": 0,
92 + "header_type": "standard_metadata_t",
93 + "metadata": true
94 + },
95 + {
96 + "name": "ethernet",
97 + "id": 1,
98 + "header_type": "ethernet_t",
99 + "metadata": false
100 + },
101 + {
102 + "name": "intrinsic_metadata",
103 + "id": 2,
104 + "header_type": "intrinsic_metadata_t",
105 + "metadata": true
106 + }
107 + ],
108 + "header_stacks": [],
109 + "parsers": [
110 + {
111 + "name": "parser",
112 + "id": 0,
113 + "init_state": "start",
114 + "parse_states": [
115 + {
116 + "name": "start",
117 + "id": 0,
118 + "parser_ops": [],
119 + "transition_key": [],
120 + "transitions": [
121 + {
122 + "value": "default",
123 + "mask": null,
124 + "next_state": "parse_ethernet"
125 + }
126 + ]
127 + },
128 + {
129 + "name": "parse_ethernet",
130 + "id": 1,
131 + "parser_ops": [
132 + {
133 + "op": "extract",
134 + "parameters": [
135 + {
136 + "type": "regular",
137 + "value": "ethernet"
138 + }
139 + ]
140 + }
141 + ],
142 + "transition_key": [],
143 + "transitions": [
144 + {
145 + "value": "default",
146 + "mask": null,
147 + "next_state": null
148 + }
149 + ]
150 + }
151 + ]
152 + }
153 + ],
154 + "deparsers": [
155 + {
156 + "name": "deparser",
157 + "id": 0,
158 + "order": [
159 + "ethernet"
160 + ]
161 + }
162 + ],
163 + "meter_arrays": [],
164 + "actions": [
165 + {
166 + "name": "flood",
167 + "id": 0,
168 + "runtime_data": [],
169 + "primitives": [
170 + {
171 + "op": "modify_field",
172 + "parameters": [
173 + {
174 + "type": "field",
175 + "value": [
176 + "intrinsic_metadata",
177 + "mcast_grp"
178 + ]
179 + },
180 + {
181 + "type": "field",
182 + "value": [
183 + "standard_metadata",
184 + "ingress_port"
185 + ]
186 + }
187 + ]
188 + }
189 + ]
190 + },
191 + {
192 + "name": "_drop",
193 + "id": 1,
194 + "runtime_data": [],
195 + "primitives": [
196 + {
197 + "op": "modify_field",
198 + "parameters": [
199 + {
200 + "type": "field",
201 + "value": [
202 + "standard_metadata",
203 + "egress_spec"
204 + ]
205 + },
206 + {
207 + "type": "hexstr",
208 + "value": "0x1ff"
209 + }
210 + ]
211 + }
212 + ]
213 + },
214 + {
215 + "name": "fwd",
216 + "id": 2,
217 + "runtime_data": [
218 + {
219 + "name": "port",
220 + "bitwidth": 9
221 + }
222 + ],
223 + "primitives": [
224 + {
225 + "op": "modify_field",
226 + "parameters": [
227 + {
228 + "type": "field",
229 + "value": [
230 + "standard_metadata",
231 + "egress_spec"
232 + ]
233 + },
234 + {
235 + "type": "runtime_data",
236 + "value": 0
237 + }
238 + ]
239 + }
240 + ]
241 + },
242 + {
243 + "name": "push_to_cp",
244 + "id": 3,
245 + "runtime_data": [],
246 + "primitives": [
247 + {
248 + "op": "modify_field",
249 + "parameters": [
250 + {
251 + "type": "field",
252 + "value": [
253 + "standard_metadata",
254 + "egress_spec"
255 + ]
256 + },
257 + {
258 + "type": "hexstr",
259 + "value": "0x200"
260 + }
261 + ]
262 + }
263 + ]
264 + }
265 + ],
266 + "pipelines": [
267 + {
268 + "name": "ingress",
269 + "id": 0,
270 + "init_table": "table0",
271 + "tables": [
272 + {
273 + "name": "table0",
274 + "id": 0,
275 + "match_type": "ternary",
276 + "type": "simple",
277 + "max_size": 16384,
278 + "with_counters": false,
279 + "direct_meters": null,
280 + "support_timeout": false,
281 + "key": [
282 + {
283 + "match_type": "ternary",
284 + "target": [
285 + "standard_metadata",
286 + "ingress_port"
287 + ],
288 + "mask": null
289 + },
290 + {
291 + "match_type": "ternary",
292 + "target": [
293 + "ethernet",
294 + "dstAddr"
295 + ],
296 + "mask": null
297 + },
298 + {
299 + "match_type": "ternary",
300 + "target": [
301 + "ethernet",
302 + "srcAddr"
303 + ],
304 + "mask": null
305 + },
306 + {
307 + "match_type": "ternary",
308 + "target": [
309 + "ethernet",
310 + "etherType"
311 + ],
312 + "mask": null
313 + }
314 + ],
315 + "actions": [
316 + "fwd",
317 + "flood",
318 + "push_to_cp",
319 + "_drop"
320 + ],
321 + "next_tables": {
322 + "fwd": null,
323 + "flood": null,
324 + "push_to_cp": null,
325 + "_drop": null
326 + },
327 + "default_action": null,
328 + "base_default_next": null
329 + }
330 + ],
331 + "conditionals": []
332 + },
333 + {
334 + "name": "egress",
335 + "id": 1,
336 + "init_table": null,
337 + "tables": [],
338 + "conditionals": []
339 + }
340 + ],
341 + "calculations": [],
342 + "checksums": [],
343 + "learn_lists": [],
344 + "field_lists": [],
345 + "counter_arrays": [],
346 + "register_arrays": [],
347 + "force_arith": [
11 [ 348 [
12 - "packet_length", 349 + "standard_metadata",
13 - 32 350 + "ingress_port"
14 ], 351 ],
15 [ 352 [
16 - "egress_spec", 353 + "standard_metadata",
17 - 9 354 + "packet_length"
18 ], 355 ],
19 [ 356 [
20 - "egress_port", 357 + "standard_metadata",
21 - 9 358 + "egress_spec"
22 ], 359 ],
23 [ 360 [
24 - "egress_instance", 361 + "standard_metadata",
25 - 32 362 + "egress_port"
26 ], 363 ],
27 [ 364 [
28 - "instance_type", 365 + "standard_metadata",
29 - 32 366 + "egress_instance"
30 ], 367 ],
31 [ 368 [
32 - "clone_spec", 369 + "standard_metadata",
33 - 32 370 + "instance_type"
34 ], 371 ],
35 [ 372 [
36 - "_padding", 373 + "standard_metadata",
37 - 5 374 + "clone_spec"
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 ], 375 ],
51 [ 376 [
52 - "srcAddr", 377 + "standard_metadata",
53 - 48 378 + "_padding"
54 ], 379 ],
55 [ 380 [
56 - "etherType", 381 + "intrinsic_metadata",
57 - 16 382 + "ingress_global_timestamp"
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 ], 383 ],
71 [ 384 [
72 - "lf_field_list", 385 + "intrinsic_metadata",
73 - 32 386 + "lf_field_list"
74 ], 387 ],
75 [ 388 [
76 - "mcast_grp", 389 + "intrinsic_metadata",
77 - 16 390 + "mcast_grp"
78 ], 391 ],
79 [ 392 [
80 - "egress_rid", 393 + "intrinsic_metadata",
81 - 16 394 + "egress_rid"
82 ] 395 ]
83 - ],
84 - "length_exp": null,
85 - "max_length": null
86 - }
87 - ],
88 - "headers": [
89 - {
90 - "name": "standard_metadata",
91 - "id": 0,
92 - "header_type": "standard_metadata_t",
93 - "metadata": true
94 - },
95 - {
96 - "name": "ethernet",
97 - "id": 1,
98 - "header_type": "ethernet_t",
99 - "metadata": false
100 - },
101 - {
102 - "name": "intrinsic_metadata",
103 - "id": 2,
104 - "header_type": "intrinsic_metadata_t",
105 - "metadata": true
106 - }
107 - ],
108 - "header_stacks": [],
109 - "parsers": [
110 - {
111 - "name": "parser",
112 - "id": 0,
113 - "init_state": "start",
114 - "parse_states": [
115 - {
116 - "name": "start",
117 - "id": 0,
118 - "parser_ops": [],
119 - "transition_key": [],
120 - "transitions": [
121 - {
122 - "value": "default",
123 - "mask": null,
124 - "next_state": "parse_ethernet"
125 - }
126 - ]
127 - },
128 - {
129 - "name": "parse_ethernet",
130 - "id": 1,
131 - "parser_ops": [
132 - {
133 - "op": "extract",
134 - "parameters": [
135 - {
136 - "type": "regular",
137 - "value": "ethernet"
138 - }
139 - ]
140 - }
141 - ],
142 - "transition_key": [],
143 - "transitions": [
144 - {
145 - "value": "default",
146 - "mask": null,
147 - "next_state": null
148 - }
149 - ]
150 - }
151 - ]
152 - }
153 - ],
154 - "deparsers": [
155 - {
156 - "name": "deparser",
157 - "id": 0,
158 - "order": [
159 - "ethernet"
160 - ]
161 - }
162 - ],
163 - "meter_arrays": [],
164 - "actions": [
165 - {
166 - "name": "flood",
167 - "id": 0,
168 - "runtime_data": [],
169 - "primitives": [
170 - {
171 - "op": "modify_field",
172 - "parameters": [
173 - {
174 - "type": "field",
175 - "value": [
176 - "intrinsic_metadata",
177 - "mcast_grp"
178 - ]
179 - },
180 - {
181 - "type": "field",
182 - "value": [
183 - "standard_metadata",
184 - "ingress_port"
185 - ]
186 - }
187 - ]
188 - }
189 - ]
190 - },
191 - {
192 - "name": "_drop",
193 - "id": 1,
194 - "runtime_data": [],
195 - "primitives": [
196 - {
197 - "op": "modify_field",
198 - "parameters": [
199 - {
200 - "type": "field",
201 - "value": [
202 - "standard_metadata",
203 - "egress_spec"
204 - ]
205 - },
206 - {
207 - "type": "hexstr",
208 - "value": "0x1ff"
209 - }
210 - ]
211 - }
212 - ]
213 - },
214 - {
215 - "name": "fwd",
216 - "id": 2,
217 - "runtime_data": [
218 - {
219 - "name": "port",
220 - "bitwidth": 9
221 - }
222 - ],
223 - "primitives": [
224 - {
225 - "op": "modify_field",
226 - "parameters": [
227 - {
228 - "type": "field",
229 - "value": [
230 - "standard_metadata",
231 - "egress_spec"
232 - ]
233 - },
234 - {
235 - "type": "runtime_data",
236 - "value": 0
237 - }
238 - ]
239 - }
240 - ]
241 - },
242 - {
243 - "name": "send_to_cpu",
244 - "id": 3,
245 - "runtime_data": [],
246 - "primitives": [
247 - {
248 - "op": "modify_field",
249 - "parameters": [
250 - {
251 - "type": "field",
252 - "value": [
253 - "standard_metadata",
254 - "egress_spec"
255 - ]
256 - },
257 - {
258 - "type": "hexstr",
259 - "value": "0xff"
260 - }
261 - ]
262 - }
263 - ]
264 - }
265 - ],
266 - "pipelines": [
267 - {
268 - "name": "ingress",
269 - "id": 0,
270 - "init_table": "table0",
271 - "tables": [
272 - {
273 - "name": "table0",
274 - "id": 0,
275 - "match_type": "ternary",
276 - "type": "simple",
277 - "max_size": 16384,
278 - "with_counters": false,
279 - "direct_meters": null,
280 - "support_timeout": false,
281 - "key": [
282 - {
283 - "match_type": "ternary",
284 - "target": [
285 - "standard_metadata",
286 - "ingress_port"
287 - ],
288 - "mask": null
289 - },
290 - {
291 - "match_type": "ternary",
292 - "target": [
293 - "ethernet",
294 - "dstAddr"
295 - ],
296 - "mask": null
297 - },
298 - {
299 - "match_type": "ternary",
300 - "target": [
301 - "ethernet",
302 - "srcAddr"
303 - ],
304 - "mask": null
305 - },
306 - {
307 - "match_type": "ternary",
308 - "target": [
309 - "ethernet",
310 - "etherType"
311 - ],
312 - "mask": null
313 - }
314 - ],
315 - "actions": [
316 - "fwd",
317 - "flood",
318 - "send_to_cpu",
319 - "_drop"
320 - ],
321 - "next_tables": {
322 - "fwd": null,
323 - "flood": null,
324 - "send_to_cpu": null,
325 - "_drop": null
326 - },
327 - "default_action": null,
328 - "base_default_next": null
329 - }
330 - ],
331 - "conditionals": []
332 - },
333 - {
334 - "name": "egress",
335 - "id": 1,
336 - "init_table": null,
337 - "tables": [],
338 - "conditionals": []
339 - }
340 - ],
341 - "calculations": [],
342 - "checksums": [],
343 - "learn_lists": [],
344 - "field_lists": [],
345 - "counter_arrays": [],
346 - "register_arrays": [],
347 - "force_arith": [
348 - [
349 - "standard_metadata",
350 - "ingress_port"
351 - ],
352 - [
353 - "standard_metadata",
354 - "packet_length"
355 - ],
356 - [
357 - "standard_metadata",
358 - "egress_spec"
359 - ],
360 - [
361 - "standard_metadata",
362 - "egress_port"
363 - ],
364 - [
365 - "standard_metadata",
366 - "egress_instance"
367 - ],
368 - [
369 - "standard_metadata",
370 - "instance_type"
371 - ],
372 - [
373 - "standard_metadata",
374 - "clone_spec"
375 - ],
376 - [
377 - "standard_metadata",
378 - "_padding"
379 - ],
380 - [
381 - "intrinsic_metadata",
382 - "ingress_global_timestamp"
383 - ],
384 - [
385 - "intrinsic_metadata",
386 - "lf_field_list"
387 - ],
388 - [
389 - "intrinsic_metadata",
390 - "mcast_grp"
391 - ],
392 - [
393 - "intrinsic_metadata",
394 - "egress_rid"
395 ] 396 ]
396 - ]
397 } 397 }
...\ No newline at end of file ...\ No newline at end of file
......