blob: 21541b08783ddd8d30b40141ca03146c901d59c8 [file] [log] [blame]
Saurav Dase3274c82015-05-24 17:21:56 -07001/*
2 * Copyright 2015 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 */
16package org.onosproject.driver.pipeline;
17
Saurav Dase3274c82015-05-24 17:21:56 -070018import org.onlab.osgi.ServiceDirectory;
19import org.onlab.packet.Ethernet;
20import org.onlab.packet.IPv4;
Saurav Das337c7a42015-06-02 15:12:06 -070021import org.onlab.packet.MacAddress;
22import org.onlab.packet.VlanId;
Saurav Dase3274c82015-05-24 17:21:56 -070023import org.onlab.util.KryoNamespace;
24import org.onosproject.core.ApplicationId;
25import org.onosproject.core.CoreService;
26import org.onosproject.net.DeviceId;
Saurav Das337c7a42015-06-02 15:12:06 -070027import org.onosproject.net.PortNumber;
Saurav Dase3274c82015-05-24 17:21:56 -070028import org.onosproject.net.behaviour.NextGroup;
29import org.onosproject.net.behaviour.Pipeliner;
30import org.onosproject.net.behaviour.PipelinerContext;
31import org.onosproject.net.driver.AbstractHandlerBehaviour;
32import org.onosproject.net.flow.DefaultFlowRule;
33import org.onosproject.net.flow.DefaultTrafficSelector;
34import org.onosproject.net.flow.DefaultTrafficTreatment;
35import org.onosproject.net.flow.FlowRule;
36import org.onosproject.net.flow.FlowRuleOperations;
37import org.onosproject.net.flow.FlowRuleOperationsContext;
38import org.onosproject.net.flow.FlowRuleService;
39import org.onosproject.net.flow.TrafficSelector;
40import org.onosproject.net.flow.TrafficTreatment;
41import org.onosproject.net.flow.criteria.Criteria;
42import org.onosproject.net.flow.criteria.Criterion;
43import org.onosproject.net.flow.criteria.EthCriterion;
44import org.onosproject.net.flow.criteria.EthTypeCriterion;
45import org.onosproject.net.flow.criteria.IPCriterion;
46import org.onosproject.net.flow.criteria.IPProtocolCriterion;
47import org.onosproject.net.flow.criteria.PortCriterion;
48import org.onosproject.net.flow.criteria.VlanIdCriterion;
Saurav Das337c7a42015-06-02 15:12:06 -070049import org.onosproject.net.flow.instructions.Instruction;
50import org.onosproject.net.flow.instructions.L2ModificationInstruction;
Saurav Dase3274c82015-05-24 17:21:56 -070051import org.onosproject.net.flowobjective.FilteringObjective;
52import org.onosproject.net.flowobjective.FlowObjectiveStore;
53import org.onosproject.net.flowobjective.ForwardingObjective;
54import org.onosproject.net.flowobjective.NextObjective;
55import org.onosproject.net.flowobjective.Objective;
56import org.onosproject.net.flowobjective.ObjectiveError;
Saurav Das337c7a42015-06-02 15:12:06 -070057import org.onosproject.store.serializers.KryoNamespaces;
Saurav Dase3274c82015-05-24 17:21:56 -070058import org.slf4j.Logger;
59
Saurav Das337c7a42015-06-02 15:12:06 -070060import java.util.ArrayList;
Saurav Dase3274c82015-05-24 17:21:56 -070061import java.util.Collection;
62import java.util.Collections;
Saurav Das337c7a42015-06-02 15:12:06 -070063import java.util.List;
64import java.util.concurrent.ConcurrentHashMap;
Saurav Dase3274c82015-05-24 17:21:56 -070065
Saurav Dase3274c82015-05-24 17:21:56 -070066import static org.slf4j.LoggerFactory.getLogger;
67
68/**
69 * Pica pipeline handler.
70 */
71public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner {
72
Saurav Das337c7a42015-06-02 15:12:06 -070073 protected static final int IP_UNICAST_TABLE = 252;
74 protected static final int ACL_TABLE = 0;
Saurav Dase3274c82015-05-24 17:21:56 -070075
Saurav Das337c7a42015-06-02 15:12:06 -070076 //private static final int CONTROLLER_PRIORITY = 255;
Saurav Dase3274c82015-05-24 17:21:56 -070077 private static final int DROP_PRIORITY = 0;
78 private static final int HIGHEST_PRIORITY = 0xffff;
79
80 private final Logger log = getLogger(getClass());
81
82 private ServiceDirectory serviceDirectory;
83 private FlowRuleService flowRuleService;
84 private CoreService coreService;
Saurav Dase3274c82015-05-24 17:21:56 -070085 private FlowObjectiveStore flowObjectiveStore;
86 private DeviceId deviceId;
87 private ApplicationId appId;
Saurav Das337c7a42015-06-02 15:12:06 -070088 private Collection<Filter> filters;
89 private Collection<ForwardingObjective> pendingVersatiles;
Saurav Dase3274c82015-05-24 17:21:56 -070090
91 private KryoNamespace appKryo = new KryoNamespace.Builder()
Saurav Das337c7a42015-06-02 15:12:06 -070092 .register(KryoNamespaces.API)
Saurav Dase3274c82015-05-24 17:21:56 -070093 .register(PicaGroup.class)
94 .register(byte[].class)
95 .build();
96
Saurav Dase3274c82015-05-24 17:21:56 -070097 @Override
98 public void init(DeviceId deviceId, PipelinerContext context) {
99 this.serviceDirectory = context.directory();
100 this.deviceId = deviceId;
101
Saurav Dase3274c82015-05-24 17:21:56 -0700102 coreService = serviceDirectory.get(CoreService.class);
103 flowRuleService = serviceDirectory.get(FlowRuleService.class);
Saurav Dase3274c82015-05-24 17:21:56 -0700104 flowObjectiveStore = context.store();
Saurav Das337c7a42015-06-02 15:12:06 -0700105 filters = Collections.newSetFromMap(new ConcurrentHashMap<Filter, Boolean>());
106 pendingVersatiles = Collections.newSetFromMap(
107 new ConcurrentHashMap<ForwardingObjective, Boolean>());
Saurav Dase3274c82015-05-24 17:21:56 -0700108 appId = coreService.registerApplication(
109 "org.onosproject.driver.OVSPicaPipeline");
110
111 initializePipeline();
112 }
113
114 @Override
115 public void filter(FilteringObjective filteringObjective) {
116 if (filteringObjective.type() == FilteringObjective.Type.PERMIT) {
117 processFilter(filteringObjective,
118 filteringObjective.op() == Objective.Operation.ADD,
119 filteringObjective.appId());
120 } else {
121 fail(filteringObjective, ObjectiveError.UNSUPPORTED);
122 }
123 }
124
125 @Override
126 public void forward(ForwardingObjective fwd) {
127 Collection<FlowRule> rules;
128 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
129
130 rules = processForward(fwd);
131 switch (fwd.op()) {
132 case ADD:
133 rules.stream()
134 .filter(rule -> rule != null)
135 .forEach(flowBuilder::add);
136 break;
137 case REMOVE:
138 rules.stream()
139 .filter(rule -> rule != null)
140 .forEach(flowBuilder::remove);
141 break;
142 default:
143 fail(fwd, ObjectiveError.UNKNOWN);
144 log.warn("Unknown forwarding type {}", fwd.op());
145 }
146
147
148 flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
149 @Override
150 public void onSuccess(FlowRuleOperations ops) {
151 pass(fwd);
152 }
153
154 @Override
155 public void onError(FlowRuleOperations ops) {
156 fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
157 }
158 }));
159
160 }
161
162 @Override
163 public void next(NextObjective nextObjective) {
164 switch (nextObjective.type()) {
165 case SIMPLE:
166 Collection<TrafficTreatment> treatments = nextObjective.next();
Saurav Das337c7a42015-06-02 15:12:06 -0700167 if (treatments.size() != 1) {
168 log.error("Next Objectives of type Simple should only have a "
169 + "single Traffic Treatment. Next Objective Id:{}", nextObjective.id());
170 fail(nextObjective, ObjectiveError.BADPARAMS);
171 return;
Saurav Dase3274c82015-05-24 17:21:56 -0700172 }
Saurav Das337c7a42015-06-02 15:12:06 -0700173 TrafficTreatment treatment = treatments.iterator().next();
174 TrafficTreatment.Builder filteredTreatment = DefaultTrafficTreatment.builder();
175 VlanId modVlanId;
176 for (Instruction ins : treatment.allInstructions()) {
177 if (ins.type() == Instruction.Type.L2MODIFICATION) {
178 L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
179 switch (l2ins.subtype()) {
180 case ETH_DST:
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 }
203 }
204 // store for future use
205 flowObjectiveStore.putNextGroup(nextObjective.id(),
206 new PicaGroup(filteredTreatment.build()));
Saurav Dase3274c82015-05-24 17:21:56 -0700207 break;
208 case HASHED:
209 case BROADCAST:
210 case FAILOVER:
211 fail(nextObjective, ObjectiveError.UNSUPPORTED);
212 log.warn("Unsupported next objective type {}", nextObjective.type());
213 break;
214 default:
215 fail(nextObjective, ObjectiveError.UNKNOWN);
216 log.warn("Unknown next objective type {}", nextObjective.type());
217 }
218
219 }
220
221 private Collection<FlowRule> processForward(ForwardingObjective fwd) {
222 switch (fwd.flag()) {
223 case SPECIFIC:
224 return processSpecific(fwd);
225 case VERSATILE:
226 return processVersatile(fwd);
227 default:
228 fail(fwd, ObjectiveError.UNKNOWN);
229 log.warn("Unknown forwarding flag {}", fwd.flag());
230 }
231 return Collections.emptySet();
232 }
233
234 private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
235 log.debug("Processing versatile forwarding objective");
236 TrafficSelector selector = fwd.selector();
237
238 EthTypeCriterion ethType =
239 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
240 if (ethType == null) {
241 log.error("Versatile forwarding objective must include ethType");
242 fail(fwd, ObjectiveError.UNKNOWN);
243 return Collections.emptySet();
244 }
Saurav Das337c7a42015-06-02 15:12:06 -0700245
Saurav Dase3274c82015-05-24 17:21:56 -0700246 if (ethType.ethType() == Ethernet.TYPE_ARP) {
Saurav Das337c7a42015-06-02 15:12:06 -0700247 if (filters.isEmpty()) {
248 pendingVersatiles.add(fwd);
249 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;
Saurav Dase3274c82015-05-24 17:21:56 -0700256 } else if (ethType.ethType() == Ethernet.TYPE_LLDP ||
257 ethType.ethType() == Ethernet.TYPE_BSN) {
258 log.warn("Driver currently does not currently handle LLDP packets");
259 fail(fwd, ObjectiveError.UNSUPPORTED);
260 return Collections.emptySet();
261 } else if (ethType.ethType() == Ethernet.TYPE_IPV4) {
262 IPCriterion ipSrc = (IPCriterion) selector
263 .getCriterion(Criterion.Type.IPV4_SRC);
264 IPCriterion ipDst = (IPCriterion) selector
265 .getCriterion(Criterion.Type.IPV4_DST);
266 IPProtocolCriterion ipProto = (IPProtocolCriterion) selector
267 .getCriterion(Criterion.Type.IP_PROTO);
268 if (ipSrc != null) {
269 log.warn("Driver does not currently handle matching Src IP");
270 fail(fwd, ObjectiveError.UNSUPPORTED);
271 return Collections.emptySet();
272 }
273 if (ipDst != null) {
274 log.error("Driver handles Dst IP matching as specific forwarding "
275 + "objective, not versatile");
276 fail(fwd, ObjectiveError.UNSUPPORTED);
277 return Collections.emptySet();
278 }
279 if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) {
280 log.warn("Driver automatically punts all packets reaching the "
Saurav Das337c7a42015-06-02 15:12:06 -0700281 + "ACL table to the controller");
Saurav Dase3274c82015-05-24 17:21:56 -0700282 pass(fwd);
283 return Collections.emptySet();
284 }
285 }
286
287 log.warn("Driver does not support given versatile forwarding objective");
288 fail(fwd, ObjectiveError.UNSUPPORTED);
289 return Collections.emptySet();
290 }
291
Saurav Das337c7a42015-06-02 15:12:06 -0700292 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
Saurav Dase3274c82015-05-24 17:21:56 -0700337 private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
338 log.debug("Processing specific forwarding objective");
339 TrafficSelector selector = fwd.selector();
340 EthTypeCriterion ethType =
341 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
342 if (ethType == null || ethType.ethType() != Ethernet.TYPE_IPV4) {
343 fail(fwd, ObjectiveError.UNSUPPORTED);
344 return Collections.emptySet();
345 }
346
Saurav Das337c7a42015-06-02 15:12:06 -0700347 List<FlowRule> ipflows = new ArrayList<FlowRule>();
348 for (Filter f: filters) {
349 TrafficSelector filteredSelector =
350 DefaultTrafficSelector.builder()
351 .matchEthType(Ethernet.TYPE_IPV4)
352 .matchIPDst(
Saurav Dase3274c82015-05-24 17:21:56 -0700353 ((IPCriterion)
354 selector.getCriterion(Criterion.Type.IPV4_DST)).ip())
Saurav Das337c7a42015-06-02 15:12:06 -0700355 .matchEthDst(f.mac())
356 .matchVlanId(f.vlanId())
357 .build();
358 TrafficTreatment tt = null;
359 if (fwd.nextId() != null) {
360 NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
361 if (next == null) {
362 log.error("next-id {} does not exist in store", fwd.nextId());
363 return Collections.emptySet();
364 }
365 tt = appKryo.deserialize(next.data());
366 if (tt == null) {
367 log.error("Error in deserializing next-id {}", fwd.nextId());
368 return Collections.emptySet();
369 }
Saurav Dase3274c82015-05-24 17:21:56 -0700370 }
Saurav Das337c7a42015-06-02 15:12:06 -0700371
372 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
373 .fromApp(fwd.appId())
374 .withPriority(fwd.priority())
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());
Saurav Dase3274c82015-05-24 17:21:56 -0700385 }
386
Saurav Das337c7a42015-06-02 15:12:06 -0700387 return ipflows;
Saurav Dase3274c82015-05-24 17:21:56 -0700388 }
389
390 private void processFilter(FilteringObjective filt, boolean install,
391 ApplicationId applicationId) {
392 // This driver only processes filtering criteria defined with switch
393 // ports as the key
394 PortCriterion p;
395 if (!filt.key().equals(Criteria.dummy()) &&
396 filt.key().type() == Criterion.Type.IN_PORT) {
397 p = (PortCriterion) filt.key();
398 } else {
399 log.warn("No key defined in filtering objective from app: {}. Not"
400 + "processing filtering objective", applicationId);
401 fail(filt, ObjectiveError.UNKNOWN);
402 return;
403 }
Saurav Das337c7a42015-06-02 15:12:06 -0700404
405 EthCriterion e = null; VlanIdCriterion v = null;
406 Collection<IPCriterion> ips = new ArrayList<IPCriterion>();
Saurav Dase3274c82015-05-24 17:21:56 -0700407 // convert filtering conditions for switch-intfs into flowrules
408 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
409 for (Criterion c : filt.conditions()) {
410 if (c.type() == Criterion.Type.ETH_DST) {
Saurav Das337c7a42015-06-02 15:12:06 -0700411 e = (EthCriterion) c;
Saurav Dase3274c82015-05-24 17:21:56 -0700412 } else if (c.type() == Criterion.Type.VLAN_VID) {
Saurav Das337c7a42015-06-02 15:12:06 -0700413 v = (VlanIdCriterion) c;
Saurav Dase3274c82015-05-24 17:21:56 -0700414 } else if (c.type() == Criterion.Type.IPV4_DST) {
Saurav Das337c7a42015-06-02 15:12:06 -0700415 ips.add((IPCriterion) c);
Saurav Dase3274c82015-05-24 17:21:56 -0700416 } else {
Saurav Das337c7a42015-06-02 15:12:06 -0700417 log.error("Unsupported filter {}", c);
Saurav Dase3274c82015-05-24 17:21:56 -0700418 fail(filt, ObjectiveError.UNSUPPORTED);
Saurav Das337c7a42015-06-02 15:12:06 -0700419 return;
Saurav Dase3274c82015-05-24 17:21:56 -0700420 }
421 }
Saurav Das337c7a42015-06-02 15:12:06 -0700422
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);
432 }
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
Saurav Dase3274c82015-05-24 17:21:56 -0700456 // apply filtering flow rules
457 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
458 @Override
459 public void onSuccess(FlowRuleOperations ops) {
460 pass(filt);
461 log.info("Applied filtering rules");
462 }
463
464 @Override
465 public void onError(FlowRuleOperations ops) {
466 fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
467 log.info("Failed to apply filtering rules");
468 }
469 }));
470 }
471
472 private void pass(Objective obj) {
473 if (obj.context().isPresent()) {
474 obj.context().get().onSuccess(obj);
475 }
476 }
477
478 private void fail(Objective obj, ObjectiveError error) {
479 if (obj.context().isPresent()) {
480 obj.context().get().onError(obj, error);
481 }
482 }
483
484 private void initializePipeline() {
Saurav Das337c7a42015-06-02 15:12:06 -0700485 //processIpUnicastTable(true);
486 processACLTable(true);
Saurav Dase3274c82015-05-24 17:21:56 -0700487 }
488
Saurav Das337c7a42015-06-02 15:12:06 -0700489 private void processACLTable(boolean install) {
Saurav Dase3274c82015-05-24 17:21:56 -0700490 TrafficSelector.Builder selector;
491 TrafficTreatment.Builder treatment;
492 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
493 FlowRule rule;
494
495 //Drop rule
496 selector = DefaultTrafficSelector.builder();
497 treatment = DefaultTrafficTreatment.builder();
498
Saurav Dase3274c82015-05-24 17:21:56 -0700499 rule = DefaultFlowRule.builder()
500 .forDevice(deviceId)
501 .withSelector(selector.build())
502 .withTreatment(treatment.build())
503 .withPriority(DROP_PRIORITY)
504 .fromApp(appId)
505 .makePermanent()
Saurav Das337c7a42015-06-02 15:12:06 -0700506 .forTable(ACL_TABLE).build();
Saurav Dase3274c82015-05-24 17:21:56 -0700507
508 ops = install ? ops.add(rule) : ops.remove(rule);
509
510 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
511 @Override
512 public void onSuccess(FlowRuleOperations ops) {
Saurav Das337c7a42015-06-02 15:12:06 -0700513 log.info("Provisioned ACL table");
Saurav Dase3274c82015-05-24 17:21:56 -0700514 }
515
516 @Override
517 public void onError(FlowRuleOperations ops) {
Saurav Das337c7a42015-06-02 15:12:06 -0700518 log.info("Failed to provision ACL table");
Saurav Dase3274c82015-05-24 17:21:56 -0700519 }
520 }));
521 }
522
Saurav Das337c7a42015-06-02 15:12:06 -0700523 private class Filter {
524 private PortCriterion port;
525 private VlanIdCriterion vlan;
526 private EthCriterion eth;
Saurav Dase3274c82015-05-24 17:21:56 -0700527
Saurav Das337c7a42015-06-02 15:12:06 -0700528 @SuppressWarnings("unused")
529 private Collection<IPCriterion> ips;
Saurav Dase3274c82015-05-24 17:21:56 -0700530
Saurav Das337c7a42015-06-02 15:12:06 -0700531 public Filter(PortCriterion p, EthCriterion e, VlanIdCriterion v,
532 Collection<IPCriterion> ips) {
533 this.eth = e;
534 this.port = p;
535 this.vlan = v;
536 this.ips = ips;
Saurav Dase3274c82015-05-24 17:21:56 -0700537 }
Saurav Dase3274c82015-05-24 17:21:56 -0700538
Saurav Das337c7a42015-06-02 15:12:06 -0700539 public PortNumber port() {
540 return port.port();
541 }
Saurav Dase3274c82015-05-24 17:21:56 -0700542
Saurav Das337c7a42015-06-02 15:12:06 -0700543 public VlanId vlanId() {
544 return vlan.vlanId();
545 }
Saurav Dase3274c82015-05-24 17:21:56 -0700546
Saurav Das337c7a42015-06-02 15:12:06 -0700547 public MacAddress mac() {
548 return eth.mac();
Saurav Dase3274c82015-05-24 17:21:56 -0700549 }
550 }
551
552 private class PicaGroup implements NextGroup {
Saurav Das337c7a42015-06-02 15:12:06 -0700553 TrafficTreatment nextActions;
Saurav Dase3274c82015-05-24 17:21:56 -0700554
Saurav Das337c7a42015-06-02 15:12:06 -0700555 public PicaGroup(TrafficTreatment next) {
556 this.nextActions = next;
Saurav Dase3274c82015-05-24 17:21:56 -0700557 }
558
559 @Override
560 public byte[] data() {
Saurav Das337c7a42015-06-02 15:12:06 -0700561 return appKryo.serialize(nextActions);
Saurav Dase3274c82015-05-24 17:21:56 -0700562 }
563
564 }
565}