blob: 57ef6eadb338b3a94eb81d22df7e3dff615ec7e3 [file] [log] [blame]
Saurav Dase3274c82015-05-24 17:21:56 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Saurav Dase3274c82015-05-24 17:21:56 -07003 *
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;
Saurav Das337c7a42015-06-02 15:12:06 -070020import org.onlab.packet.MacAddress;
21import org.onlab.packet.VlanId;
Saurav Dase3274c82015-05-24 17:21:56 -070022import org.onlab.util.KryoNamespace;
23import org.onosproject.core.ApplicationId;
24import org.onosproject.core.CoreService;
25import org.onosproject.net.DeviceId;
Saurav Das337c7a42015-06-02 15:12:06 -070026import org.onosproject.net.PortNumber;
Saurav Dase3274c82015-05-24 17:21:56 -070027import org.onosproject.net.behaviour.NextGroup;
28import org.onosproject.net.behaviour.Pipeliner;
29import org.onosproject.net.behaviour.PipelinerContext;
30import org.onosproject.net.driver.AbstractHandlerBehaviour;
31import org.onosproject.net.flow.DefaultFlowRule;
32import org.onosproject.net.flow.DefaultTrafficSelector;
33import org.onosproject.net.flow.DefaultTrafficTreatment;
34import org.onosproject.net.flow.FlowRule;
35import org.onosproject.net.flow.FlowRuleOperations;
36import org.onosproject.net.flow.FlowRuleOperationsContext;
37import org.onosproject.net.flow.FlowRuleService;
38import org.onosproject.net.flow.TrafficSelector;
39import org.onosproject.net.flow.TrafficTreatment;
40import org.onosproject.net.flow.criteria.Criteria;
41import org.onosproject.net.flow.criteria.Criterion;
42import org.onosproject.net.flow.criteria.EthCriterion;
43import org.onosproject.net.flow.criteria.EthTypeCriterion;
44import org.onosproject.net.flow.criteria.IPCriterion;
Saurav Dase3274c82015-05-24 17:21:56 -070045import org.onosproject.net.flow.criteria.PortCriterion;
46import org.onosproject.net.flow.criteria.VlanIdCriterion;
Saurav Das337c7a42015-06-02 15:12:06 -070047import org.onosproject.net.flow.instructions.Instruction;
48import org.onosproject.net.flow.instructions.L2ModificationInstruction;
Saurav Dase3274c82015-05-24 17:21:56 -070049import org.onosproject.net.flowobjective.FilteringObjective;
50import org.onosproject.net.flowobjective.FlowObjectiveStore;
51import org.onosproject.net.flowobjective.ForwardingObjective;
52import org.onosproject.net.flowobjective.NextObjective;
53import org.onosproject.net.flowobjective.Objective;
54import org.onosproject.net.flowobjective.ObjectiveError;
Saurav Das337c7a42015-06-02 15:12:06 -070055import org.onosproject.store.serializers.KryoNamespaces;
Saurav Dase3274c82015-05-24 17:21:56 -070056import org.slf4j.Logger;
57
Saurav Das337c7a42015-06-02 15:12:06 -070058import java.util.ArrayList;
Saurav Dase3274c82015-05-24 17:21:56 -070059import java.util.Collection;
60import java.util.Collections;
Saurav Das337c7a42015-06-02 15:12:06 -070061import java.util.List;
Sho SHIMIZU45906042016-01-13 23:05:54 -080062import java.util.Objects;
Saurav Das337c7a42015-06-02 15:12:06 -070063import java.util.concurrent.ConcurrentHashMap;
Saurav Dase3274c82015-05-24 17:21:56 -070064
Saurav Dase3274c82015-05-24 17:21:56 -070065import static org.slf4j.LoggerFactory.getLogger;
66
67/**
68 * Pica pipeline handler.
69 */
70public class PicaPipeline extends AbstractHandlerBehaviour implements Pipeliner {
71
Saurav Das337c7a42015-06-02 15:12:06 -070072 protected static final int IP_UNICAST_TABLE = 252;
73 protected static final int ACL_TABLE = 0;
Saurav Dase3274c82015-05-24 17:21:56 -070074
Saurav Das337c7a42015-06-02 15:12:06 -070075 //private static final int CONTROLLER_PRIORITY = 255;
Saurav Dase3274c82015-05-24 17:21:56 -070076 private static final int DROP_PRIORITY = 0;
77 private static final int HIGHEST_PRIORITY = 0xffff;
78
79 private final Logger log = getLogger(getClass());
80
81 private ServiceDirectory serviceDirectory;
82 private FlowRuleService flowRuleService;
83 private CoreService coreService;
Saurav Dase3274c82015-05-24 17:21:56 -070084 private FlowObjectiveStore flowObjectiveStore;
85 private DeviceId deviceId;
86 private ApplicationId appId;
Saurav Das337c7a42015-06-02 15:12:06 -070087 private Collection<Filter> filters;
88 private Collection<ForwardingObjective> pendingVersatiles;
Saurav Dase3274c82015-05-24 17:21:56 -070089
90 private KryoNamespace appKryo = new KryoNamespace.Builder()
Saurav Das337c7a42015-06-02 15:12:06 -070091 .register(KryoNamespaces.API)
Saurav Dase3274c82015-05-24 17:21:56 -070092 .register(PicaGroup.class)
Charles Chaneefdedf2016-05-23 16:45:45 -070093 .build("PicaPipeline");
Saurav Dase3274c82015-05-24 17:21:56 -070094
Saurav Dase3274c82015-05-24 17:21:56 -070095 @Override
96 public void init(DeviceId deviceId, PipelinerContext context) {
97 this.serviceDirectory = context.directory();
98 this.deviceId = deviceId;
99
Saurav Dase3274c82015-05-24 17:21:56 -0700100 coreService = serviceDirectory.get(CoreService.class);
101 flowRuleService = serviceDirectory.get(FlowRuleService.class);
Saurav Dase3274c82015-05-24 17:21:56 -0700102 flowObjectiveStore = context.store();
Saurav Das337c7a42015-06-02 15:12:06 -0700103 filters = Collections.newSetFromMap(new ConcurrentHashMap<Filter, Boolean>());
104 pendingVersatiles = Collections.newSetFromMap(
105 new ConcurrentHashMap<ForwardingObjective, Boolean>());
Saurav Dase3274c82015-05-24 17:21:56 -0700106 appId = coreService.registerApplication(
107 "org.onosproject.driver.OVSPicaPipeline");
108
109 initializePipeline();
110 }
111
112 @Override
113 public void filter(FilteringObjective filteringObjective) {
114 if (filteringObjective.type() == FilteringObjective.Type.PERMIT) {
115 processFilter(filteringObjective,
116 filteringObjective.op() == Objective.Operation.ADD,
117 filteringObjective.appId());
118 } else {
119 fail(filteringObjective, ObjectiveError.UNSUPPORTED);
120 }
121 }
122
123 @Override
124 public void forward(ForwardingObjective fwd) {
125 Collection<FlowRule> rules;
126 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
127
128 rules = processForward(fwd);
129 switch (fwd.op()) {
130 case ADD:
131 rules.stream()
Sho SHIMIZU45906042016-01-13 23:05:54 -0800132 .filter(Objects::nonNull)
Saurav Dase3274c82015-05-24 17:21:56 -0700133 .forEach(flowBuilder::add);
134 break;
135 case REMOVE:
136 rules.stream()
Sho SHIMIZU45906042016-01-13 23:05:54 -0800137 .filter(Objects::nonNull)
Saurav Dase3274c82015-05-24 17:21:56 -0700138 .forEach(flowBuilder::remove);
139 break;
140 default:
141 fail(fwd, ObjectiveError.UNKNOWN);
142 log.warn("Unknown forwarding type {}", fwd.op());
143 }
144
145
146 flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
147 @Override
148 public void onSuccess(FlowRuleOperations ops) {
149 pass(fwd);
150 }
151
152 @Override
153 public void onError(FlowRuleOperations ops) {
154 fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
155 }
156 }));
157
158 }
159
160 @Override
161 public void next(NextObjective nextObjective) {
162 switch (nextObjective.type()) {
163 case SIMPLE:
164 Collection<TrafficTreatment> treatments = nextObjective.next();
Saurav Das337c7a42015-06-02 15:12:06 -0700165 if (treatments.size() != 1) {
166 log.error("Next Objectives of type Simple should only have a "
167 + "single Traffic Treatment. Next Objective Id:{}", nextObjective.id());
168 fail(nextObjective, ObjectiveError.BADPARAMS);
169 return;
Saurav Dase3274c82015-05-24 17:21:56 -0700170 }
Saurav Das337c7a42015-06-02 15:12:06 -0700171 TrafficTreatment treatment = treatments.iterator().next();
172 TrafficTreatment.Builder filteredTreatment = DefaultTrafficTreatment.builder();
173 VlanId modVlanId;
174 for (Instruction ins : treatment.allInstructions()) {
175 if (ins.type() == Instruction.Type.L2MODIFICATION) {
176 L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
177 switch (l2ins.subtype()) {
178 case ETH_DST:
179 filteredTreatment.setEthDst(
180 ((L2ModificationInstruction.ModEtherInstruction) l2ins).mac());
181 break;
182 case ETH_SRC:
183 filteredTreatment.setEthSrc(
184 ((L2ModificationInstruction.ModEtherInstruction) l2ins).mac());
185 break;
186 case VLAN_ID:
187 modVlanId = ((L2ModificationInstruction.ModVlanIdInstruction) l2ins).vlanId();
188 filteredTreatment.setVlanId(modVlanId);
189 break;
190 default:
191 break;
192 }
193 } else if (ins.type() == Instruction.Type.OUTPUT) {
194 //long portNum = ((Instructions.OutputInstruction) ins).port().toLong();
195 filteredTreatment.add(ins);
196 } else {
197 // Ignore the vlan_pcp action since it's does matter much.
198 log.warn("Driver does not handle this type of TrafficTreatment"
199 + " instruction in nextObjectives: {}", ins.type());
200 }
201 }
202 // store for future use
203 flowObjectiveStore.putNextGroup(nextObjective.id(),
204 new PicaGroup(filteredTreatment.build()));
Saurav Dase3274c82015-05-24 17:21:56 -0700205 break;
206 case HASHED:
207 case BROADCAST:
208 case FAILOVER:
209 fail(nextObjective, ObjectiveError.UNSUPPORTED);
210 log.warn("Unsupported next objective type {}", nextObjective.type());
211 break;
212 default:
213 fail(nextObjective, ObjectiveError.UNKNOWN);
214 log.warn("Unknown next objective type {}", nextObjective.type());
215 }
216
217 }
218
Daniele Moro06aac702021-07-19 22:39:22 +0200219 @Override
220 public void purgeAll(ApplicationId appId) {
221 flowRuleService.purgeFlowRules(deviceId, appId);
222 }
223
Saurav Dase3274c82015-05-24 17:21:56 -0700224 private Collection<FlowRule> processForward(ForwardingObjective fwd) {
225 switch (fwd.flag()) {
226 case SPECIFIC:
227 return processSpecific(fwd);
228 case VERSATILE:
229 return processVersatile(fwd);
230 default:
231 fail(fwd, ObjectiveError.UNKNOWN);
232 log.warn("Unknown forwarding flag {}", fwd.flag());
233 }
234 return Collections.emptySet();
235 }
236
237 private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
238 log.debug("Processing versatile forwarding objective");
239 TrafficSelector selector = fwd.selector();
Saurav Das598a02f2015-08-31 18:19:30 -0700240 TrafficTreatment treatment = fwd.treatment();
241 Collection<FlowRule> flowrules = new ArrayList<FlowRule>();
242
243 // first add this rule for basic single-table operation
244 // or non-ARP related multi-table operation
245 FlowRule rule = DefaultFlowRule.builder()
246 .forDevice(deviceId)
247 .withSelector(selector)
248 .withTreatment(treatment)
249 .withPriority(fwd.priority())
250 .fromApp(fwd.appId())
251 .makePermanent()
252 .forTable(ACL_TABLE).build();
253 flowrules.add(rule);
Saurav Dase3274c82015-05-24 17:21:56 -0700254
255 EthTypeCriterion ethType =
256 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
257 if (ethType == null) {
Saurav Das598a02f2015-08-31 18:19:30 -0700258 log.warn("No ethType in versatile forwarding obj. Not processing further.");
259 return flowrules;
Saurav Dase3274c82015-05-24 17:21:56 -0700260 }
Saurav Das337c7a42015-06-02 15:12:06 -0700261
Saurav Das598a02f2015-08-31 18:19:30 -0700262 // now deal with possible mix of ARP with filtering objectives
263 // in multi-table scenarios
alshabibcaf1ca22015-06-25 15:18:16 -0700264 if (ethType.ethType().toShort() == Ethernet.TYPE_ARP) {
Saurav Das337c7a42015-06-02 15:12:06 -0700265 if (filters.isEmpty()) {
266 pendingVersatiles.add(fwd);
Saurav Das598a02f2015-08-31 18:19:30 -0700267 return flowrules;
Saurav Das337c7a42015-06-02 15:12:06 -0700268 }
Saurav Das337c7a42015-06-02 15:12:06 -0700269 for (Filter filter : filters) {
270 flowrules.addAll(processVersatilesWithFilters(filter, fwd));
271 }
Saurav Dase3274c82015-05-24 17:21:56 -0700272 }
Saurav Das598a02f2015-08-31 18:19:30 -0700273 return flowrules;
Saurav Dase3274c82015-05-24 17:21:56 -0700274 }
275
Saurav Das337c7a42015-06-02 15:12:06 -0700276 private Collection<FlowRule> processVersatilesWithFilters(
277 Filter filt, ForwardingObjective fwd) {
278 Collection<FlowRule> flows = new ArrayList<FlowRule>();
279
280 // rule for ARP replies
281 log.debug("adding ARP rule in ACL table");
282 TrafficSelector.Builder sel = DefaultTrafficSelector.builder();
283 TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
284 sel.matchInPort(filt.port());
285 sel.matchVlanId(filt.vlanId());
286 sel.matchEthDst(filt.mac());
287 sel.matchEthType(Ethernet.TYPE_ARP);
288 treat.setOutput(PortNumber.CONTROLLER);
289 FlowRule rule = DefaultFlowRule.builder()
290 .forDevice(deviceId)
291 .withSelector(sel.build())
292 .withTreatment(treat.build())
293 .withPriority(HIGHEST_PRIORITY)
294 .fromApp(appId)
295 .makePermanent()
296 .forTable(ACL_TABLE).build();
297 flows.add(rule);
298
299 // rule for ARP Broadcast
300 sel = DefaultTrafficSelector.builder();
301 treat = DefaultTrafficTreatment.builder();
302 sel.matchInPort(filt.port());
303 sel.matchVlanId(filt.vlanId());
304 sel.matchEthDst(MacAddress.BROADCAST);
305 sel.matchEthType(Ethernet.TYPE_ARP);
306 treat.setOutput(PortNumber.CONTROLLER);
307 rule = DefaultFlowRule.builder()
308 .forDevice(deviceId)
309 .withSelector(sel.build())
310 .withTreatment(treat.build())
311 .withPriority(HIGHEST_PRIORITY)
312 .fromApp(appId)
313 .makePermanent()
314 .forTable(ACL_TABLE).build();
315 flows.add(rule);
316
317 return flows;
318 }
319
320
Saurav Dase3274c82015-05-24 17:21:56 -0700321 private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
322 log.debug("Processing specific forwarding objective");
323 TrafficSelector selector = fwd.selector();
324 EthTypeCriterion ethType =
325 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
alshabibcaf1ca22015-06-25 15:18:16 -0700326 if (ethType == null || ethType.ethType().toShort() != Ethernet.TYPE_IPV4) {
Saurav Dase3274c82015-05-24 17:21:56 -0700327 fail(fwd, ObjectiveError.UNSUPPORTED);
328 return Collections.emptySet();
329 }
330
Saurav Das337c7a42015-06-02 15:12:06 -0700331 List<FlowRule> ipflows = new ArrayList<FlowRule>();
332 for (Filter f: filters) {
333 TrafficSelector filteredSelector =
334 DefaultTrafficSelector.builder()
335 .matchEthType(Ethernet.TYPE_IPV4)
336 .matchIPDst(
Saurav Dase3274c82015-05-24 17:21:56 -0700337 ((IPCriterion)
338 selector.getCriterion(Criterion.Type.IPV4_DST)).ip())
Saurav Das337c7a42015-06-02 15:12:06 -0700339 .matchEthDst(f.mac())
340 .matchVlanId(f.vlanId())
341 .build();
342 TrafficTreatment tt = null;
343 if (fwd.nextId() != null) {
344 NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
345 if (next == null) {
346 log.error("next-id {} does not exist in store", fwd.nextId());
347 return Collections.emptySet();
348 }
349 tt = appKryo.deserialize(next.data());
350 if (tt == null) {
351 log.error("Error in deserializing next-id {}", fwd.nextId());
352 return Collections.emptySet();
353 }
Saurav Dase3274c82015-05-24 17:21:56 -0700354 }
Saurav Das337c7a42015-06-02 15:12:06 -0700355
356 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
357 .fromApp(fwd.appId())
358 .withPriority(fwd.priority())
359 .forDevice(deviceId)
360 .withSelector(filteredSelector)
361 .withTreatment(tt);
362 if (fwd.permanent()) {
363 ruleBuilder.makePermanent();
364 } else {
365 ruleBuilder.makeTemporary(fwd.timeout());
366 }
367 ruleBuilder.forTable(IP_UNICAST_TABLE);
368 ipflows.add(ruleBuilder.build());
Saurav Dase3274c82015-05-24 17:21:56 -0700369 }
370
Saurav Das337c7a42015-06-02 15:12:06 -0700371 return ipflows;
Saurav Dase3274c82015-05-24 17:21:56 -0700372 }
373
374 private void processFilter(FilteringObjective filt, boolean install,
375 ApplicationId applicationId) {
376 // This driver only processes filtering criteria defined with switch
377 // ports as the key
378 PortCriterion p;
379 if (!filt.key().equals(Criteria.dummy()) &&
380 filt.key().type() == Criterion.Type.IN_PORT) {
381 p = (PortCriterion) filt.key();
382 } else {
383 log.warn("No key defined in filtering objective from app: {}. Not"
384 + "processing filtering objective", applicationId);
385 fail(filt, ObjectiveError.UNKNOWN);
386 return;
387 }
Saurav Das337c7a42015-06-02 15:12:06 -0700388
Ray Milkey74e59132018-01-17 15:24:52 -0800389 EthCriterion e = null;
390 VlanIdCriterion v = null;
Saurav Das337c7a42015-06-02 15:12:06 -0700391 Collection<IPCriterion> ips = new ArrayList<IPCriterion>();
Saurav Dase3274c82015-05-24 17:21:56 -0700392 // convert filtering conditions for switch-intfs into flowrules
393 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
394 for (Criterion c : filt.conditions()) {
395 if (c.type() == Criterion.Type.ETH_DST) {
Saurav Das337c7a42015-06-02 15:12:06 -0700396 e = (EthCriterion) c;
Saurav Dase3274c82015-05-24 17:21:56 -0700397 } else if (c.type() == Criterion.Type.VLAN_VID) {
Saurav Das337c7a42015-06-02 15:12:06 -0700398 v = (VlanIdCriterion) c;
Saurav Dase3274c82015-05-24 17:21:56 -0700399 } else if (c.type() == Criterion.Type.IPV4_DST) {
Saurav Das337c7a42015-06-02 15:12:06 -0700400 ips.add((IPCriterion) c);
Saurav Dase3274c82015-05-24 17:21:56 -0700401 } else {
Saurav Das337c7a42015-06-02 15:12:06 -0700402 log.error("Unsupported filter {}", c);
Saurav Dase3274c82015-05-24 17:21:56 -0700403 fail(filt, ObjectiveError.UNSUPPORTED);
Saurav Das337c7a42015-06-02 15:12:06 -0700404 return;
Saurav Dase3274c82015-05-24 17:21:56 -0700405 }
406 }
Saurav Das337c7a42015-06-02 15:12:06 -0700407
Ray Milkey74e59132018-01-17 15:24:52 -0800408 if (v == null || e == null) {
409 log.warn("Pica Pipeline ETH_DST and/or VLAN_ID not specified");
410 fail(filt, ObjectiveError.BADPARAMS);
411 return;
412 }
413
Saurav Das337c7a42015-06-02 15:12:06 -0700414 // cache for later use
415 Filter filter = new Filter(p, e, v, ips);
416 filters.add(filter);
417
418 // apply any pending versatile forwarding objectives
419 for (ForwardingObjective fwd : pendingVersatiles) {
420 Collection<FlowRule> ret = processVersatilesWithFilters(filter, fwd);
421 for (FlowRule fr : ret) {
422 ops.add(fr);
423 }
424 }
425
426 for (IPCriterion ipaddr : ips) {
427 log.debug("adding IP filtering rules in ACL table: {}", ipaddr.ip());
428 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
429 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
430 selector.matchInPort(p.port());
431 selector.matchVlanId(v.vlanId());
432 selector.matchEthDst(e.mac());
433 selector.matchEthType(Ethernet.TYPE_IPV4);
434 selector.matchIPDst(ipaddr.ip()); // router IPs to the controller
435 treatment.setOutput(PortNumber.CONTROLLER);
436 FlowRule rule = DefaultFlowRule.builder()
437 .forDevice(deviceId)
438 .withSelector(selector.build())
439 .withTreatment(treatment.build())
440 .withPriority(HIGHEST_PRIORITY)
441 .fromApp(applicationId)
442 .makePermanent()
443 .forTable(ACL_TABLE).build();
444 ops = ops.add(rule);
445 }
446
Saurav Dase3274c82015-05-24 17:21:56 -0700447 // apply filtering flow rules
448 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
449 @Override
450 public void onSuccess(FlowRuleOperations ops) {
451 pass(filt);
452 log.info("Applied filtering rules");
453 }
454
455 @Override
456 public void onError(FlowRuleOperations ops) {
457 fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
458 log.info("Failed to apply filtering rules");
459 }
460 }));
461 }
462
463 private void pass(Objective obj) {
Sho SHIMIZUef7e2902016-02-12 18:38:29 -0800464 obj.context().ifPresent(context -> context.onSuccess(obj));
Saurav Dase3274c82015-05-24 17:21:56 -0700465 }
466
467 private void fail(Objective obj, ObjectiveError error) {
Sho SHIMIZUef7e2902016-02-12 18:38:29 -0800468 obj.context().ifPresent(context -> context.onError(obj, error));
Saurav Dase3274c82015-05-24 17:21:56 -0700469 }
470
471 private void initializePipeline() {
Saurav Das337c7a42015-06-02 15:12:06 -0700472 //processIpUnicastTable(true);
Jonathan Hartb35540a2015-11-17 09:30:56 -0800473 processAclTable(true);
Saurav Dase3274c82015-05-24 17:21:56 -0700474 }
475
Jonathan Hartb35540a2015-11-17 09:30:56 -0800476 private void processAclTable(boolean install) {
Saurav Dase3274c82015-05-24 17:21:56 -0700477 TrafficSelector.Builder selector;
478 TrafficTreatment.Builder treatment;
479 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
480 FlowRule rule;
481
482 //Drop rule
483 selector = DefaultTrafficSelector.builder();
484 treatment = DefaultTrafficTreatment.builder();
485
Saurav Dase3274c82015-05-24 17:21:56 -0700486 rule = DefaultFlowRule.builder()
487 .forDevice(deviceId)
488 .withSelector(selector.build())
489 .withTreatment(treatment.build())
490 .withPriority(DROP_PRIORITY)
491 .fromApp(appId)
492 .makePermanent()
Saurav Das337c7a42015-06-02 15:12:06 -0700493 .forTable(ACL_TABLE).build();
Saurav Dase3274c82015-05-24 17:21:56 -0700494
495 ops = install ? ops.add(rule) : ops.remove(rule);
496
497 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
498 @Override
499 public void onSuccess(FlowRuleOperations ops) {
Saurav Das337c7a42015-06-02 15:12:06 -0700500 log.info("Provisioned ACL table");
Saurav Dase3274c82015-05-24 17:21:56 -0700501 }
502
503 @Override
504 public void onError(FlowRuleOperations ops) {
Saurav Das337c7a42015-06-02 15:12:06 -0700505 log.info("Failed to provision ACL table");
Saurav Dase3274c82015-05-24 17:21:56 -0700506 }
507 }));
508 }
509
Saurav Das337c7a42015-06-02 15:12:06 -0700510 private class Filter {
511 private PortCriterion port;
512 private VlanIdCriterion vlan;
513 private EthCriterion eth;
Saurav Dase3274c82015-05-24 17:21:56 -0700514
Saurav Das337c7a42015-06-02 15:12:06 -0700515 @SuppressWarnings("unused")
516 private Collection<IPCriterion> ips;
Saurav Dase3274c82015-05-24 17:21:56 -0700517
Saurav Das337c7a42015-06-02 15:12:06 -0700518 public Filter(PortCriterion p, EthCriterion e, VlanIdCriterion v,
519 Collection<IPCriterion> ips) {
520 this.eth = e;
521 this.port = p;
522 this.vlan = v;
523 this.ips = ips;
Saurav Dase3274c82015-05-24 17:21:56 -0700524 }
Saurav Dase3274c82015-05-24 17:21:56 -0700525
Saurav Das337c7a42015-06-02 15:12:06 -0700526 public PortNumber port() {
527 return port.port();
528 }
Saurav Dase3274c82015-05-24 17:21:56 -0700529
Saurav Das337c7a42015-06-02 15:12:06 -0700530 public VlanId vlanId() {
531 return vlan.vlanId();
532 }
Saurav Dase3274c82015-05-24 17:21:56 -0700533
Saurav Das337c7a42015-06-02 15:12:06 -0700534 public MacAddress mac() {
535 return eth.mac();
Saurav Dase3274c82015-05-24 17:21:56 -0700536 }
537 }
538
539 private class PicaGroup implements NextGroup {
Saurav Das337c7a42015-06-02 15:12:06 -0700540 TrafficTreatment nextActions;
Saurav Dase3274c82015-05-24 17:21:56 -0700541
Saurav Das337c7a42015-06-02 15:12:06 -0700542 public PicaGroup(TrafficTreatment next) {
543 this.nextActions = next;
Saurav Dase3274c82015-05-24 17:21:56 -0700544 }
545
546 @Override
547 public byte[] data() {
Saurav Das337c7a42015-06-02 15:12:06 -0700548 return appKryo.serialize(nextActions);
Saurav Dase3274c82015-05-24 17:21:56 -0700549 }
Saurav Dase3274c82015-05-24 17:21:56 -0700550 }
Saurav Das24431192016-03-07 19:13:00 -0800551
552 @Override
553 public List<String> getNextMappings(NextGroup nextGroup) {
554 // TODO Implementation deferred to vendor
555 return null;
556 }
Saurav Dase3274c82015-05-24 17:21:56 -0700557}