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