Fixes for the Pica8 pipeline and the cpqd emulation of the OFDPA pipeline.
Change-Id: Ib1982cdb7bc580cf86c43ace229388ee1f1106a2
Showing
4 changed files
with
251 additions
and
318 deletions
| ... | @@ -29,7 +29,7 @@ public class CpqdOFDPA1Pipeline extends OFDPA1Pipeline { | ... | @@ -29,7 +29,7 @@ public class CpqdOFDPA1Pipeline extends OFDPA1Pipeline { |
| 29 | processIpTable(); | 29 | processIpTable(); |
| 30 | //processMcastTable(); | 30 | //processMcastTable(); |
| 31 | processBridgingTable(); | 31 | processBridgingTable(); |
| 32 | - //processAclTable(); | 32 | + processAclTable(); |
| 33 | //processGroupTable(); | 33 | //processGroupTable(); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| ... | @@ -152,7 +152,35 @@ public class CpqdOFDPA1Pipeline extends OFDPA1Pipeline { | ... | @@ -152,7 +152,35 @@ public class CpqdOFDPA1Pipeline extends OFDPA1Pipeline { |
| 152 | log.info("Failed to initialize Bridging table"); | 152 | log.info("Failed to initialize Bridging table"); |
| 153 | } | 153 | } |
| 154 | })); | 154 | })); |
| 155 | + } | ||
| 155 | 156 | ||
| 157 | + private void processAclTable() { | ||
| 158 | + //table miss entry - catch all to executed action-set | ||
| 159 | + FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 160 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 161 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 162 | + selector = DefaultTrafficSelector.builder(); | ||
| 163 | + treatment = DefaultTrafficTreatment.builder(); | ||
| 164 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 165 | + .forDevice(deviceId) | ||
| 166 | + .withSelector(selector.build()) | ||
| 167 | + .withTreatment(treatment.build()) | ||
| 168 | + .withPriority(LOWEST_PRIORITY) | ||
| 169 | + .fromApp(driverId) | ||
| 170 | + .makePermanent() | ||
| 171 | + .forTable(ACL_TABLE).build(); | ||
| 172 | + ops = ops.add(rule); | ||
| 173 | + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 174 | + @Override | ||
| 175 | + public void onSuccess(FlowRuleOperations ops) { | ||
| 176 | + log.info("Initialized Acl table"); | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + @Override | ||
| 180 | + public void onError(FlowRuleOperations ops) { | ||
| 181 | + log.info("Failed to initialize Acl table"); | ||
| 182 | + } | ||
| 183 | + })); | ||
| 156 | } | 184 | } |
| 157 | 185 | ||
| 158 | } | 186 | } | ... | ... |
| ... | @@ -529,7 +529,6 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -529,7 +529,6 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
| 529 | .makePermanent() | 529 | .makePermanent() |
| 530 | .forTable(ACL_TABLE); | 530 | .forTable(ACL_TABLE); |
| 531 | 531 | ||
| 532 | - // XXX bug in OFDPA | ||
| 533 | return Collections.singletonList(ruleBuilder.build()); | 532 | return Collections.singletonList(ruleBuilder.build()); |
| 534 | } | 533 | } |
| 535 | 534 | ... | ... |
| ... | @@ -15,18 +15,16 @@ | ... | @@ -15,18 +15,16 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.driver.pipeline; | 16 | package org.onosproject.driver.pipeline; |
| 17 | 17 | ||
| 18 | -import com.google.common.cache.Cache; | ||
| 19 | -import com.google.common.cache.CacheBuilder; | ||
| 20 | -import com.google.common.cache.RemovalCause; | ||
| 21 | -import com.google.common.cache.RemovalNotification; | ||
| 22 | - | ||
| 23 | import org.onlab.osgi.ServiceDirectory; | 18 | import org.onlab.osgi.ServiceDirectory; |
| 24 | import org.onlab.packet.Ethernet; | 19 | import org.onlab.packet.Ethernet; |
| 25 | import org.onlab.packet.IPv4; | 20 | import org.onlab.packet.IPv4; |
| 21 | +import org.onlab.packet.MacAddress; | ||
| 22 | +import org.onlab.packet.VlanId; | ||
| 26 | import org.onlab.util.KryoNamespace; | 23 | import org.onlab.util.KryoNamespace; |
| 27 | import org.onosproject.core.ApplicationId; | 24 | import org.onosproject.core.ApplicationId; |
| 28 | import org.onosproject.core.CoreService; | 25 | import org.onosproject.core.CoreService; |
| 29 | import org.onosproject.net.DeviceId; | 26 | import org.onosproject.net.DeviceId; |
| 27 | +import org.onosproject.net.PortNumber; | ||
| 30 | import org.onosproject.net.behaviour.NextGroup; | 28 | import org.onosproject.net.behaviour.NextGroup; |
| 31 | import org.onosproject.net.behaviour.Pipeliner; | 29 | import org.onosproject.net.behaviour.Pipeliner; |
| 32 | import org.onosproject.net.behaviour.PipelinerContext; | 30 | import org.onosproject.net.behaviour.PipelinerContext; |
| ... | @@ -48,34 +46,23 @@ import org.onosproject.net.flow.criteria.IPCriterion; | ... | @@ -48,34 +46,23 @@ import org.onosproject.net.flow.criteria.IPCriterion; |
| 48 | import org.onosproject.net.flow.criteria.IPProtocolCriterion; | 46 | import org.onosproject.net.flow.criteria.IPProtocolCriterion; |
| 49 | import org.onosproject.net.flow.criteria.PortCriterion; | 47 | import org.onosproject.net.flow.criteria.PortCriterion; |
| 50 | import org.onosproject.net.flow.criteria.VlanIdCriterion; | 48 | import org.onosproject.net.flow.criteria.VlanIdCriterion; |
| 49 | +import org.onosproject.net.flow.instructions.Instruction; | ||
| 50 | +import org.onosproject.net.flow.instructions.L2ModificationInstruction; | ||
| 51 | import org.onosproject.net.flowobjective.FilteringObjective; | 51 | import org.onosproject.net.flowobjective.FilteringObjective; |
| 52 | import org.onosproject.net.flowobjective.FlowObjectiveStore; | 52 | import org.onosproject.net.flowobjective.FlowObjectiveStore; |
| 53 | import org.onosproject.net.flowobjective.ForwardingObjective; | 53 | import org.onosproject.net.flowobjective.ForwardingObjective; |
| 54 | import org.onosproject.net.flowobjective.NextObjective; | 54 | import org.onosproject.net.flowobjective.NextObjective; |
| 55 | import org.onosproject.net.flowobjective.Objective; | 55 | import org.onosproject.net.flowobjective.Objective; |
| 56 | import org.onosproject.net.flowobjective.ObjectiveError; | 56 | import org.onosproject.net.flowobjective.ObjectiveError; |
| 57 | -import org.onosproject.net.group.DefaultGroupBucket; | 57 | +import org.onosproject.store.serializers.KryoNamespaces; |
| 58 | -import org.onosproject.net.group.DefaultGroupDescription; | ||
| 59 | -import org.onosproject.net.group.DefaultGroupKey; | ||
| 60 | -import org.onosproject.net.group.Group; | ||
| 61 | -import org.onosproject.net.group.GroupBucket; | ||
| 62 | -import org.onosproject.net.group.GroupBuckets; | ||
| 63 | -import org.onosproject.net.group.GroupDescription; | ||
| 64 | -import org.onosproject.net.group.GroupEvent; | ||
| 65 | -import org.onosproject.net.group.GroupKey; | ||
| 66 | -import org.onosproject.net.group.GroupListener; | ||
| 67 | -import org.onosproject.net.group.GroupService; | ||
| 68 | import org.slf4j.Logger; | 58 | import org.slf4j.Logger; |
| 69 | 59 | ||
| 60 | +import java.util.ArrayList; | ||
| 70 | import java.util.Collection; | 61 | import java.util.Collection; |
| 71 | import java.util.Collections; | 62 | import java.util.Collections; |
| 72 | -import java.util.Set; | 63 | +import java.util.List; |
| 73 | -import java.util.concurrent.Executors; | 64 | +import java.util.concurrent.ConcurrentHashMap; |
| 74 | -import java.util.concurrent.ScheduledExecutorService; | ||
| 75 | -import java.util.concurrent.TimeUnit; | ||
| 76 | -import java.util.stream.Collectors; | ||
| 77 | 65 | ||
| 78 | -import static org.onlab.util.Tools.groupedThreads; | ||
| 79 | import static org.slf4j.LoggerFactory.getLogger; | 66 | import static org.slf4j.LoggerFactory.getLogger; |
| 80 | 67 | ||
| 81 | /** | 68 | /** |
| ... | @@ -83,12 +70,10 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -83,12 +70,10 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 83 | */ | 70 | */ |
| 84 | public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner { | 71 | public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
| 85 | 72 | ||
| 86 | - protected static final int VLAN_TABLE = 252; | 73 | + protected static final int IP_UNICAST_TABLE = 252; |
| 87 | - protected static final int ETHTYPE_TABLE = 252; | 74 | + protected static final int ACL_TABLE = 0; |
| 88 | - protected static final int IP_UNICAST_TABLE = 251; | ||
| 89 | - protected static final int ACL_TABLE = 251; | ||
| 90 | 75 | ||
| 91 | - private static final int CONTROLLER_PRIORITY = 255; | 76 | + //private static final int CONTROLLER_PRIORITY = 255; |
| 92 | private static final int DROP_PRIORITY = 0; | 77 | private static final int DROP_PRIORITY = 0; |
| 93 | private static final int HIGHEST_PRIORITY = 0xffff; | 78 | private static final int HIGHEST_PRIORITY = 0xffff; |
| 94 | 79 | ||
| ... | @@ -97,46 +82,29 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -97,46 +82,29 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 97 | private ServiceDirectory serviceDirectory; | 82 | private ServiceDirectory serviceDirectory; |
| 98 | private FlowRuleService flowRuleService; | 83 | private FlowRuleService flowRuleService; |
| 99 | private CoreService coreService; | 84 | private CoreService coreService; |
| 100 | - private GroupService groupService; | ||
| 101 | private FlowObjectiveStore flowObjectiveStore; | 85 | private FlowObjectiveStore flowObjectiveStore; |
| 102 | private DeviceId deviceId; | 86 | private DeviceId deviceId; |
| 103 | private ApplicationId appId; | 87 | private ApplicationId appId; |
| 88 | + private Collection<Filter> filters; | ||
| 89 | + private Collection<ForwardingObjective> pendingVersatiles; | ||
| 104 | 90 | ||
| 105 | private KryoNamespace appKryo = new KryoNamespace.Builder() | 91 | private KryoNamespace appKryo = new KryoNamespace.Builder() |
| 106 | - .register(GroupKey.class) | 92 | + .register(KryoNamespaces.API) |
| 107 | - .register(DefaultGroupKey.class) | ||
| 108 | .register(PicaGroup.class) | 93 | .register(PicaGroup.class) |
| 109 | .register(byte[].class) | 94 | .register(byte[].class) |
| 110 | .build(); | 95 | .build(); |
| 111 | 96 | ||
| 112 | - private Cache<GroupKey, NextObjective> pendingGroups; | ||
| 113 | - | ||
| 114 | - private ScheduledExecutorService groupChecker = | ||
| 115 | - Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner", | ||
| 116 | - "ovs-pica-%d")); | ||
| 117 | - | ||
| 118 | @Override | 97 | @Override |
| 119 | public void init(DeviceId deviceId, PipelinerContext context) { | 98 | public void init(DeviceId deviceId, PipelinerContext context) { |
| 120 | this.serviceDirectory = context.directory(); | 99 | this.serviceDirectory = context.directory(); |
| 121 | this.deviceId = deviceId; | 100 | this.deviceId = deviceId; |
| 122 | 101 | ||
| 123 | - pendingGroups = CacheBuilder.newBuilder() | ||
| 124 | - .expireAfterWrite(20, TimeUnit.SECONDS) | ||
| 125 | - .removalListener((RemovalNotification<GroupKey, NextObjective> notification) -> { | ||
| 126 | - if (notification.getCause() == RemovalCause.EXPIRED) { | ||
| 127 | - fail(notification.getValue(), ObjectiveError.GROUPINSTALLATIONFAILED); | ||
| 128 | - } | ||
| 129 | - }).build(); | ||
| 130 | - | ||
| 131 | - groupChecker.scheduleAtFixedRate(new GroupChecker(), 0, 500, TimeUnit.MILLISECONDS); | ||
| 132 | - | ||
| 133 | coreService = serviceDirectory.get(CoreService.class); | 102 | coreService = serviceDirectory.get(CoreService.class); |
| 134 | flowRuleService = serviceDirectory.get(FlowRuleService.class); | 103 | flowRuleService = serviceDirectory.get(FlowRuleService.class); |
| 135 | - groupService = serviceDirectory.get(GroupService.class); | ||
| 136 | flowObjectiveStore = context.store(); | 104 | flowObjectiveStore = context.store(); |
| 137 | - | 105 | + filters = Collections.newSetFromMap(new ConcurrentHashMap<Filter, Boolean>()); |
| 138 | - groupService.addListener(new InnerGroupListener()); | 106 | + pendingVersatiles = Collections.newSetFromMap( |
| 139 | - | 107 | + new ConcurrentHashMap<ForwardingObjective, Boolean>()); |
| 140 | appId = coreService.registerApplication( | 108 | appId = coreService.registerApplication( |
| 141 | "org.onosproject.driver.OVSPicaPipeline"); | 109 | "org.onosproject.driver.OVSPicaPipeline"); |
| 142 | 110 | ||
| ... | @@ -196,22 +164,46 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -196,22 +164,46 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 196 | switch (nextObjective.type()) { | 164 | switch (nextObjective.type()) { |
| 197 | case SIMPLE: | 165 | case SIMPLE: |
| 198 | Collection<TrafficTreatment> treatments = nextObjective.next(); | 166 | Collection<TrafficTreatment> treatments = nextObjective.next(); |
| 199 | - if (treatments.size() == 1) { | 167 | + if (treatments.size() != 1) { |
| 200 | - TrafficTreatment treatment = treatments.iterator().next(); | 168 | + log.error("Next Objectives of type Simple should only have a " |
| 201 | - GroupBucket bucket = | 169 | + + "single Traffic Treatment. Next Objective Id:{}", nextObjective.id()); |
| 202 | - DefaultGroupBucket.createIndirectGroupBucket(treatment); | 170 | + fail(nextObjective, ObjectiveError.BADPARAMS); |
| 203 | - final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id())); | 171 | + return; |
| 204 | - GroupDescription groupDescription | 172 | + } |
| 205 | - = new DefaultGroupDescription(deviceId, | 173 | + TrafficTreatment treatment = treatments.iterator().next(); |
| 206 | - GroupDescription.Type.INDIRECT, | 174 | + TrafficTreatment.Builder filteredTreatment = DefaultTrafficTreatment.builder(); |
| 207 | - new GroupBuckets(Collections | 175 | + VlanId modVlanId; |
| 208 | - .singletonList(bucket)), | 176 | + for (Instruction ins : treatment.allInstructions()) { |
| 209 | - key, | 177 | + if (ins.type() == Instruction.Type.L2MODIFICATION) { |
| 210 | - null, // let group service determine group id | 178 | + L2ModificationInstruction l2ins = (L2ModificationInstruction) ins; |
| 211 | - nextObjective.appId()); | 179 | + switch (l2ins.subtype()) { |
| 212 | - groupService.addGroup(groupDescription); | 180 | + case ETH_DST: |
| 213 | - pendingGroups.put(key, nextObjective); | 181 | + filteredTreatment.setEthDst( |
| 182 | + ((L2ModificationInstruction.ModEtherInstruction) l2ins).mac()); | ||
| 183 | + break; | ||
| 184 | + case ETH_SRC: | ||
| 185 | + filteredTreatment.setEthSrc( | ||
| 186 | + ((L2ModificationInstruction.ModEtherInstruction) l2ins).mac()); | ||
| 187 | + break; | ||
| 188 | + case VLAN_ID: | ||
| 189 | + modVlanId = ((L2ModificationInstruction.ModVlanIdInstruction) l2ins).vlanId(); | ||
| 190 | + filteredTreatment.setVlanId(modVlanId); | ||
| 191 | + break; | ||
| 192 | + default: | ||
| 193 | + break; | ||
| 194 | + } | ||
| 195 | + } else if (ins.type() == Instruction.Type.OUTPUT) { | ||
| 196 | + //long portNum = ((Instructions.OutputInstruction) ins).port().toLong(); | ||
| 197 | + filteredTreatment.add(ins); | ||
| 198 | + } else { | ||
| 199 | + // Ignore the vlan_pcp action since it's does matter much. | ||
| 200 | + log.warn("Driver does not handle this type of TrafficTreatment" | ||
| 201 | + + " instruction in nextObjectives: {}", ins.type()); | ||
| 202 | + } | ||
| 214 | } | 203 | } |
| 204 | + // store for future use | ||
| 205 | + flowObjectiveStore.putNextGroup(nextObjective.id(), | ||
| 206 | + new PicaGroup(filteredTreatment.build())); | ||
| 215 | break; | 207 | break; |
| 216 | case HASHED: | 208 | case HASHED: |
| 217 | case BROADCAST: | 209 | case BROADCAST: |
| ... | @@ -250,11 +242,17 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -250,11 +242,17 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 250 | fail(fwd, ObjectiveError.UNKNOWN); | 242 | fail(fwd, ObjectiveError.UNKNOWN); |
| 251 | return Collections.emptySet(); | 243 | return Collections.emptySet(); |
| 252 | } | 244 | } |
| 245 | + | ||
| 253 | if (ethType.ethType() == Ethernet.TYPE_ARP) { | 246 | if (ethType.ethType() == Ethernet.TYPE_ARP) { |
| 254 | - log.warn("Driver automatically handles ARP packets by punting to controller " | 247 | + if (filters.isEmpty()) { |
| 255 | - + " from ETHER table"); | 248 | + pendingVersatiles.add(fwd); |
| 256 | - pass(fwd); | 249 | + return Collections.emptySet(); |
| 257 | - return Collections.emptySet(); | 250 | + } |
| 251 | + Collection<FlowRule> flowrules = new ArrayList<FlowRule>(); | ||
| 252 | + for (Filter filter : filters) { | ||
| 253 | + flowrules.addAll(processVersatilesWithFilters(filter, fwd)); | ||
| 254 | + } | ||
| 255 | + return flowrules; | ||
| 258 | } else if (ethType.ethType() == Ethernet.TYPE_LLDP || | 256 | } else if (ethType.ethType() == Ethernet.TYPE_LLDP || |
| 259 | ethType.ethType() == Ethernet.TYPE_BSN) { | 257 | ethType.ethType() == Ethernet.TYPE_BSN) { |
| 260 | log.warn("Driver currently does not currently handle LLDP packets"); | 258 | log.warn("Driver currently does not currently handle LLDP packets"); |
| ... | @@ -280,7 +278,7 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -280,7 +278,7 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 280 | } | 278 | } |
| 281 | if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) { | 279 | if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) { |
| 282 | log.warn("Driver automatically punts all packets reaching the " | 280 | log.warn("Driver automatically punts all packets reaching the " |
| 283 | - + "LOCAL table to the controller"); | 281 | + + "ACL table to the controller"); |
| 284 | pass(fwd); | 282 | pass(fwd); |
| 285 | return Collections.emptySet(); | 283 | return Collections.emptySet(); |
| 286 | } | 284 | } |
| ... | @@ -291,6 +289,51 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -291,6 +289,51 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 291 | return Collections.emptySet(); | 289 | return Collections.emptySet(); |
| 292 | } | 290 | } |
| 293 | 291 | ||
| 292 | + private Collection<FlowRule> processVersatilesWithFilters( | ||
| 293 | + Filter filt, ForwardingObjective fwd) { | ||
| 294 | + Collection<FlowRule> flows = new ArrayList<FlowRule>(); | ||
| 295 | + | ||
| 296 | + // rule for ARP replies | ||
| 297 | + log.debug("adding ARP rule in ACL table"); | ||
| 298 | + TrafficSelector.Builder sel = DefaultTrafficSelector.builder(); | ||
| 299 | + TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); | ||
| 300 | + sel.matchInPort(filt.port()); | ||
| 301 | + sel.matchVlanId(filt.vlanId()); | ||
| 302 | + sel.matchEthDst(filt.mac()); | ||
| 303 | + sel.matchEthType(Ethernet.TYPE_ARP); | ||
| 304 | + treat.setOutput(PortNumber.CONTROLLER); | ||
| 305 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 306 | + .forDevice(deviceId) | ||
| 307 | + .withSelector(sel.build()) | ||
| 308 | + .withTreatment(treat.build()) | ||
| 309 | + .withPriority(HIGHEST_PRIORITY) | ||
| 310 | + .fromApp(appId) | ||
| 311 | + .makePermanent() | ||
| 312 | + .forTable(ACL_TABLE).build(); | ||
| 313 | + flows.add(rule); | ||
| 314 | + | ||
| 315 | + // rule for ARP Broadcast | ||
| 316 | + sel = DefaultTrafficSelector.builder(); | ||
| 317 | + treat = DefaultTrafficTreatment.builder(); | ||
| 318 | + sel.matchInPort(filt.port()); | ||
| 319 | + sel.matchVlanId(filt.vlanId()); | ||
| 320 | + sel.matchEthDst(MacAddress.BROADCAST); | ||
| 321 | + sel.matchEthType(Ethernet.TYPE_ARP); | ||
| 322 | + treat.setOutput(PortNumber.CONTROLLER); | ||
| 323 | + rule = DefaultFlowRule.builder() | ||
| 324 | + .forDevice(deviceId) | ||
| 325 | + .withSelector(sel.build()) | ||
| 326 | + .withTreatment(treat.build()) | ||
| 327 | + .withPriority(HIGHEST_PRIORITY) | ||
| 328 | + .fromApp(appId) | ||
| 329 | + .makePermanent() | ||
| 330 | + .forTable(ACL_TABLE).build(); | ||
| 331 | + flows.add(rule); | ||
| 332 | + | ||
| 333 | + return flows; | ||
| 334 | + } | ||
| 335 | + | ||
| 336 | + | ||
| 294 | private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { | 337 | private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { |
| 295 | log.debug("Processing specific forwarding objective"); | 338 | log.debug("Processing specific forwarding objective"); |
| 296 | TrafficSelector selector = fwd.selector(); | 339 | TrafficSelector selector = fwd.selector(); |
| ... | @@ -301,46 +344,47 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -301,46 +344,47 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 301 | return Collections.emptySet(); | 344 | return Collections.emptySet(); |
| 302 | } | 345 | } |
| 303 | 346 | ||
| 304 | - TrafficSelector filteredSelector = | 347 | + List<FlowRule> ipflows = new ArrayList<FlowRule>(); |
| 305 | - DefaultTrafficSelector.builder() | 348 | + for (Filter f: filters) { |
| 306 | - .matchEthType(Ethernet.TYPE_IPV4) | 349 | + TrafficSelector filteredSelector = |
| 307 | - .matchIPDst( | 350 | + DefaultTrafficSelector.builder() |
| 351 | + .matchEthType(Ethernet.TYPE_IPV4) | ||
| 352 | + .matchIPDst( | ||
| 308 | ((IPCriterion) | 353 | ((IPCriterion) |
| 309 | selector.getCriterion(Criterion.Type.IPV4_DST)).ip()) | 354 | selector.getCriterion(Criterion.Type.IPV4_DST)).ip()) |
| 310 | - .build(); | 355 | + .matchEthDst(f.mac()) |
| 311 | - | 356 | + .matchVlanId(f.vlanId()) |
| 312 | - TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); | 357 | + .build(); |
| 313 | - | 358 | + TrafficTreatment tt = null; |
| 314 | - if (fwd.nextId() != null) { | 359 | + if (fwd.nextId() != null) { |
| 315 | - NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); | 360 | + NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); |
| 316 | - GroupKey key = appKryo.deserialize(next.data()); | 361 | + if (next == null) { |
| 317 | - Group group = groupService.getGroup(deviceId, key); | 362 | + log.error("next-id {} does not exist in store", fwd.nextId()); |
| 318 | - if (group == null) { | 363 | + return Collections.emptySet(); |
| 319 | - log.warn("The group left!"); | 364 | + } |
| 320 | - fail(fwd, ObjectiveError.GROUPMISSING); | 365 | + tt = appKryo.deserialize(next.data()); |
| 321 | - return Collections.emptySet(); | 366 | + if (tt == null) { |
| 367 | + log.error("Error in deserializing next-id {}", fwd.nextId()); | ||
| 368 | + return Collections.emptySet(); | ||
| 369 | + } | ||
| 322 | } | 370 | } |
| 323 | - tb.group(group.id()); | ||
| 324 | - } | ||
| 325 | - | ||
| 326 | - FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() | ||
| 327 | - .fromApp(fwd.appId()) | ||
| 328 | - .withPriority(fwd.priority()) | ||
| 329 | - .forDevice(deviceId) | ||
| 330 | - .withSelector(filteredSelector) | ||
| 331 | - .withTreatment(tb.build()); | ||
| 332 | 371 | ||
| 333 | - if (fwd.permanent()) { | 372 | + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() |
| 334 | - ruleBuilder.makePermanent(); | 373 | + .fromApp(fwd.appId()) |
| 335 | - } else { | 374 | + .withPriority(fwd.priority()) |
| 336 | - ruleBuilder.makeTemporary(fwd.timeout()); | 375 | + .forDevice(deviceId) |
| 376 | + .withSelector(filteredSelector) | ||
| 377 | + .withTreatment(tt); | ||
| 378 | + if (fwd.permanent()) { | ||
| 379 | + ruleBuilder.makePermanent(); | ||
| 380 | + } else { | ||
| 381 | + ruleBuilder.makeTemporary(fwd.timeout()); | ||
| 382 | + } | ||
| 383 | + ruleBuilder.forTable(IP_UNICAST_TABLE); | ||
| 384 | + ipflows.add(ruleBuilder.build()); | ||
| 337 | } | 385 | } |
| 338 | 386 | ||
| 339 | - ruleBuilder.forTable(IP_UNICAST_TABLE); | 387 | + return ipflows; |
| 340 | - | ||
| 341 | - | ||
| 342 | - return Collections.singletonList(ruleBuilder.build()); | ||
| 343 | - | ||
| 344 | } | 388 | } |
| 345 | 389 | ||
| 346 | private void processFilter(FilteringObjective filt, boolean install, | 390 | private void processFilter(FilteringObjective filt, boolean install, |
| ... | @@ -357,67 +401,58 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -357,67 +401,58 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 357 | fail(filt, ObjectiveError.UNKNOWN); | 401 | fail(filt, ObjectiveError.UNKNOWN); |
| 358 | return; | 402 | return; |
| 359 | } | 403 | } |
| 404 | + | ||
| 405 | + EthCriterion e = null; VlanIdCriterion v = null; | ||
| 406 | + Collection<IPCriterion> ips = new ArrayList<IPCriterion>(); | ||
| 360 | // convert filtering conditions for switch-intfs into flowrules | 407 | // convert filtering conditions for switch-intfs into flowrules |
| 361 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 408 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
| 362 | for (Criterion c : filt.conditions()) { | 409 | for (Criterion c : filt.conditions()) { |
| 363 | if (c.type() == Criterion.Type.ETH_DST) { | 410 | if (c.type() == Criterion.Type.ETH_DST) { |
| 364 | - EthCriterion e = (EthCriterion) c; | 411 | + e = (EthCriterion) c; |
| 365 | - log.debug("adding rule for MAC: {}", e.mac()); | ||
| 366 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 367 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 368 | - selector.matchEthDst(e.mac()); | ||
| 369 | - treatment.transition(IP_UNICAST_TABLE); | ||
| 370 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 371 | - .forDevice(deviceId) | ||
| 372 | - .withSelector(selector.build()) | ||
| 373 | - .withTreatment(treatment.build()) | ||
| 374 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 375 | - .fromApp(applicationId) | ||
| 376 | - .makePermanent() | ||
| 377 | - .forTable(ETHTYPE_TABLE).build(); | ||
| 378 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 379 | } else if (c.type() == Criterion.Type.VLAN_VID) { | 412 | } else if (c.type() == Criterion.Type.VLAN_VID) { |
| 380 | - VlanIdCriterion v = (VlanIdCriterion) c; | 413 | + v = (VlanIdCriterion) c; |
| 381 | - log.debug("adding rule for VLAN: {}", v.vlanId()); | ||
| 382 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 383 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 384 | - selector.matchVlanId(v.vlanId()); | ||
| 385 | - selector.matchInPort(p.port()); | ||
| 386 | - treatment.transition(ETHTYPE_TABLE); | ||
| 387 | - treatment.deferred().popVlan(); | ||
| 388 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 389 | - .forDevice(deviceId) | ||
| 390 | - .withSelector(selector.build()) | ||
| 391 | - .withTreatment(treatment.build()) | ||
| 392 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 393 | - .fromApp(applicationId) | ||
| 394 | - .makePermanent() | ||
| 395 | - .forTable(VLAN_TABLE).build(); | ||
| 396 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 397 | } else if (c.type() == Criterion.Type.IPV4_DST) { | 414 | } else if (c.type() == Criterion.Type.IPV4_DST) { |
| 398 | - IPCriterion ip = (IPCriterion) c; | 415 | + ips.add((IPCriterion) c); |
| 399 | - log.debug("adding rule for IP: {}", ip.ip()); | ||
| 400 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 401 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 402 | - selector.matchEthType(Ethernet.TYPE_IPV4); | ||
| 403 | - selector.matchIPDst(ip.ip()); | ||
| 404 | - treatment.transition(ACL_TABLE); | ||
| 405 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 406 | - .forDevice(deviceId) | ||
| 407 | - .withSelector(selector.build()) | ||
| 408 | - .withTreatment(treatment.build()) | ||
| 409 | - .withPriority(HIGHEST_PRIORITY) | ||
| 410 | - .fromApp(applicationId) | ||
| 411 | - .makePermanent() | ||
| 412 | - .forTable(IP_UNICAST_TABLE).build(); | ||
| 413 | - | ||
| 414 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 415 | } else { | 416 | } else { |
| 416 | - log.warn("Driver does not currently process filtering condition" | 417 | + log.error("Unsupported filter {}", c); |
| 417 | - + " of type: {}", c.type()); | ||
| 418 | fail(filt, ObjectiveError.UNSUPPORTED); | 418 | fail(filt, ObjectiveError.UNSUPPORTED); |
| 419 | + return; | ||
| 420 | + } | ||
| 421 | + } | ||
| 422 | + | ||
| 423 | + // cache for later use | ||
| 424 | + Filter filter = new Filter(p, e, v, ips); | ||
| 425 | + filters.add(filter); | ||
| 426 | + | ||
| 427 | + // apply any pending versatile forwarding objectives | ||
| 428 | + for (ForwardingObjective fwd : pendingVersatiles) { | ||
| 429 | + Collection<FlowRule> ret = processVersatilesWithFilters(filter, fwd); | ||
| 430 | + for (FlowRule fr : ret) { | ||
| 431 | + ops.add(fr); | ||
| 419 | } | 432 | } |
| 420 | } | 433 | } |
| 434 | + | ||
| 435 | + for (IPCriterion ipaddr : ips) { | ||
| 436 | + log.debug("adding IP filtering rules in ACL table: {}", ipaddr.ip()); | ||
| 437 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 438 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 439 | + selector.matchInPort(p.port()); | ||
| 440 | + selector.matchVlanId(v.vlanId()); | ||
| 441 | + selector.matchEthDst(e.mac()); | ||
| 442 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
| 443 | + selector.matchIPDst(ipaddr.ip()); // router IPs to the controller | ||
| 444 | + treatment.setOutput(PortNumber.CONTROLLER); | ||
| 445 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 446 | + .forDevice(deviceId) | ||
| 447 | + .withSelector(selector.build()) | ||
| 448 | + .withTreatment(treatment.build()) | ||
| 449 | + .withPriority(HIGHEST_PRIORITY) | ||
| 450 | + .fromApp(applicationId) | ||
| 451 | + .makePermanent() | ||
| 452 | + .forTable(ACL_TABLE).build(); | ||
| 453 | + ops = ops.add(rule); | ||
| 454 | + } | ||
| 455 | + | ||
| 421 | // apply filtering flow rules | 456 | // apply filtering flow rules |
| 422 | flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | 457 | flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { |
| 423 | @Override | 458 | @Override |
| ... | @@ -447,25 +482,20 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -447,25 +482,20 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 447 | } | 482 | } |
| 448 | 483 | ||
| 449 | private void initializePipeline() { | 484 | private void initializePipeline() { |
| 450 | - processVlanTable(true); | 485 | + //processIpUnicastTable(true); |
| 451 | - processEtherTable(true); | 486 | + processACLTable(true); |
| 452 | - processIpUnicastTable(true); | ||
| 453 | - //processACLTable(true); | ||
| 454 | } | 487 | } |
| 455 | 488 | ||
| 456 | - private void processVlanTable(boolean install) { | 489 | + private void processACLTable(boolean install) { |
| 457 | TrafficSelector.Builder selector; | 490 | TrafficSelector.Builder selector; |
| 458 | TrafficTreatment.Builder treatment; | 491 | TrafficTreatment.Builder treatment; |
| 459 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 492 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
| 460 | FlowRule rule; | 493 | FlowRule rule; |
| 461 | 494 | ||
| 462 | - | ||
| 463 | //Drop rule | 495 | //Drop rule |
| 464 | selector = DefaultTrafficSelector.builder(); | 496 | selector = DefaultTrafficSelector.builder(); |
| 465 | treatment = DefaultTrafficTreatment.builder(); | 497 | treatment = DefaultTrafficTreatment.builder(); |
| 466 | 498 | ||
| 467 | - treatment.drop(); | ||
| 468 | - | ||
| 469 | rule = DefaultFlowRule.builder() | 499 | rule = DefaultFlowRule.builder() |
| 470 | .forDevice(deviceId) | 500 | .forDevice(deviceId) |
| 471 | .withSelector(selector.build()) | 501 | .withSelector(selector.build()) |
| ... | @@ -473,186 +503,62 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -473,186 +503,62 @@ public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner |
| 473 | .withPriority(DROP_PRIORITY) | 503 | .withPriority(DROP_PRIORITY) |
| 474 | .fromApp(appId) | 504 | .fromApp(appId) |
| 475 | .makePermanent() | 505 | .makePermanent() |
| 476 | - .forTable(VLAN_TABLE).build(); | 506 | + .forTable(ACL_TABLE).build(); |
| 477 | 507 | ||
| 478 | ops = install ? ops.add(rule) : ops.remove(rule); | 508 | ops = install ? ops.add(rule) : ops.remove(rule); |
| 479 | 509 | ||
| 480 | flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | 510 | flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { |
| 481 | @Override | 511 | @Override |
| 482 | public void onSuccess(FlowRuleOperations ops) { | 512 | public void onSuccess(FlowRuleOperations ops) { |
| 483 | - log.info("Provisioned vlan table"); | 513 | + log.info("Provisioned ACL table"); |
| 484 | } | 514 | } |
| 485 | 515 | ||
| 486 | @Override | 516 | @Override |
| 487 | public void onError(FlowRuleOperations ops) { | 517 | public void onError(FlowRuleOperations ops) { |
| 488 | - log.info("Failed to provision vlan table"); | 518 | + log.info("Failed to provision ACL table"); |
| 489 | } | 519 | } |
| 490 | })); | 520 | })); |
| 491 | } | 521 | } |
| 492 | 522 | ||
| 493 | - private void processEtherTable(boolean install) { | 523 | + private class Filter { |
| 494 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 524 | + private PortCriterion port; |
| 495 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment | 525 | + private VlanIdCriterion vlan; |
| 496 | - .builder(); | 526 | + private EthCriterion eth; |
| 497 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 498 | - FlowRule rule; | ||
| 499 | - | ||
| 500 | - selector.matchEthType(Ethernet.TYPE_ARP); | ||
| 501 | - treatment.punt(); | ||
| 502 | - | ||
| 503 | - rule = DefaultFlowRule.builder() | ||
| 504 | - .forDevice(deviceId) | ||
| 505 | - .withSelector(selector.build()) | ||
| 506 | - .withTreatment(treatment.build()) | ||
| 507 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 508 | - .fromApp(appId) | ||
| 509 | - .makePermanent() | ||
| 510 | - .forTable(ETHTYPE_TABLE).build(); | ||
| 511 | - | ||
| 512 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 513 | - | ||
| 514 | - selector = DefaultTrafficSelector.builder(); | ||
| 515 | - treatment = DefaultTrafficTreatment.builder(); | ||
| 516 | - | ||
| 517 | - selector.matchEthType(Ethernet.TYPE_IPV4); | ||
| 518 | - treatment.transition(IP_UNICAST_TABLE); | ||
| 519 | - | ||
| 520 | - rule = DefaultFlowRule.builder() | ||
| 521 | - .forDevice(deviceId) | ||
| 522 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 523 | - .withSelector(selector.build()) | ||
| 524 | - .withTreatment(treatment.build()) | ||
| 525 | - .fromApp(appId) | ||
| 526 | - .makePermanent() | ||
| 527 | - .forTable(ETHTYPE_TABLE).build(); | ||
| 528 | - | ||
| 529 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 530 | 527 | ||
| 531 | - //Drop rule | 528 | + @SuppressWarnings("unused") |
| 532 | - selector = DefaultTrafficSelector.builder(); | 529 | + private Collection<IPCriterion> ips; |
| 533 | - treatment = DefaultTrafficTreatment.builder(); | 530 | + |
| 534 | - | 531 | + public Filter(PortCriterion p, EthCriterion e, VlanIdCriterion v, |
| 535 | - treatment.drop(); | 532 | + Collection<IPCriterion> ips) { |
| 536 | - | 533 | + this.eth = e; |
| 537 | - rule = DefaultFlowRule.builder() | 534 | + this.port = p; |
| 538 | - .forDevice(deviceId) | 535 | + this.vlan = v; |
| 539 | - .withSelector(selector.build()) | 536 | + this.ips = ips; |
| 540 | - .withTreatment(treatment.build()) | ||
| 541 | - .withPriority(DROP_PRIORITY) | ||
| 542 | - .fromApp(appId) | ||
| 543 | - .makePermanent() | ||
| 544 | - .forTable(ETHTYPE_TABLE).build(); | ||
| 545 | - | ||
| 546 | - | ||
| 547 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 548 | - | ||
| 549 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 550 | - @Override | ||
| 551 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 552 | - log.info("Provisioned ether table"); | ||
| 553 | - } | ||
| 554 | - | ||
| 555 | - @Override | ||
| 556 | - public void onError(FlowRuleOperations ops) { | ||
| 557 | - log.info("Failed to provision ether table"); | ||
| 558 | - } | ||
| 559 | - })); | ||
| 560 | - | ||
| 561 | - } | ||
| 562 | - | ||
| 563 | - | ||
| 564 | - private void processIpUnicastTable(boolean install) { | ||
| 565 | - TrafficSelector.Builder selector; | ||
| 566 | - TrafficTreatment.Builder treatment; | ||
| 567 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 568 | - FlowRule rule; | ||
| 569 | - | ||
| 570 | - //Drop rule | ||
| 571 | - selector = DefaultTrafficSelector.builder(); | ||
| 572 | - treatment = DefaultTrafficTreatment.builder(); | ||
| 573 | - | ||
| 574 | - treatment.drop(); | ||
| 575 | - | ||
| 576 | - rule = DefaultFlowRule.builder() | ||
| 577 | - .forDevice(deviceId) | ||
| 578 | - .withSelector(selector.build()) | ||
| 579 | - .withTreatment(treatment.build()) | ||
| 580 | - .withPriority(DROP_PRIORITY) | ||
| 581 | - .fromApp(appId) | ||
| 582 | - .makePermanent() | ||
| 583 | - .forTable(IP_UNICAST_TABLE).build(); | ||
| 584 | - | ||
| 585 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 586 | - | ||
| 587 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 588 | - @Override | ||
| 589 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 590 | - log.info("Provisioned FIB table"); | ||
| 591 | - } | ||
| 592 | - | ||
| 593 | - @Override | ||
| 594 | - public void onError(FlowRuleOperations ops) { | ||
| 595 | - log.info("Failed to provision FIB table"); | ||
| 596 | - } | ||
| 597 | - })); | ||
| 598 | - } | ||
| 599 | - | ||
| 600 | - | ||
| 601 | - private class InnerGroupListener implements GroupListener { | ||
| 602 | - @Override | ||
| 603 | - public void event(GroupEvent event) { | ||
| 604 | - if (event.type() == GroupEvent.Type.GROUP_ADDED) { | ||
| 605 | - GroupKey key = event.subject().appCookie(); | ||
| 606 | - | ||
| 607 | - NextObjective obj = pendingGroups.getIfPresent(key); | ||
| 608 | - if (obj != null) { | ||
| 609 | - flowObjectiveStore.putNextGroup(obj.id(), new PicaGroup(key)); | ||
| 610 | - pass(obj); | ||
| 611 | - pendingGroups.invalidate(key); | ||
| 612 | - } | ||
| 613 | - } | ||
| 614 | } | 537 | } |
| 615 | - } | ||
| 616 | 538 | ||
| 539 | + public PortNumber port() { | ||
| 540 | + return port.port(); | ||
| 541 | + } | ||
| 617 | 542 | ||
| 618 | - private class GroupChecker implements Runnable { | 543 | + public VlanId vlanId() { |
| 544 | + return vlan.vlanId(); | ||
| 545 | + } | ||
| 619 | 546 | ||
| 620 | - @Override | 547 | + public MacAddress mac() { |
| 621 | - public void run() { | 548 | + return eth.mac(); |
| 622 | - Set<GroupKey> keys = pendingGroups.asMap().keySet().stream() | ||
| 623 | - .filter(key -> groupService.getGroup(deviceId, key) != null) | ||
| 624 | - .collect(Collectors.toSet()); | ||
| 625 | - | ||
| 626 | - keys.stream().forEach(key -> { | ||
| 627 | - NextObjective obj = pendingGroups.getIfPresent(key); | ||
| 628 | - if (obj == null) { | ||
| 629 | - return; | ||
| 630 | - } | ||
| 631 | - pass(obj); | ||
| 632 | - pendingGroups.invalidate(key); | ||
| 633 | - log.info("Heard back from group service for group {}. " | ||
| 634 | - + "Applying pending forwarding objectives", obj.id()); | ||
| 635 | - flowObjectiveStore.putNextGroup(obj.id(), new PicaGroup(key)); | ||
| 636 | - }); | ||
| 637 | } | 549 | } |
| 638 | } | 550 | } |
| 639 | 551 | ||
| 640 | private class PicaGroup implements NextGroup { | 552 | private class PicaGroup implements NextGroup { |
| 553 | + TrafficTreatment nextActions; | ||
| 641 | 554 | ||
| 642 | - private final GroupKey key; | 555 | + public PicaGroup(TrafficTreatment next) { |
| 643 | - | 556 | + this.nextActions = next; |
| 644 | - public PicaGroup(GroupKey key) { | ||
| 645 | - this.key = key; | ||
| 646 | - } | ||
| 647 | - | ||
| 648 | - @SuppressWarnings("unused") | ||
| 649 | - public GroupKey key() { | ||
| 650 | - return key; | ||
| 651 | } | 557 | } |
| 652 | 558 | ||
| 653 | @Override | 559 | @Override |
| 654 | public byte[] data() { | 560 | public byte[] data() { |
| 655 | - return appKryo.serialize(key); | 561 | + return appKryo.serialize(nextActions); |
| 656 | } | 562 | } |
| 657 | 563 | ||
| 658 | } | 564 | } | ... | ... |
| ... | @@ -84,7 +84,7 @@ | ... | @@ -84,7 +84,7 @@ |
| 84 | impl="org.onosproject.driver.pipeline.CentecV350Pipeline"/> | 84 | impl="org.onosproject.driver.pipeline.CentecV350Pipeline"/> |
| 85 | </driver> | 85 | </driver> |
| 86 | <driver name="pica" extends="default" | 86 | <driver name="pica" extends="default" |
| 87 | - manufacturer="Pica8, Inc." hwVersion="ly2" swVersion="PicOS 2.6"> | 87 | + manufacturer="Pica8, Inc." hwVersion=".*" swVersion="PicOS 2.6"> |
| 88 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" | 88 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" |
| 89 | impl="org.onosproject.driver.pipeline.PicaPipeline"/> | 89 | impl="org.onosproject.driver.pipeline.PicaPipeline"/> |
| 90 | </driver> | 90 | </driver> | ... | ... |
-
Please register or login to post a comment