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
Showing
6 changed files
with
542 additions
and
427 deletions
... | @@ -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); | ... | ... |
drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/translators/Bmv2DefaultTranslatorConfig.java
0 → 100644
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 | ... | ... |
-
Please register or login to post a comment