blob: 5b9fd04f0768cd6925a3c51200c145e5c2bb81f5 [file] [log] [blame]
Thomas Vachuska58de4162015-09-10 16:15:33 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Thomas Vachuska58de4162015-09-10 16:15:33 -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 */
Saurav Das558afec2015-05-31 17:12:48 -070016package org.onosproject.driver.pipeline;
17
Charles Chan5270ed02016-01-30 23:22:37 -080018import com.google.common.collect.ImmutableList;
Charles Chan5b9df8d2016-03-28 22:21:40 -070019import com.google.common.collect.ImmutableSet;
Saurav Das8a0732e2015-11-20 15:27:53 -080020import org.onlab.packet.Ethernet;
Flavio Castroe10fa242016-01-15 12:43:51 -080021import org.onlab.packet.IpPrefix;
Jonathan Hart855179c2016-04-26 07:40:04 -070022import org.onlab.packet.MacAddress;
Saurav Das2857f382015-11-03 14:39:27 -080023import org.onlab.packet.VlanId;
24import org.onosproject.core.ApplicationId;
Charles Chan425854b2016-04-11 15:32:12 -070025import org.onosproject.core.CoreService;
26import org.onosproject.net.DeviceId;
Saurav Das2857f382015-11-03 14:39:27 -080027import org.onosproject.net.Port;
28import org.onosproject.net.PortNumber;
Saurav Das8a0732e2015-11-20 15:27:53 -080029import org.onosproject.net.behaviour.NextGroup;
Charles Chan425854b2016-04-11 15:32:12 -070030import org.onosproject.net.behaviour.PipelinerContext;
31import org.onosproject.net.device.DeviceService;
Saurav Das558afec2015-05-31 17:12:48 -070032import 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;
Charles Chan425854b2016-04-11 15:32:12 -070038import org.onosproject.net.flow.FlowRuleService;
Saurav Das558afec2015-05-31 17:12:48 -070039import org.onosproject.net.flow.TrafficSelector;
40import org.onosproject.net.flow.TrafficTreatment;
Saurav Das4ce45962015-11-24 23:21:05 -080041import org.onosproject.net.flow.criteria.Criteria;
Saurav Das8a0732e2015-11-20 15:27:53 -080042import org.onosproject.net.flow.criteria.Criterion;
Saurav Das4ce45962015-11-24 23:21:05 -080043import org.onosproject.net.flow.criteria.EthCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080044import org.onosproject.net.flow.criteria.EthTypeCriterion;
45import org.onosproject.net.flow.criteria.IPCriterion;
Pier Ventree0ae7a32016-11-23 09:57:42 -080046import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
47import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080048import org.onosproject.net.flow.criteria.MplsBosCriterion;
49import org.onosproject.net.flow.criteria.MplsCriterion;
Saurav Das2857f382015-11-03 14:39:27 -080050import org.onosproject.net.flow.criteria.PortCriterion;
51import org.onosproject.net.flow.criteria.VlanIdCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080052import org.onosproject.net.flow.instructions.Instruction;
Saurav Das52025962016-01-28 22:30:01 -080053import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
54import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
55import org.onosproject.net.flowobjective.FilteringObjective;
Saurav Das8a0732e2015-11-20 15:27:53 -080056import org.onosproject.net.flowobjective.ForwardingObjective;
57import org.onosproject.net.flowobjective.ObjectiveError;
58import org.onosproject.net.group.Group;
59import org.onosproject.net.group.GroupKey;
Charles Chan425854b2016-04-11 15:32:12 -070060import org.onosproject.net.group.GroupService;
Charles Chanf57a8252016-06-29 19:12:37 -070061import org.onosproject.net.packet.PacketPriority;
Saurav Das558afec2015-05-31 17:12:48 -070062import org.slf4j.Logger;
63
Jonathan Hart855179c2016-04-26 07:40:04 -070064import java.util.ArrayList;
65import java.util.Collection;
66import java.util.Collections;
67import java.util.Deque;
68import java.util.List;
69
Pier Ventree0ae7a32016-11-23 09:57:42 -080070import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
Jonathan Hart855179c2016-04-26 07:40:04 -070071import static org.slf4j.LoggerFactory.getLogger;
72
Saurav Das558afec2015-05-31 17:12:48 -070073
74/**
Saurav Das822c4e22015-10-23 10:51:11 -070075 * Driver for software switch emulation of the OFDPA 2.0 pipeline.
Saurav Das52025962016-01-28 22:30:01 -080076 * The software switch is the CPqD OF 1.3 switch. Unfortunately the CPqD switch
77 * does not handle vlan tags and mpls labels simultaneously, which requires us
78 * to do some workarounds in the driver. This driver is meant for the use of
79 * the cpqd switch when MPLS is required. As a result this driver works only
80 * on incoming untagged packets.
Saurav Das558afec2015-05-31 17:12:48 -070081 */
Charles Chan361154b2016-03-24 10:23:39 -070082public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline {
Saurav Das558afec2015-05-31 17:12:48 -070083
84 private final Logger log = getLogger(getClass());
85
Charles Chan425854b2016-04-11 15:32:12 -070086 @Override
87 public void init(DeviceId deviceId, PipelinerContext context) {
88 this.deviceId = deviceId;
89
90 // Initialize OFDPA group handler
91 groupHandler = new CpqdOfdpa2GroupHandler();
92 groupHandler.init(deviceId, context);
93
94 serviceDirectory = context.directory();
95 coreService = serviceDirectory.get(CoreService.class);
96 flowRuleService = serviceDirectory.get(FlowRuleService.class);
97 groupService = serviceDirectory.get(GroupService.class);
98 flowObjectiveStore = context.store();
99 deviceService = serviceDirectory.get(DeviceService.class);
100
101 driverId = coreService.registerApplication(
102 "org.onosproject.driver.CpqdOfdpa2Pipeline");
103
104 initializePipeline();
105 }
106
Saurav Das4ce45962015-11-24 23:21:05 -0800107 /*
Saurav Das52025962016-01-28 22:30:01 -0800108 * CPQD emulation does not require special untagged packet handling, unlike
109 * the real ofdpa.
110 */
111 @Override
112 protected void processFilter(FilteringObjective filt,
113 boolean install, ApplicationId applicationId) {
114 // This driver only processes filtering criteria defined with switch
115 // ports as the key
116 PortCriterion portCriterion = null;
117 EthCriterion ethCriterion = null;
118 VlanIdCriterion vidCriterion = null;
119 Collection<IPCriterion> ips = new ArrayList<IPCriterion>();
120 if (!filt.key().equals(Criteria.dummy()) &&
121 filt.key().type() == Criterion.Type.IN_PORT) {
122 portCriterion = (PortCriterion) filt.key();
123 } else {
124 log.warn("No key defined in filtering objective from app: {}. Not"
125 + "processing filtering objective", applicationId);
126 fail(filt, ObjectiveError.UNKNOWN);
127 return;
128 }
129 // convert filtering conditions for switch-intfs into flowrules
130 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
131 for (Criterion criterion : filt.conditions()) {
Charles Chan5b9df8d2016-03-28 22:21:40 -0700132 if (criterion.type() == Criterion.Type.ETH_DST ||
133 criterion.type() == Criterion.Type.ETH_DST_MASKED) {
Saurav Das52025962016-01-28 22:30:01 -0800134 ethCriterion = (EthCriterion) criterion;
135 } else if (criterion.type() == Criterion.Type.VLAN_VID) {
136 vidCriterion = (VlanIdCriterion) criterion;
137 } else if (criterion.type() == Criterion.Type.IPV4_DST) {
138 ips.add((IPCriterion) criterion);
139 } else {
140 log.error("Unsupported filter {}", criterion);
141 fail(filt, ObjectiveError.UNSUPPORTED);
142 return;
143 }
144 }
145
146 VlanId assignedVlan = null;
147 // For VLAN cross-connect packets, use the configured VLAN
148 if (vidCriterion != null) {
149 if (vidCriterion.vlanId() != VlanId.NONE) {
150 assignedVlan = vidCriterion.vlanId();
151
152 // For untagged packets, assign a VLAN ID
153 } else {
154 if (filt.meta() == null) {
155 log.error("Missing metadata in filtering objective required " +
156 "for vlan assignment in dev {}", deviceId);
157 fail(filt, ObjectiveError.BADPARAMS);
158 return;
159 }
160 for (Instruction i : filt.meta().allInstructions()) {
161 if (i instanceof ModVlanIdInstruction) {
162 assignedVlan = ((ModVlanIdInstruction) i).vlanId();
163 }
164 }
165 if (assignedVlan == null) {
166 log.error("Driver requires an assigned vlan-id to tag incoming "
167 + "untagged packets. Not processing vlan filters on "
168 + "device {}", deviceId);
169 fail(filt, ObjectiveError.BADPARAMS);
170 return;
171 }
172 }
173 }
174
175 if (ethCriterion == null || ethCriterion.mac().equals(MacAddress.NONE)) {
176 log.debug("filtering objective missing dstMac, cannot program TMAC table");
177 } else {
178 for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion,
179 vidCriterion, assignedVlan,
180 applicationId)) {
181 log.debug("adding MAC filtering rules in TMAC table: {} for dev: {}",
182 tmacRule, deviceId);
183 ops = install ? ops.add(tmacRule) : ops.remove(tmacRule);
184 }
185 }
186
187 if (ethCriterion == null || vidCriterion == null) {
188 log.debug("filtering objective missing dstMac or VLAN, "
189 + "cannot program VLAN Table");
190 } else {
191 List<FlowRule> allRules = processVlanIdFilter(
192 portCriterion, vidCriterion, assignedVlan, applicationId);
193 for (FlowRule rule : allRules) {
194 log.debug("adding VLAN filtering rule in VLAN table: {} for dev: {}",
195 rule, deviceId);
196 ops = install ? ops.add(rule) : ops.remove(rule);
197 }
198 }
199
200 for (IPCriterion ipaddr : ips) {
201 // since we ignore port information for IP rules, and the same (gateway) IP
202 // can be configured on multiple ports, we make sure that we send
203 // only a single rule to the switch.
204 if (!sentIpFilters.contains(ipaddr)) {
205 sentIpFilters.add(ipaddr);
206 log.debug("adding IP filtering rules in ACL table {} for dev: {}",
207 ipaddr, deviceId);
208 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
209 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
210 selector.matchEthType(Ethernet.TYPE_IPV4);
211 selector.matchIPDst(ipaddr.ip());
212 treatment.setOutput(PortNumber.CONTROLLER);
213 FlowRule rule = DefaultFlowRule.builder()
214 .forDevice(deviceId)
215 .withSelector(selector.build())
216 .withTreatment(treatment.build())
217 .withPriority(HIGHEST_PRIORITY)
218 .fromApp(applicationId)
219 .makePermanent()
220 .forTable(ACL_TABLE).build();
221 ops = install ? ops.add(rule) : ops.remove(rule);
222 }
223 }
224
225 // apply filtering flow rules
226 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
227 @Override
228 public void onSuccess(FlowRuleOperations ops) {
229 log.info("Applied {} filtering rules in device {}",
230 ops.stages().get(0).size(), deviceId);
231 pass(filt);
232 }
233
234 @Override
235 public void onError(FlowRuleOperations ops) {
236 log.info("Failed to apply all filtering rules in dev {}", deviceId);
237 fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
238 }
239 }));
240
241 }
242
243 /*
Saurav Das1ce0a7b2016-10-21 14:06:29 -0700244 * Cpqd emulation does not require the non OF-standard rules for
245 * matching untagged packets that ofdpa uses.
Saurav Das4ce45962015-11-24 23:21:05 -0800246 *
247 * (non-Javadoc)
248 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processVlanIdFilter
249 */
Saurav Das558afec2015-05-31 17:12:48 -0700250 @Override
Saurav Das2857f382015-11-03 14:39:27 -0800251 protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion,
252 VlanIdCriterion vidCriterion,
253 VlanId assignedVlan,
254 ApplicationId applicationId) {
Charles Chan79769232016-07-05 16:34:39 -0700255 List<FlowRule> rules = new ArrayList<>();
Saurav Das2857f382015-11-03 14:39:27 -0800256 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
257 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
258 selector.matchVlanId(vidCriterion.vlanId());
Saurav Das4f980082015-11-05 13:39:15 -0800259 treatment.transition(TMAC_TABLE);
260
Saurav Das2857f382015-11-03 14:39:27 -0800261 if (vidCriterion.vlanId() == VlanId.NONE) {
262 // untagged packets are assigned vlans
263 treatment.pushVlan().setVlanId(assignedVlan);
Charles Chan79769232016-07-05 16:34:39 -0700264
265 // Emulating OFDPA behavior by popping off internal assigned VLAN
266 // before sending to controller
Pier Ventree0ae7a32016-11-23 09:57:42 -0800267 rules.add(buildArpPunt(assignedVlan, applicationId));
268 rules.add(buildIcmpV6Punt(assignedVlan, applicationId));
Saurav Das2857f382015-11-03 14:39:27 -0800269 }
Saurav Das2857f382015-11-03 14:39:27 -0800270
271 // ofdpa cannot match on ALL portnumber, so we need to use separate
272 // rules for each port.
273 List<PortNumber> portnums = new ArrayList<PortNumber>();
274 if (portCriterion.port() == PortNumber.ALL) {
275 for (Port port : deviceService.getPorts(deviceId)) {
276 if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
277 portnums.add(port.number());
278 }
279 }
280 } else {
281 portnums.add(portCriterion.port());
282 }
Saurav Das4f980082015-11-05 13:39:15 -0800283
Saurav Das2857f382015-11-03 14:39:27 -0800284 for (PortNumber pnum : portnums) {
Saurav Das4f980082015-11-05 13:39:15 -0800285 // create rest of flowrule
Saurav Das2857f382015-11-03 14:39:27 -0800286 selector.matchInPort(pnum);
287 FlowRule rule = DefaultFlowRule.builder()
288 .forDevice(deviceId)
289 .withSelector(selector.build())
290 .withTreatment(treatment.build())
291 .withPriority(DEFAULT_PRIORITY)
292 .fromApp(applicationId)
293 .makePermanent()
294 .forTable(VLAN_TABLE).build();
295 rules.add(rule);
296 }
Charles Chanf57a8252016-06-29 19:12:37 -0700297
Saurav Das2857f382015-11-03 14:39:27 -0800298 return rules;
299 }
300
Pier Ventree0ae7a32016-11-23 09:57:42 -0800301 /**
302 * Builds a punt to the controller rule for the arp protocol.
303 *
304 * @param assignedVlan the internal assigned vlan id
305 * @param applicationId the application id
306 * @return the punt flow rule for the arp
307 */
308 private FlowRule buildArpPunt(VlanId assignedVlan, ApplicationId applicationId) {
309 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
310 .matchEthType(Ethernet.TYPE_ARP)
311 .matchVlanId(assignedVlan);
312 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder()
313 .popVlan()
314 .punt();
315
316 return DefaultFlowRule.builder()
317 .forDevice(deviceId)
318 .withSelector(sbuilder.build())
319 .withTreatment(tbuilder.build())
320 .withPriority(PacketPriority.CONTROL.priorityValue() + 1)
321 .fromApp(applicationId)
322 .makePermanent()
323 .forTable(ACL_TABLE).build();
324 }
325
326 /**
327 * Builds a punt to the controller rule for the icmp v6 messages.
328 *
329 * @param assignedVlan the internal assigned vlan id
330 * @param applicationId the application id
331 * @return the punt flow rule for the icmp v6 messages
332 */
333 private FlowRule buildIcmpV6Punt(VlanId assignedVlan, ApplicationId applicationId) {
334 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
335 .matchVlanId(assignedVlan)
336 .matchEthType(Ethernet.TYPE_IPV6)
337 .matchIPProtocol(PROTOCOL_ICMP6);
338 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder()
339 .popVlan()
340 .punt();
341
342 return DefaultFlowRule.builder()
343 .forDevice(deviceId)
344 .withSelector(sbuilder.build())
345 .withTreatment(tbuilder.build())
346 .withPriority(PacketPriority.CONTROL.priorityValue() + 1)
347 .fromApp(applicationId)
348 .makePermanent()
349 .forTable(ACL_TABLE).build();
350 }
351
Saurav Das4ce45962015-11-24 23:21:05 -0800352 /*
353 * Cpqd emulation does not handle vlan tags and mpls labels correctly.
354 * Workaround requires popping off the VLAN tags in the TMAC table.
355 *
356 * (non-Javadoc)
357 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthDstFilter
358 */
Saurav Das8a0732e2015-11-20 15:27:53 -0800359 @Override
Saurav Das4ce45962015-11-24 23:21:05 -0800360 protected List<FlowRule> processEthDstFilter(PortCriterion portCriterion,
361 EthCriterion ethCriterion,
362 VlanIdCriterion vidCriterion,
363 VlanId assignedVlan,
364 ApplicationId applicationId) {
Charles Chan5270ed02016-01-30 23:22:37 -0800365 // Consider PortNumber.ANY as wildcard. Match ETH_DST only
366 if (portCriterion != null && portCriterion.port() == PortNumber.ANY) {
367 return processEthDstOnlyFilter(ethCriterion, applicationId);
368 }
369
Charles Chan5b9df8d2016-03-28 22:21:40 -0700370 // Multicast MAC
371 if (ethCriterion.mask() != null) {
372 return processMcastEthDstFilter(ethCriterion, applicationId);
373 }
374
Saurav Das4ce45962015-11-24 23:21:05 -0800375 //handling untagged packets via assigned VLAN
376 if (vidCriterion.vlanId() == VlanId.NONE) {
377 vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan);
378 }
379 // ofdpa cannot match on ALL portnumber, so we need to use separate
380 // rules for each port.
381 List<PortNumber> portnums = new ArrayList<PortNumber>();
382 if (portCriterion.port() == PortNumber.ALL) {
383 for (Port port : deviceService.getPorts(deviceId)) {
384 if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
385 portnums.add(port.number());
386 }
387 }
388 } else {
389 portnums.add(portCriterion.port());
390 }
391
392 List<FlowRule> rules = new ArrayList<FlowRule>();
393 for (PortNumber pnum : portnums) {
394 // for unicast IP packets
395 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
396 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
397 selector.matchInPort(pnum);
398 selector.matchVlanId(vidCriterion.vlanId());
399 selector.matchEthType(Ethernet.TYPE_IPV4);
400 selector.matchEthDst(ethCriterion.mac());
401 /*
402 * Note: CpqD switches do not handle MPLS-related operation properly
403 * for a packet with VLAN tag. We pop VLAN here as a workaround.
404 * Side effect: HostService learns redundant hosts with same MAC but
405 * different VLAN. No known side effect on the network reachability.
406 */
407 treatment.popVlan();
408 treatment.transition(UNICAST_ROUTING_TABLE);
409 FlowRule rule = DefaultFlowRule.builder()
410 .forDevice(deviceId)
411 .withSelector(selector.build())
412 .withTreatment(treatment.build())
413 .withPriority(DEFAULT_PRIORITY)
414 .fromApp(applicationId)
415 .makePermanent()
416 .forTable(TMAC_TABLE).build();
417 rules.add(rule);
418 //for MPLS packets
419 selector = DefaultTrafficSelector.builder();
420 treatment = DefaultTrafficTreatment.builder();
421 selector.matchInPort(pnum);
422 selector.matchVlanId(vidCriterion.vlanId());
423 selector.matchEthType(Ethernet.MPLS_UNICAST);
424 selector.matchEthDst(ethCriterion.mac());
425 // workaround here again
426 treatment.popVlan();
427 treatment.transition(MPLS_TABLE_0);
428 rule = DefaultFlowRule.builder()
429 .forDevice(deviceId)
430 .withSelector(selector.build())
431 .withTreatment(treatment.build())
432 .withPriority(DEFAULT_PRIORITY)
433 .fromApp(applicationId)
434 .makePermanent()
435 .forTable(TMAC_TABLE).build();
436 rules.add(rule);
Pier Ventree0ae7a32016-11-23 09:57:42 -0800437 /*
438 * TMAC rules for IPv6 packets
439 */
440 selector = DefaultTrafficSelector.builder();
441 treatment = DefaultTrafficTreatment.builder();
442 selector.matchInPort(pnum);
443 selector.matchVlanId(vidCriterion.vlanId());
444 selector.matchEthType(Ethernet.TYPE_IPV6);
445 selector.matchEthDst(ethCriterion.mac());
446 /*
447 * workaround here again, we are removing
448 * the vlan tag before to go through the
449 * rest of the pipeline
450 */
451 treatment.popVlan();
452 treatment.transition(UNICAST_ROUTING_TABLE);
453 rule = DefaultFlowRule.builder()
454 .forDevice(deviceId)
455 .withSelector(selector.build())
456 .withTreatment(treatment.build())
457 .withPriority(DEFAULT_PRIORITY)
458 .fromApp(applicationId)
459 .makePermanent()
460 .forTable(TMAC_TABLE).build();
461 rules.add(rule);
Saurav Das4ce45962015-11-24 23:21:05 -0800462 }
463 return rules;
464 }
465
Charles Chan5270ed02016-01-30 23:22:37 -0800466 @Override
467 protected List<FlowRule> processEthDstOnlyFilter(EthCriterion ethCriterion,
468 ApplicationId applicationId) {
469 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
470 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
471 selector.matchEthType(Ethernet.TYPE_IPV4);
472 selector.matchEthDst(ethCriterion.mac());
473 /*
474 * Note: CpqD switches do not handle MPLS-related operation properly
475 * for a packet with VLAN tag. We pop VLAN here as a workaround.
476 * Side effect: HostService learns redundant hosts with same MAC but
477 * different VLAN. No known side effect on the network reachability.
478 */
479 treatment.popVlan();
480 treatment.transition(UNICAST_ROUTING_TABLE);
481 FlowRule rule = DefaultFlowRule.builder()
482 .forDevice(deviceId)
483 .withSelector(selector.build())
484 .withTreatment(treatment.build())
485 .withPriority(DEFAULT_PRIORITY)
486 .fromApp(applicationId)
487 .makePermanent()
488 .forTable(TMAC_TABLE).build();
489 return ImmutableList.<FlowRule>builder().add(rule).build();
490 }
491
Saurav Das4ce45962015-11-24 23:21:05 -0800492 /*
493 * Cpqd emulation allows MPLS ecmp.
494 *
495 * (non-Javadoc)
496 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthTypeSpecific
497 */
498 @Override
499 protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
Saurav Das8a0732e2015-11-20 15:27:53 -0800500 TrafficSelector selector = fwd.selector();
501 EthTypeCriterion ethType =
502 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
503 if ((ethType == null) ||
504 (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) &&
Pier Ventree0ae7a32016-11-23 09:57:42 -0800505 (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST) &&
506 (ethType.ethType().toShort() != Ethernet.TYPE_IPV6)) {
Saurav Das4ce45962015-11-24 23:21:05 -0800507 log.warn("processSpecific: Unsupported forwarding objective criteria"
508 + "ethType:{} in dev:{}", ethType, deviceId);
Saurav Das8a0732e2015-11-20 15:27:53 -0800509 fail(fwd, ObjectiveError.UNSUPPORTED);
510 return Collections.emptySet();
511 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800512 boolean defaultRule = false;
Saurav Das8a0732e2015-11-20 15:27:53 -0800513 int forTableId = -1;
514 TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder();
Flavio Castroe10fa242016-01-15 12:43:51 -0800515 TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
516
Saurav Das8a0732e2015-11-20 15:27:53 -0800517 if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
Flavio Castroe10fa242016-01-15 12:43:51 -0800518 IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
Charles Chan5b9df8d2016-03-28 22:21:40 -0700519 if (ipv4Dst.isMulticast()) {
520 if (ipv4Dst.prefixLength() != 32) {
521 log.warn("Multicast specific forwarding objective can only be /32");
522 fail(fwd, ObjectiveError.BADPARAMS);
523 return ImmutableSet.of();
524 }
525 VlanId assignedVlan = readVlanFromSelector(fwd.meta());
526 if (assignedVlan == null) {
527 log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
528 fail(fwd, ObjectiveError.BADPARAMS);
529 return ImmutableSet.of();
530 }
531 filteredSelector.matchVlanId(assignedVlan);
532 filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
533 forTableId = MULTICAST_ROUTING_TABLE;
534 log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}"
535 + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
Flavio Castroe10fa242016-01-15 12:43:51 -0800536 } else {
Charles Chanf9e98652016-09-07 16:54:23 -0700537 if (ipv4Dst.prefixLength() == 0) {
538 // The entire IPV4_DST field is wildcarded intentionally
539 filteredSelector.matchEthType(Ethernet.TYPE_IPV4);
Charles Chan5b9df8d2016-03-28 22:21:40 -0700540 } else {
Charles Chanf9e98652016-09-07 16:54:23 -0700541 filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
Charles Chan5b9df8d2016-03-28 22:21:40 -0700542 }
543 forTableId = UNICAST_ROUTING_TABLE;
544 log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}"
545 + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
Flavio Castroe10fa242016-01-15 12:43:51 -0800546 }
Pier Ventree0ae7a32016-11-23 09:57:42 -0800547 } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
548 if (buildIpv6Selector(filteredSelector, fwd) < 0) {
549 return Collections.emptyList();
550 }
551 forTableId = UNICAST_ROUTING_TABLE;
Saurav Das8a0732e2015-11-20 15:27:53 -0800552 } else {
553 filteredSelector
554 .matchEthType(Ethernet.MPLS_UNICAST)
555 .matchMplsLabel(((MplsCriterion)
556 selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
557 MplsBosCriterion bos = (MplsBosCriterion) selector
558 .getCriterion(Criterion.Type.MPLS_BOS);
559 if (bos != null) {
560 filteredSelector.matchMplsBos(bos.mplsBos());
561 }
562 forTableId = MPLS_TABLE_1;
Saurav Das4ce45962015-11-24 23:21:05 -0800563 log.debug("processing MPLS specific forwarding objective {} -> next:{}"
564 + " in dev {}", fwd.id(), fwd.nextId(), deviceId);
Saurav Das8a0732e2015-11-20 15:27:53 -0800565 }
566
567 TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
568 if (fwd.treatment() != null) {
569 for (Instruction i : fwd.treatment().allInstructions()) {
Charles Chan7d10b162015-12-07 18:54:45 -0800570 /*
571 * NOTE: OF-DPA does not support immediate instruction in
572 * L3 unicast and MPLS table.
573 */
574 tb.deferred().add(i);
Saurav Das8a0732e2015-11-20 15:27:53 -0800575 }
576 }
577
578 if (fwd.nextId() != null) {
Saurav Das423fe2b2015-12-04 10:52:59 -0800579 NextGroup next = getGroupForNextObjective(fwd.nextId());
580 if (next != null) {
581 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
582 // we only need the top level group's key to point the flow to it
583 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
584 if (group == null) {
Saurav Das1ce0a7b2016-10-21 14:06:29 -0700585 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
586 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
Saurav Das423fe2b2015-12-04 10:52:59 -0800587 fail(fwd, ObjectiveError.GROUPMISSING);
588 return Collections.emptySet();
589 }
590 tb.deferred().group(group.id());
Saurav Das8a0732e2015-11-20 15:27:53 -0800591 }
Saurav Das8a0732e2015-11-20 15:27:53 -0800592 }
593 tb.transition(ACL_TABLE);
594 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
595 .fromApp(fwd.appId())
596 .withPriority(fwd.priority())
597 .forDevice(deviceId)
598 .withSelector(filteredSelector.build())
599 .withTreatment(tb.build())
600 .forTable(forTableId);
601
602 if (fwd.permanent()) {
603 ruleBuilder.makePermanent();
604 } else {
605 ruleBuilder.makeTemporary(fwd.timeout());
606 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800607 Collection<FlowRule> flowRuleCollection = new ArrayList<>();
608 flowRuleCollection.add(ruleBuilder.build());
609 if (defaultRule) {
Pier Ventree0ae7a32016-11-23 09:57:42 -0800610 flowRuleCollection.add(
611 defaultRoute(fwd, complementarySelector, forTableId, tb)
612 );
Flavio Castroe10fa242016-01-15 12:43:51 -0800613 log.debug("Default rule 0.0.0.0/0 is being installed two rules");
614 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800615 return flowRuleCollection;
Saurav Das8a0732e2015-11-20 15:27:53 -0800616 }
617
Charles Chan1e492d32016-01-30 23:22:37 -0800618 @Override
619 protected Collection<FlowRule> processEthDstSpecific(ForwardingObjective fwd) {
620 List<FlowRule> rules = new ArrayList<>();
621
622 // Build filtered selector
623 TrafficSelector selector = fwd.selector();
624 EthCriterion ethCriterion = (EthCriterion) selector
625 .getCriterion(Criterion.Type.ETH_DST);
626 VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) selector
627 .getCriterion(Criterion.Type.VLAN_VID);
628
629 if (vlanIdCriterion == null) {
630 log.warn("Forwarding objective for bridging requires vlan. Not "
631 + "installing fwd:{} in dev:{}", fwd.id(), deviceId);
632 fail(fwd, ObjectiveError.BADPARAMS);
633 return Collections.emptySet();
634 }
635
636 TrafficSelector.Builder filteredSelectorBuilder =
637 DefaultTrafficSelector.builder();
638 // Do not match MacAddress for subnet broadcast entry
639 if (!ethCriterion.mac().equals(MacAddress.NONE)) {
640 filteredSelectorBuilder.matchEthDst(ethCriterion.mac());
641 log.debug("processing L2 forwarding objective:{} -> next:{} in dev:{}",
642 fwd.id(), fwd.nextId(), deviceId);
643 } else {
644 log.debug("processing L2 Broadcast forwarding objective:{} -> next:{} "
645 + "in dev:{} for vlan:{}",
646 fwd.id(), fwd.nextId(), deviceId, vlanIdCriterion.vlanId());
647 }
648 filteredSelectorBuilder.matchVlanId(vlanIdCriterion.vlanId());
649 TrafficSelector filteredSelector = filteredSelectorBuilder.build();
650
651 if (fwd.treatment() != null) {
652 log.warn("Ignoring traffic treatment in fwd rule {} meant for L2 table"
653 + "for dev:{}. Expecting only nextId", fwd.id(), deviceId);
654 }
655
656 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
657 if (fwd.nextId() != null) {
658 NextGroup next = getGroupForNextObjective(fwd.nextId());
659 if (next != null) {
660 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
661 // we only need the top level group's key to point the flow to it
662 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
663 if (group != null) {
664 treatmentBuilder.deferred().group(group.id());
665 } else {
666 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
667 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
668 fail(fwd, ObjectiveError.GROUPMISSING);
669 return Collections.emptySet();
670 }
671 }
672 }
673 treatmentBuilder.immediate().transition(ACL_TABLE);
674 TrafficTreatment filteredTreatment = treatmentBuilder.build();
675
676 // Build bridging table entries
677 FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();
678 flowRuleBuilder.fromApp(fwd.appId())
679 .withPriority(fwd.priority())
680 .forDevice(deviceId)
681 .withSelector(filteredSelector)
682 .withTreatment(filteredTreatment)
683 .forTable(BRIDGING_TABLE);
684 if (fwd.permanent()) {
685 flowRuleBuilder.makePermanent();
686 } else {
687 flowRuleBuilder.makeTemporary(fwd.timeout());
688 }
689 rules.add(flowRuleBuilder.build());
690 return rules;
691 }
692
Saurav Das52025962016-01-28 22:30:01 -0800693 /*
694 * In the OF-DPA 2.0 pipeline, versatile forwarding objectives go to the
695 * ACL table. Because we pop off vlan tags in TMAC table,
696 * we need to avoid matching on vlans in the ACL table.
697 */
698 @Override
699 protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
700 log.info("Processing versatile forwarding objective");
701
702 EthTypeCriterion ethType =
703 (EthTypeCriterion) fwd.selector().getCriterion(Criterion.Type.ETH_TYPE);
704 if (ethType == null) {
705 log.error("Versatile forwarding objective must include ethType");
706 fail(fwd, ObjectiveError.BADPARAMS);
707 return Collections.emptySet();
708 }
709 if (fwd.nextId() == null && fwd.treatment() == null) {
710 log.error("Forwarding objective {} from {} must contain "
711 + "nextId or Treatment", fwd.selector(), fwd.appId());
712 return Collections.emptySet();
713 }
714
715 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
716 fwd.selector().criteria().forEach(criterion -> {
717 if (criterion instanceof VlanIdCriterion) {
718 // avoid matching on vlans
719 return;
Pier Ventree0ae7a32016-11-23 09:57:42 -0800720 } else if (criterion instanceof Icmpv6TypeCriterion ||
721 criterion instanceof Icmpv6CodeCriterion) {
722 /*
723 * We silenty discard these criterions, our current
724 * OFDPA platform does not support these matches on
725 * the ACL table.
726 */
727 log.warn("ICMPv6 Type and ICMPv6 Code are not supported");
Saurav Das52025962016-01-28 22:30:01 -0800728 } else {
729 sbuilder.add(criterion);
730 }
731 });
732
733 // XXX driver does not currently do type checking as per Tables 65-67 in
734 // OFDPA 2.0 spec. The only allowed treatment is a punt to the controller.
735 TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
736 if (fwd.treatment() != null) {
737 for (Instruction ins : fwd.treatment().allInstructions()) {
738 if (ins instanceof OutputInstruction) {
739 OutputInstruction o = (OutputInstruction) ins;
740 if (o.port() == PortNumber.CONTROLLER) {
741 ttBuilder.add(o);
742 } else {
743 log.warn("Only allowed treatments in versatile forwarding "
744 + "objectives are punts to the controller");
745 }
746 } else {
747 log.warn("Cannot process instruction in versatile fwd {}", ins);
748 }
749 }
Charles Chan2df0e8a2017-01-09 11:45:08 -0800750 if (fwd.treatment().clearedDeferred()) {
751 ttBuilder.wipeDeferred();
752 }
Saurav Das52025962016-01-28 22:30:01 -0800753 }
754 if (fwd.nextId() != null) {
755 // overide case
756 NextGroup next = getGroupForNextObjective(fwd.nextId());
757 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
758 // we only need the top level group's key to point the flow to it
759 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
760 if (group == null) {
761 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
762 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
763 fail(fwd, ObjectiveError.GROUPMISSING);
764 return Collections.emptySet();
765 }
766 ttBuilder.deferred().group(group.id());
767 }
768
769 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
770 .fromApp(fwd.appId())
771 .withPriority(fwd.priority())
772 .forDevice(deviceId)
773 .withSelector(sbuilder.build())
774 .withTreatment(ttBuilder.build())
775 .makePermanent()
776 .forTable(ACL_TABLE);
777 return Collections.singletonList(ruleBuilder.build());
778 }
779
780 /*
781 * Cpqd emulation requires table-miss-entries in forwarding tables.
782 * Real OFDPA does not require these rules as they are put in by default.
783 *
784 * (non-Javadoc)
785 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#initializePipeline()
786 */
Saurav Das2857f382015-11-03 14:39:27 -0800787 @Override
Saurav Das558afec2015-05-31 17:12:48 -0700788 protected void initializePipeline() {
789 processPortTable();
Saurav Das2857f382015-11-03 14:39:27 -0800790 // vlan table processing not required, as default is to drop packets
791 // which can be accomplished without a table-miss-entry.
Saurav Das558afec2015-05-31 17:12:48 -0700792 processTmacTable();
793 processIpTable();
Jonathan Hart855179c2016-04-26 07:40:04 -0700794 processMulticastIpTable();
Saurav Das2857f382015-11-03 14:39:27 -0800795 processMplsTable();
Saurav Das558afec2015-05-31 17:12:48 -0700796 processBridgingTable();
Saurav Das337c7a42015-06-02 15:12:06 -0700797 processAclTable();
Saurav Das558afec2015-05-31 17:12:48 -0700798 }
799
Saurav Das558afec2015-05-31 17:12:48 -0700800 protected void processPortTable() {
801 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
802 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
803 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
804 treatment.transition(VLAN_TABLE);
805 FlowRule tmisse = DefaultFlowRule.builder()
806 .forDevice(deviceId)
807 .withSelector(selector.build())
808 .withTreatment(treatment.build())
809 .withPriority(LOWEST_PRIORITY)
810 .fromApp(driverId)
811 .makePermanent()
812 .forTable(PORT_TABLE).build();
813 ops = ops.add(tmisse);
814
815 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
816 @Override
817 public void onSuccess(FlowRuleOperations ops) {
818 log.info("Initialized port table");
819 }
820
821 @Override
822 public void onError(FlowRuleOperations ops) {
823 log.info("Failed to initialize port table");
824 }
825 }));
826 }
827
Saurav Das558afec2015-05-31 17:12:48 -0700828 protected void processTmacTable() {
829 //table miss entry
830 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
831 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
832 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das558afec2015-05-31 17:12:48 -0700833 treatment.transition(BRIDGING_TABLE);
834 FlowRule rule = DefaultFlowRule.builder()
835 .forDevice(deviceId)
836 .withSelector(selector.build())
837 .withTreatment(treatment.build())
838 .withPriority(LOWEST_PRIORITY)
839 .fromApp(driverId)
840 .makePermanent()
841 .forTable(TMAC_TABLE).build();
842 ops = ops.add(rule);
843 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
844 @Override
845 public void onSuccess(FlowRuleOperations ops) {
846 log.info("Initialized tmac table");
847 }
848
849 @Override
850 public void onError(FlowRuleOperations ops) {
851 log.info("Failed to initialize tmac table");
852 }
853 }));
854 }
855
Saurav Das558afec2015-05-31 17:12:48 -0700856 protected void processIpTable() {
857 //table miss entry
858 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
859 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
860 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das558afec2015-05-31 17:12:48 -0700861 treatment.transition(ACL_TABLE);
862 FlowRule rule = DefaultFlowRule.builder()
863 .forDevice(deviceId)
864 .withSelector(selector.build())
865 .withTreatment(treatment.build())
866 .withPriority(LOWEST_PRIORITY)
867 .fromApp(driverId)
868 .makePermanent()
869 .forTable(UNICAST_ROUTING_TABLE).build();
870 ops = ops.add(rule);
871 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
872 @Override
873 public void onSuccess(FlowRuleOperations ops) {
874 log.info("Initialized IP table");
875 }
876
877 @Override
878 public void onError(FlowRuleOperations ops) {
879 log.info("Failed to initialize unicast IP table");
880 }
881 }));
882 }
883
Jonathan Hart855179c2016-04-26 07:40:04 -0700884 protected void processMulticastIpTable() {
885 //table miss entry
886 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
887 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
888 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
889 treatment.transition(ACL_TABLE);
890 FlowRule rule = DefaultFlowRule.builder()
891 .forDevice(deviceId)
892 .withSelector(selector.build())
893 .withTreatment(treatment.build())
894 .withPriority(LOWEST_PRIORITY)
895 .fromApp(driverId)
896 .makePermanent()
897 .forTable(MULTICAST_ROUTING_TABLE).build();
898 ops = ops.add(rule);
899 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
900 @Override
901 public void onSuccess(FlowRuleOperations ops) {
902 log.info("Initialized multicast IP table");
903 }
904
905 @Override
906 public void onError(FlowRuleOperations ops) {
907 log.info("Failed to initialize multicast IP table");
908 }
909 }));
910 }
911
Saurav Das2857f382015-11-03 14:39:27 -0800912 protected void processMplsTable() {
913 //table miss entry
914 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
915 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
916 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
917 selector = DefaultTrafficSelector.builder();
918 treatment = DefaultTrafficTreatment.builder();
919 treatment.transition(MPLS_TABLE_1);
920 FlowRule rule = DefaultFlowRule.builder()
921 .forDevice(deviceId)
922 .withSelector(selector.build())
923 .withTreatment(treatment.build())
924 .withPriority(LOWEST_PRIORITY)
925 .fromApp(driverId)
926 .makePermanent()
927 .forTable(MPLS_TABLE_0).build();
928 ops = ops.add(rule);
929
930 treatment.transition(ACL_TABLE);
931 rule = DefaultFlowRule.builder()
932 .forDevice(deviceId)
933 .withSelector(selector.build())
934 .withTreatment(treatment.build())
935 .withPriority(LOWEST_PRIORITY)
936 .fromApp(driverId)
937 .makePermanent()
938 .forTable(MPLS_TABLE_1).build();
939 ops = ops.add(rule);
940
941 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
942 @Override
943 public void onSuccess(FlowRuleOperations ops) {
944 log.info("Initialized MPLS tables");
945 }
946
947 @Override
948 public void onError(FlowRuleOperations ops) {
949 log.info("Failed to initialize MPLS tables");
950 }
951 }));
952 }
953
Saurav Das558afec2015-05-31 17:12:48 -0700954 private void processBridgingTable() {
955 //table miss entry
956 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
957 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
958 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das558afec2015-05-31 17:12:48 -0700959 treatment.transition(ACL_TABLE);
960 FlowRule rule = DefaultFlowRule.builder()
961 .forDevice(deviceId)
962 .withSelector(selector.build())
963 .withTreatment(treatment.build())
964 .withPriority(LOWEST_PRIORITY)
965 .fromApp(driverId)
966 .makePermanent()
967 .forTable(BRIDGING_TABLE).build();
968 ops = ops.add(rule);
969 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
970 @Override
971 public void onSuccess(FlowRuleOperations ops) {
972 log.info("Initialized Bridging table");
973 }
974
975 @Override
976 public void onError(FlowRuleOperations ops) {
977 log.info("Failed to initialize Bridging table");
978 }
979 }));
Saurav Das337c7a42015-06-02 15:12:06 -0700980 }
Saurav Das558afec2015-05-31 17:12:48 -0700981
Saurav Dasa07f2032015-10-19 14:37:36 -0700982 protected void processAclTable() {
Saurav Das337c7a42015-06-02 15:12:06 -0700983 //table miss entry - catch all to executed action-set
984 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
985 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
986 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das337c7a42015-06-02 15:12:06 -0700987 FlowRule rule = DefaultFlowRule.builder()
988 .forDevice(deviceId)
989 .withSelector(selector.build())
990 .withTreatment(treatment.build())
991 .withPriority(LOWEST_PRIORITY)
992 .fromApp(driverId)
993 .makePermanent()
994 .forTable(ACL_TABLE).build();
995 ops = ops.add(rule);
996 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
997 @Override
998 public void onSuccess(FlowRuleOperations ops) {
999 log.info("Initialized Acl table");
1000 }
1001
1002 @Override
1003 public void onError(FlowRuleOperations ops) {
1004 log.info("Failed to initialize Acl table");
1005 }
1006 }));
Saurav Das558afec2015-05-31 17:12:48 -07001007 }
1008
1009}