Saurav Das

Fixes for the Pica8 pipeline and the cpqd emulation of the OFDPA pipeline.

Change-Id: Ib1982cdb7bc580cf86c43ace229388ee1f1106a2
...@@ -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>
......