blob: ecc3dbf9e1012b6e50e7ee792a40086226d462da [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;
25import org.onosproject.net.Port;
26import org.onosproject.net.PortNumber;
Saurav Das8a0732e2015-11-20 15:27:53 -080027import org.onosproject.net.behaviour.NextGroup;
Charles Chan425854b2016-04-11 15:32:12 -070028import org.onosproject.net.behaviour.PipelinerContext;
Saurav Das558afec2015-05-31 17:12:48 -070029import org.onosproject.net.flow.DefaultFlowRule;
30import org.onosproject.net.flow.DefaultTrafficSelector;
31import org.onosproject.net.flow.DefaultTrafficTreatment;
32import org.onosproject.net.flow.FlowRule;
33import org.onosproject.net.flow.FlowRuleOperations;
34import org.onosproject.net.flow.FlowRuleOperationsContext;
35import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
Saurav Das4ce45962015-11-24 23:21:05 -080037import org.onosproject.net.flow.criteria.Criteria;
Saurav Das8a0732e2015-11-20 15:27:53 -080038import org.onosproject.net.flow.criteria.Criterion;
Saurav Das4ce45962015-11-24 23:21:05 -080039import org.onosproject.net.flow.criteria.EthCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080040import org.onosproject.net.flow.criteria.EthTypeCriterion;
41import org.onosproject.net.flow.criteria.IPCriterion;
Pier Ventree0ae7a32016-11-23 09:57:42 -080042import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
43import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080044import org.onosproject.net.flow.criteria.MplsBosCriterion;
45import org.onosproject.net.flow.criteria.MplsCriterion;
Saurav Das2857f382015-11-03 14:39:27 -080046import org.onosproject.net.flow.criteria.PortCriterion;
47import org.onosproject.net.flow.criteria.VlanIdCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080048import org.onosproject.net.flow.instructions.Instruction;
Saurav Das52025962016-01-28 22:30:01 -080049import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
Charles Chan40132b32017-01-22 00:19:37 -080050import org.onosproject.net.flow.instructions.L3ModificationInstruction;
Saurav Das52025962016-01-28 22:30:01 -080051import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
52import org.onosproject.net.flowobjective.FilteringObjective;
Saurav Das8a0732e2015-11-20 15:27:53 -080053import org.onosproject.net.flowobjective.ForwardingObjective;
54import org.onosproject.net.flowobjective.ObjectiveError;
55import org.onosproject.net.group.Group;
56import org.onosproject.net.group.GroupKey;
Charles Chanf57a8252016-06-29 19:12:37 -070057import org.onosproject.net.packet.PacketPriority;
Saurav Das558afec2015-05-31 17:12:48 -070058import org.slf4j.Logger;
59
Jonathan Hart855179c2016-04-26 07:40:04 -070060import java.util.ArrayList;
61import java.util.Collection;
62import java.util.Collections;
63import java.util.Deque;
64import java.util.List;
65
Pier Ventree0ae7a32016-11-23 09:57:42 -080066import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
Jonathan Hart855179c2016-04-26 07:40:04 -070067import static org.slf4j.LoggerFactory.getLogger;
68
Saurav Das558afec2015-05-31 17:12:48 -070069
70/**
Charles Chan40132b32017-01-22 00:19:37 -080071 * Driver for software switch emulation of the OFDPA pipeline.
Saurav Das52025962016-01-28 22:30:01 -080072 * The software switch is the CPqD OF 1.3 switch. Unfortunately the CPqD switch
73 * does not handle vlan tags and mpls labels simultaneously, which requires us
74 * to do some workarounds in the driver. This driver is meant for the use of
75 * the cpqd switch when MPLS is required. As a result this driver works only
76 * on incoming untagged packets.
Saurav Das558afec2015-05-31 17:12:48 -070077 */
Charles Chan361154b2016-03-24 10:23:39 -070078public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline {
Saurav Das558afec2015-05-31 17:12:48 -070079
80 private final Logger log = getLogger(getClass());
81
Charles Chan40132b32017-01-22 00:19:37 -080082 /**
83 * Determines whether this pipeline support copy ttl instructions or not.
84 *
85 * @return true if copy ttl instructions are supported
86 */
87 protected boolean supportCopyTtl() {
88 return true;
89 }
90
Charles Chan425854b2016-04-11 15:32:12 -070091 @Override
Charles Chan40132b32017-01-22 00:19:37 -080092 protected void initDriverId() {
Charles Chan425854b2016-04-11 15:32:12 -070093 driverId = coreService.registerApplication(
94 "org.onosproject.driver.CpqdOfdpa2Pipeline");
Charles Chan40132b32017-01-22 00:19:37 -080095 }
Charles Chan425854b2016-04-11 15:32:12 -070096
Charles Chan40132b32017-01-22 00:19:37 -080097 @Override
98 protected void initGroupHander(PipelinerContext context) {
99 groupHandler = new CpqdOfdpa2GroupHandler();
100 groupHandler.init(deviceId, context);
Charles Chan425854b2016-04-11 15:32:12 -0700101 }
102
Saurav Das4ce45962015-11-24 23:21:05 -0800103 /*
Saurav Das52025962016-01-28 22:30:01 -0800104 * CPQD emulation does not require special untagged packet handling, unlike
105 * the real ofdpa.
106 */
107 @Override
108 protected void processFilter(FilteringObjective filt,
109 boolean install, ApplicationId applicationId) {
110 // This driver only processes filtering criteria defined with switch
111 // ports as the key
112 PortCriterion portCriterion = null;
113 EthCriterion ethCriterion = null;
114 VlanIdCriterion vidCriterion = null;
115 Collection<IPCriterion> ips = new ArrayList<IPCriterion>();
116 if (!filt.key().equals(Criteria.dummy()) &&
117 filt.key().type() == Criterion.Type.IN_PORT) {
118 portCriterion = (PortCriterion) filt.key();
119 } else {
120 log.warn("No key defined in filtering objective from app: {}. Not"
121 + "processing filtering objective", applicationId);
122 fail(filt, ObjectiveError.UNKNOWN);
123 return;
124 }
125 // convert filtering conditions for switch-intfs into flowrules
126 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
127 for (Criterion criterion : filt.conditions()) {
Charles Chan5b9df8d2016-03-28 22:21:40 -0700128 if (criterion.type() == Criterion.Type.ETH_DST ||
129 criterion.type() == Criterion.Type.ETH_DST_MASKED) {
Saurav Das52025962016-01-28 22:30:01 -0800130 ethCriterion = (EthCriterion) criterion;
131 } else if (criterion.type() == Criterion.Type.VLAN_VID) {
132 vidCriterion = (VlanIdCriterion) criterion;
133 } else if (criterion.type() == Criterion.Type.IPV4_DST) {
134 ips.add((IPCriterion) criterion);
135 } else {
136 log.error("Unsupported filter {}", criterion);
137 fail(filt, ObjectiveError.UNSUPPORTED);
138 return;
139 }
140 }
141
142 VlanId assignedVlan = null;
143 // For VLAN cross-connect packets, use the configured VLAN
144 if (vidCriterion != null) {
145 if (vidCriterion.vlanId() != VlanId.NONE) {
146 assignedVlan = vidCriterion.vlanId();
147
148 // For untagged packets, assign a VLAN ID
149 } else {
150 if (filt.meta() == null) {
151 log.error("Missing metadata in filtering objective required " +
152 "for vlan assignment in dev {}", deviceId);
153 fail(filt, ObjectiveError.BADPARAMS);
154 return;
155 }
156 for (Instruction i : filt.meta().allInstructions()) {
157 if (i instanceof ModVlanIdInstruction) {
158 assignedVlan = ((ModVlanIdInstruction) i).vlanId();
159 }
160 }
161 if (assignedVlan == null) {
162 log.error("Driver requires an assigned vlan-id to tag incoming "
163 + "untagged packets. Not processing vlan filters on "
164 + "device {}", deviceId);
165 fail(filt, ObjectiveError.BADPARAMS);
166 return;
167 }
168 }
169 }
170
171 if (ethCriterion == null || ethCriterion.mac().equals(MacAddress.NONE)) {
172 log.debug("filtering objective missing dstMac, cannot program TMAC table");
173 } else {
174 for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion,
175 vidCriterion, assignedVlan,
176 applicationId)) {
177 log.debug("adding MAC filtering rules in TMAC table: {} for dev: {}",
178 tmacRule, deviceId);
179 ops = install ? ops.add(tmacRule) : ops.remove(tmacRule);
180 }
181 }
182
183 if (ethCriterion == null || vidCriterion == null) {
184 log.debug("filtering objective missing dstMac or VLAN, "
185 + "cannot program VLAN Table");
186 } else {
187 List<FlowRule> allRules = processVlanIdFilter(
188 portCriterion, vidCriterion, assignedVlan, applicationId);
189 for (FlowRule rule : allRules) {
190 log.debug("adding VLAN filtering rule in VLAN table: {} for dev: {}",
191 rule, deviceId);
192 ops = install ? ops.add(rule) : ops.remove(rule);
193 }
194 }
195
196 for (IPCriterion ipaddr : ips) {
197 // since we ignore port information for IP rules, and the same (gateway) IP
198 // can be configured on multiple ports, we make sure that we send
199 // only a single rule to the switch.
200 if (!sentIpFilters.contains(ipaddr)) {
201 sentIpFilters.add(ipaddr);
202 log.debug("adding IP filtering rules in ACL table {} for dev: {}",
203 ipaddr, deviceId);
204 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
205 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
206 selector.matchEthType(Ethernet.TYPE_IPV4);
207 selector.matchIPDst(ipaddr.ip());
208 treatment.setOutput(PortNumber.CONTROLLER);
209 FlowRule rule = DefaultFlowRule.builder()
210 .forDevice(deviceId)
211 .withSelector(selector.build())
212 .withTreatment(treatment.build())
213 .withPriority(HIGHEST_PRIORITY)
214 .fromApp(applicationId)
215 .makePermanent()
216 .forTable(ACL_TABLE).build();
217 ops = install ? ops.add(rule) : ops.remove(rule);
218 }
219 }
220
221 // apply filtering flow rules
222 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
223 @Override
224 public void onSuccess(FlowRuleOperations ops) {
225 log.info("Applied {} filtering rules in device {}",
226 ops.stages().get(0).size(), deviceId);
227 pass(filt);
228 }
229
230 @Override
231 public void onError(FlowRuleOperations ops) {
232 log.info("Failed to apply all filtering rules in dev {}", deviceId);
233 fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
234 }
235 }));
236
237 }
238
239 /*
Saurav Das1ce0a7b2016-10-21 14:06:29 -0700240 * Cpqd emulation does not require the non OF-standard rules for
241 * matching untagged packets that ofdpa uses.
Saurav Das4ce45962015-11-24 23:21:05 -0800242 *
243 * (non-Javadoc)
244 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processVlanIdFilter
245 */
Saurav Das558afec2015-05-31 17:12:48 -0700246 @Override
Saurav Das2857f382015-11-03 14:39:27 -0800247 protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion,
248 VlanIdCriterion vidCriterion,
249 VlanId assignedVlan,
250 ApplicationId applicationId) {
Charles Chan79769232016-07-05 16:34:39 -0700251 List<FlowRule> rules = new ArrayList<>();
Saurav Das2857f382015-11-03 14:39:27 -0800252 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
253 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
254 selector.matchVlanId(vidCriterion.vlanId());
Saurav Das4f980082015-11-05 13:39:15 -0800255 treatment.transition(TMAC_TABLE);
256
Saurav Das2857f382015-11-03 14:39:27 -0800257 if (vidCriterion.vlanId() == VlanId.NONE) {
258 // untagged packets are assigned vlans
259 treatment.pushVlan().setVlanId(assignedVlan);
Charles Chan79769232016-07-05 16:34:39 -0700260
261 // Emulating OFDPA behavior by popping off internal assigned VLAN
262 // before sending to controller
Pier Ventree0ae7a32016-11-23 09:57:42 -0800263 rules.add(buildArpPunt(assignedVlan, applicationId));
264 rules.add(buildIcmpV6Punt(assignedVlan, applicationId));
Saurav Das2857f382015-11-03 14:39:27 -0800265 }
Saurav Das2857f382015-11-03 14:39:27 -0800266
267 // ofdpa cannot match on ALL portnumber, so we need to use separate
268 // rules for each port.
269 List<PortNumber> portnums = new ArrayList<PortNumber>();
270 if (portCriterion.port() == PortNumber.ALL) {
271 for (Port port : deviceService.getPorts(deviceId)) {
272 if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
273 portnums.add(port.number());
274 }
275 }
276 } else {
277 portnums.add(portCriterion.port());
278 }
Saurav Das4f980082015-11-05 13:39:15 -0800279
Saurav Das2857f382015-11-03 14:39:27 -0800280 for (PortNumber pnum : portnums) {
Saurav Das4f980082015-11-05 13:39:15 -0800281 // create rest of flowrule
Saurav Das2857f382015-11-03 14:39:27 -0800282 selector.matchInPort(pnum);
283 FlowRule rule = DefaultFlowRule.builder()
284 .forDevice(deviceId)
285 .withSelector(selector.build())
286 .withTreatment(treatment.build())
287 .withPriority(DEFAULT_PRIORITY)
288 .fromApp(applicationId)
289 .makePermanent()
290 .forTable(VLAN_TABLE).build();
291 rules.add(rule);
292 }
Charles Chanf57a8252016-06-29 19:12:37 -0700293
Saurav Das2857f382015-11-03 14:39:27 -0800294 return rules;
295 }
296
Pier Ventree0ae7a32016-11-23 09:57:42 -0800297 /**
298 * Builds a punt to the controller rule for the arp protocol.
299 *
300 * @param assignedVlan the internal assigned vlan id
301 * @param applicationId the application id
302 * @return the punt flow rule for the arp
303 */
304 private FlowRule buildArpPunt(VlanId assignedVlan, ApplicationId applicationId) {
305 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
306 .matchEthType(Ethernet.TYPE_ARP)
307 .matchVlanId(assignedVlan);
308 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder()
309 .popVlan()
310 .punt();
311
312 return DefaultFlowRule.builder()
313 .forDevice(deviceId)
314 .withSelector(sbuilder.build())
315 .withTreatment(tbuilder.build())
316 .withPriority(PacketPriority.CONTROL.priorityValue() + 1)
317 .fromApp(applicationId)
318 .makePermanent()
319 .forTable(ACL_TABLE).build();
320 }
321
322 /**
323 * Builds a punt to the controller rule for the icmp v6 messages.
324 *
325 * @param assignedVlan the internal assigned vlan id
326 * @param applicationId the application id
327 * @return the punt flow rule for the icmp v6 messages
328 */
329 private FlowRule buildIcmpV6Punt(VlanId assignedVlan, ApplicationId applicationId) {
330 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
331 .matchVlanId(assignedVlan)
332 .matchEthType(Ethernet.TYPE_IPV6)
333 .matchIPProtocol(PROTOCOL_ICMP6);
334 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder()
335 .popVlan()
336 .punt();
337
338 return DefaultFlowRule.builder()
339 .forDevice(deviceId)
340 .withSelector(sbuilder.build())
341 .withTreatment(tbuilder.build())
342 .withPriority(PacketPriority.CONTROL.priorityValue() + 1)
343 .fromApp(applicationId)
344 .makePermanent()
345 .forTable(ACL_TABLE).build();
346 }
347
Saurav Das4ce45962015-11-24 23:21:05 -0800348 /*
349 * Cpqd emulation does not handle vlan tags and mpls labels correctly.
350 * Workaround requires popping off the VLAN tags in the TMAC table.
351 *
352 * (non-Javadoc)
353 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthDstFilter
354 */
Saurav Das8a0732e2015-11-20 15:27:53 -0800355 @Override
Saurav Das4ce45962015-11-24 23:21:05 -0800356 protected List<FlowRule> processEthDstFilter(PortCriterion portCriterion,
357 EthCriterion ethCriterion,
358 VlanIdCriterion vidCriterion,
359 VlanId assignedVlan,
360 ApplicationId applicationId) {
Charles Chan5270ed02016-01-30 23:22:37 -0800361 // Consider PortNumber.ANY as wildcard. Match ETH_DST only
362 if (portCriterion != null && portCriterion.port() == PortNumber.ANY) {
363 return processEthDstOnlyFilter(ethCriterion, applicationId);
364 }
365
Charles Chan5b9df8d2016-03-28 22:21:40 -0700366 // Multicast MAC
367 if (ethCriterion.mask() != null) {
368 return processMcastEthDstFilter(ethCriterion, applicationId);
369 }
370
Saurav Das4ce45962015-11-24 23:21:05 -0800371 //handling untagged packets via assigned VLAN
372 if (vidCriterion.vlanId() == VlanId.NONE) {
373 vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan);
374 }
375 // ofdpa cannot match on ALL portnumber, so we need to use separate
376 // rules for each port.
377 List<PortNumber> portnums = new ArrayList<PortNumber>();
378 if (portCriterion.port() == PortNumber.ALL) {
379 for (Port port : deviceService.getPorts(deviceId)) {
380 if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
381 portnums.add(port.number());
382 }
383 }
384 } else {
385 portnums.add(portCriterion.port());
386 }
387
388 List<FlowRule> rules = new ArrayList<FlowRule>();
389 for (PortNumber pnum : portnums) {
390 // for unicast IP packets
391 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
392 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
393 selector.matchInPort(pnum);
394 selector.matchVlanId(vidCriterion.vlanId());
395 selector.matchEthType(Ethernet.TYPE_IPV4);
396 selector.matchEthDst(ethCriterion.mac());
397 /*
398 * Note: CpqD switches do not handle MPLS-related operation properly
399 * for a packet with VLAN tag. We pop VLAN here as a workaround.
400 * Side effect: HostService learns redundant hosts with same MAC but
401 * different VLAN. No known side effect on the network reachability.
402 */
403 treatment.popVlan();
404 treatment.transition(UNICAST_ROUTING_TABLE);
405 FlowRule rule = DefaultFlowRule.builder()
406 .forDevice(deviceId)
407 .withSelector(selector.build())
408 .withTreatment(treatment.build())
409 .withPriority(DEFAULT_PRIORITY)
410 .fromApp(applicationId)
411 .makePermanent()
412 .forTable(TMAC_TABLE).build();
413 rules.add(rule);
414 //for MPLS packets
415 selector = DefaultTrafficSelector.builder();
416 treatment = DefaultTrafficTreatment.builder();
417 selector.matchInPort(pnum);
418 selector.matchVlanId(vidCriterion.vlanId());
419 selector.matchEthType(Ethernet.MPLS_UNICAST);
420 selector.matchEthDst(ethCriterion.mac());
421 // workaround here again
422 treatment.popVlan();
423 treatment.transition(MPLS_TABLE_0);
424 rule = DefaultFlowRule.builder()
425 .forDevice(deviceId)
426 .withSelector(selector.build())
427 .withTreatment(treatment.build())
428 .withPriority(DEFAULT_PRIORITY)
429 .fromApp(applicationId)
430 .makePermanent()
431 .forTable(TMAC_TABLE).build();
432 rules.add(rule);
Pier Ventree0ae7a32016-11-23 09:57:42 -0800433 /*
434 * TMAC rules for IPv6 packets
435 */
436 selector = DefaultTrafficSelector.builder();
437 treatment = DefaultTrafficTreatment.builder();
438 selector.matchInPort(pnum);
439 selector.matchVlanId(vidCriterion.vlanId());
440 selector.matchEthType(Ethernet.TYPE_IPV6);
441 selector.matchEthDst(ethCriterion.mac());
442 /*
443 * workaround here again, we are removing
444 * the vlan tag before to go through the
445 * rest of the pipeline
446 */
447 treatment.popVlan();
448 treatment.transition(UNICAST_ROUTING_TABLE);
449 rule = DefaultFlowRule.builder()
450 .forDevice(deviceId)
451 .withSelector(selector.build())
452 .withTreatment(treatment.build())
453 .withPriority(DEFAULT_PRIORITY)
454 .fromApp(applicationId)
455 .makePermanent()
456 .forTable(TMAC_TABLE).build();
457 rules.add(rule);
Saurav Das4ce45962015-11-24 23:21:05 -0800458 }
459 return rules;
460 }
461
Charles Chan5270ed02016-01-30 23:22:37 -0800462 @Override
463 protected List<FlowRule> processEthDstOnlyFilter(EthCriterion ethCriterion,
464 ApplicationId applicationId) {
465 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
466 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
467 selector.matchEthType(Ethernet.TYPE_IPV4);
468 selector.matchEthDst(ethCriterion.mac());
469 /*
470 * Note: CpqD switches do not handle MPLS-related operation properly
471 * for a packet with VLAN tag. We pop VLAN here as a workaround.
472 * Side effect: HostService learns redundant hosts with same MAC but
473 * different VLAN. No known side effect on the network reachability.
474 */
475 treatment.popVlan();
476 treatment.transition(UNICAST_ROUTING_TABLE);
477 FlowRule rule = DefaultFlowRule.builder()
478 .forDevice(deviceId)
479 .withSelector(selector.build())
480 .withTreatment(treatment.build())
481 .withPriority(DEFAULT_PRIORITY)
482 .fromApp(applicationId)
483 .makePermanent()
484 .forTable(TMAC_TABLE).build();
485 return ImmutableList.<FlowRule>builder().add(rule).build();
486 }
487
Saurav Das4ce45962015-11-24 23:21:05 -0800488 /*
489 * Cpqd emulation allows MPLS ecmp.
490 *
491 * (non-Javadoc)
492 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthTypeSpecific
493 */
494 @Override
495 protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
Saurav Das8a0732e2015-11-20 15:27:53 -0800496 TrafficSelector selector = fwd.selector();
497 EthTypeCriterion ethType =
498 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
499 if ((ethType == null) ||
500 (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) &&
Pier Ventree0ae7a32016-11-23 09:57:42 -0800501 (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST) &&
502 (ethType.ethType().toShort() != Ethernet.TYPE_IPV6)) {
Saurav Das4ce45962015-11-24 23:21:05 -0800503 log.warn("processSpecific: Unsupported forwarding objective criteria"
504 + "ethType:{} in dev:{}", ethType, deviceId);
Saurav Das8a0732e2015-11-20 15:27:53 -0800505 fail(fwd, ObjectiveError.UNSUPPORTED);
506 return Collections.emptySet();
507 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800508 boolean defaultRule = false;
Saurav Das8a0732e2015-11-20 15:27:53 -0800509 int forTableId = -1;
510 TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder();
Flavio Castroe10fa242016-01-15 12:43:51 -0800511 TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
512
Saurav Das8a0732e2015-11-20 15:27:53 -0800513 if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
Flavio Castroe10fa242016-01-15 12:43:51 -0800514 IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
Charles Chan5b9df8d2016-03-28 22:21:40 -0700515 if (ipv4Dst.isMulticast()) {
516 if (ipv4Dst.prefixLength() != 32) {
517 log.warn("Multicast specific forwarding objective can only be /32");
518 fail(fwd, ObjectiveError.BADPARAMS);
519 return ImmutableSet.of();
520 }
521 VlanId assignedVlan = readVlanFromSelector(fwd.meta());
522 if (assignedVlan == null) {
523 log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
524 fail(fwd, ObjectiveError.BADPARAMS);
525 return ImmutableSet.of();
526 }
527 filteredSelector.matchVlanId(assignedVlan);
528 filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
529 forTableId = MULTICAST_ROUTING_TABLE;
530 log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}"
531 + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
Flavio Castroe10fa242016-01-15 12:43:51 -0800532 } else {
Charles Chanf9e98652016-09-07 16:54:23 -0700533 if (ipv4Dst.prefixLength() == 0) {
534 // The entire IPV4_DST field is wildcarded intentionally
535 filteredSelector.matchEthType(Ethernet.TYPE_IPV4);
Charles Chan5b9df8d2016-03-28 22:21:40 -0700536 } else {
Charles Chanf9e98652016-09-07 16:54:23 -0700537 filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
Charles Chan5b9df8d2016-03-28 22:21:40 -0700538 }
539 forTableId = UNICAST_ROUTING_TABLE;
540 log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}"
541 + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
Flavio Castroe10fa242016-01-15 12:43:51 -0800542 }
Pier Ventree0ae7a32016-11-23 09:57:42 -0800543 } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
544 if (buildIpv6Selector(filteredSelector, fwd) < 0) {
545 return Collections.emptyList();
546 }
547 forTableId = UNICAST_ROUTING_TABLE;
Saurav Das8a0732e2015-11-20 15:27:53 -0800548 } else {
549 filteredSelector
550 .matchEthType(Ethernet.MPLS_UNICAST)
551 .matchMplsLabel(((MplsCriterion)
552 selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
553 MplsBosCriterion bos = (MplsBosCriterion) selector
554 .getCriterion(Criterion.Type.MPLS_BOS);
555 if (bos != null) {
556 filteredSelector.matchMplsBos(bos.mplsBos());
557 }
558 forTableId = MPLS_TABLE_1;
Saurav Das4ce45962015-11-24 23:21:05 -0800559 log.debug("processing MPLS specific forwarding objective {} -> next:{}"
560 + " in dev {}", fwd.id(), fwd.nextId(), deviceId);
Saurav Das8a0732e2015-11-20 15:27:53 -0800561 }
562
563 TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
564 if (fwd.treatment() != null) {
565 for (Instruction i : fwd.treatment().allInstructions()) {
Charles Chan40132b32017-01-22 00:19:37 -0800566 if (!supportCopyTtl() && i instanceof L3ModificationInstruction) {
567 L3ModificationInstruction l3instr = (L3ModificationInstruction) i;
568 if (l3instr.subtype().equals(L3ModificationInstruction.L3SubType.TTL_IN) ||
569 l3instr.subtype().equals(L3ModificationInstruction.L3SubType.TTL_OUT)) {
570 continue;
571 }
572 }
Charles Chan7d10b162015-12-07 18:54:45 -0800573 /*
574 * NOTE: OF-DPA does not support immediate instruction in
575 * L3 unicast and MPLS table.
576 */
577 tb.deferred().add(i);
Saurav Das8a0732e2015-11-20 15:27:53 -0800578 }
579 }
580
581 if (fwd.nextId() != null) {
Saurav Das423fe2b2015-12-04 10:52:59 -0800582 NextGroup next = getGroupForNextObjective(fwd.nextId());
583 if (next != null) {
584 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
585 // we only need the top level group's key to point the flow to it
586 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
587 if (group == null) {
Saurav Das1ce0a7b2016-10-21 14:06:29 -0700588 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
589 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
Saurav Das423fe2b2015-12-04 10:52:59 -0800590 fail(fwd, ObjectiveError.GROUPMISSING);
591 return Collections.emptySet();
592 }
593 tb.deferred().group(group.id());
Saurav Das8a0732e2015-11-20 15:27:53 -0800594 }
Saurav Das8a0732e2015-11-20 15:27:53 -0800595 }
596 tb.transition(ACL_TABLE);
597 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
598 .fromApp(fwd.appId())
599 .withPriority(fwd.priority())
600 .forDevice(deviceId)
601 .withSelector(filteredSelector.build())
602 .withTreatment(tb.build())
603 .forTable(forTableId);
604
605 if (fwd.permanent()) {
606 ruleBuilder.makePermanent();
607 } else {
608 ruleBuilder.makeTemporary(fwd.timeout());
609 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800610 Collection<FlowRule> flowRuleCollection = new ArrayList<>();
611 flowRuleCollection.add(ruleBuilder.build());
612 if (defaultRule) {
Pier Ventree0ae7a32016-11-23 09:57:42 -0800613 flowRuleCollection.add(
614 defaultRoute(fwd, complementarySelector, forTableId, tb)
615 );
Flavio Castroe10fa242016-01-15 12:43:51 -0800616 log.debug("Default rule 0.0.0.0/0 is being installed two rules");
617 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800618 return flowRuleCollection;
Saurav Das8a0732e2015-11-20 15:27:53 -0800619 }
620
Charles Chan1e492d32016-01-30 23:22:37 -0800621 @Override
622 protected Collection<FlowRule> processEthDstSpecific(ForwardingObjective fwd) {
623 List<FlowRule> rules = new ArrayList<>();
624
625 // Build filtered selector
626 TrafficSelector selector = fwd.selector();
627 EthCriterion ethCriterion = (EthCriterion) selector
628 .getCriterion(Criterion.Type.ETH_DST);
629 VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) selector
630 .getCriterion(Criterion.Type.VLAN_VID);
631
632 if (vlanIdCriterion == null) {
633 log.warn("Forwarding objective for bridging requires vlan. Not "
634 + "installing fwd:{} in dev:{}", fwd.id(), deviceId);
635 fail(fwd, ObjectiveError.BADPARAMS);
636 return Collections.emptySet();
637 }
638
639 TrafficSelector.Builder filteredSelectorBuilder =
640 DefaultTrafficSelector.builder();
641 // Do not match MacAddress for subnet broadcast entry
642 if (!ethCriterion.mac().equals(MacAddress.NONE)) {
643 filteredSelectorBuilder.matchEthDst(ethCriterion.mac());
644 log.debug("processing L2 forwarding objective:{} -> next:{} in dev:{}",
645 fwd.id(), fwd.nextId(), deviceId);
646 } else {
647 log.debug("processing L2 Broadcast forwarding objective:{} -> next:{} "
648 + "in dev:{} for vlan:{}",
649 fwd.id(), fwd.nextId(), deviceId, vlanIdCriterion.vlanId());
650 }
651 filteredSelectorBuilder.matchVlanId(vlanIdCriterion.vlanId());
652 TrafficSelector filteredSelector = filteredSelectorBuilder.build();
653
654 if (fwd.treatment() != null) {
655 log.warn("Ignoring traffic treatment in fwd rule {} meant for L2 table"
656 + "for dev:{}. Expecting only nextId", fwd.id(), deviceId);
657 }
658
659 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
660 if (fwd.nextId() != null) {
661 NextGroup next = getGroupForNextObjective(fwd.nextId());
662 if (next != null) {
663 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
664 // we only need the top level group's key to point the flow to it
665 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
666 if (group != null) {
667 treatmentBuilder.deferred().group(group.id());
668 } else {
669 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
670 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
671 fail(fwd, ObjectiveError.GROUPMISSING);
672 return Collections.emptySet();
673 }
674 }
675 }
676 treatmentBuilder.immediate().transition(ACL_TABLE);
677 TrafficTreatment filteredTreatment = treatmentBuilder.build();
678
679 // Build bridging table entries
680 FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();
681 flowRuleBuilder.fromApp(fwd.appId())
682 .withPriority(fwd.priority())
683 .forDevice(deviceId)
684 .withSelector(filteredSelector)
685 .withTreatment(filteredTreatment)
686 .forTable(BRIDGING_TABLE);
687 if (fwd.permanent()) {
688 flowRuleBuilder.makePermanent();
689 } else {
690 flowRuleBuilder.makeTemporary(fwd.timeout());
691 }
692 rules.add(flowRuleBuilder.build());
693 return rules;
694 }
695
Saurav Das52025962016-01-28 22:30:01 -0800696 /*
697 * In the OF-DPA 2.0 pipeline, versatile forwarding objectives go to the
698 * ACL table. Because we pop off vlan tags in TMAC table,
699 * we need to avoid matching on vlans in the ACL table.
700 */
701 @Override
702 protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
703 log.info("Processing versatile forwarding objective");
704
705 EthTypeCriterion ethType =
706 (EthTypeCriterion) fwd.selector().getCriterion(Criterion.Type.ETH_TYPE);
707 if (ethType == null) {
708 log.error("Versatile forwarding objective must include ethType");
709 fail(fwd, ObjectiveError.BADPARAMS);
710 return Collections.emptySet();
711 }
712 if (fwd.nextId() == null && fwd.treatment() == null) {
713 log.error("Forwarding objective {} from {} must contain "
714 + "nextId or Treatment", fwd.selector(), fwd.appId());
715 return Collections.emptySet();
716 }
717
718 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
719 fwd.selector().criteria().forEach(criterion -> {
720 if (criterion instanceof VlanIdCriterion) {
721 // avoid matching on vlans
722 return;
Pier Ventree0ae7a32016-11-23 09:57:42 -0800723 } else if (criterion instanceof Icmpv6TypeCriterion ||
724 criterion instanceof Icmpv6CodeCriterion) {
725 /*
726 * We silenty discard these criterions, our current
727 * OFDPA platform does not support these matches on
728 * the ACL table.
729 */
730 log.warn("ICMPv6 Type and ICMPv6 Code are not supported");
Saurav Das52025962016-01-28 22:30:01 -0800731 } else {
732 sbuilder.add(criterion);
733 }
734 });
735
736 // XXX driver does not currently do type checking as per Tables 65-67 in
737 // OFDPA 2.0 spec. The only allowed treatment is a punt to the controller.
738 TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
739 if (fwd.treatment() != null) {
740 for (Instruction ins : fwd.treatment().allInstructions()) {
741 if (ins instanceof OutputInstruction) {
742 OutputInstruction o = (OutputInstruction) ins;
743 if (o.port() == PortNumber.CONTROLLER) {
744 ttBuilder.add(o);
745 } else {
746 log.warn("Only allowed treatments in versatile forwarding "
747 + "objectives are punts to the controller");
748 }
749 } else {
750 log.warn("Cannot process instruction in versatile fwd {}", ins);
751 }
752 }
Charles Chan2df0e8a2017-01-09 11:45:08 -0800753 if (fwd.treatment().clearedDeferred()) {
754 ttBuilder.wipeDeferred();
755 }
Saurav Das52025962016-01-28 22:30:01 -0800756 }
757 if (fwd.nextId() != null) {
758 // overide case
759 NextGroup next = getGroupForNextObjective(fwd.nextId());
760 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
761 // we only need the top level group's key to point the flow to it
762 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
763 if (group == null) {
764 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
765 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
766 fail(fwd, ObjectiveError.GROUPMISSING);
767 return Collections.emptySet();
768 }
769 ttBuilder.deferred().group(group.id());
770 }
771
772 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
773 .fromApp(fwd.appId())
774 .withPriority(fwd.priority())
775 .forDevice(deviceId)
776 .withSelector(sbuilder.build())
777 .withTreatment(ttBuilder.build())
778 .makePermanent()
779 .forTable(ACL_TABLE);
780 return Collections.singletonList(ruleBuilder.build());
781 }
782
783 /*
784 * Cpqd emulation requires table-miss-entries in forwarding tables.
785 * Real OFDPA does not require these rules as they are put in by default.
786 *
787 * (non-Javadoc)
788 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#initializePipeline()
789 */
Saurav Das2857f382015-11-03 14:39:27 -0800790 @Override
Saurav Das558afec2015-05-31 17:12:48 -0700791 protected void initializePipeline() {
792 processPortTable();
Saurav Das2857f382015-11-03 14:39:27 -0800793 // vlan table processing not required, as default is to drop packets
794 // which can be accomplished without a table-miss-entry.
Saurav Das558afec2015-05-31 17:12:48 -0700795 processTmacTable();
796 processIpTable();
Jonathan Hart855179c2016-04-26 07:40:04 -0700797 processMulticastIpTable();
Saurav Das2857f382015-11-03 14:39:27 -0800798 processMplsTable();
Saurav Das558afec2015-05-31 17:12:48 -0700799 processBridgingTable();
Saurav Das337c7a42015-06-02 15:12:06 -0700800 processAclTable();
Saurav Das558afec2015-05-31 17:12:48 -0700801 }
802
Saurav Das558afec2015-05-31 17:12:48 -0700803 protected void processPortTable() {
804 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
805 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
806 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
807 treatment.transition(VLAN_TABLE);
808 FlowRule tmisse = DefaultFlowRule.builder()
809 .forDevice(deviceId)
810 .withSelector(selector.build())
811 .withTreatment(treatment.build())
812 .withPriority(LOWEST_PRIORITY)
813 .fromApp(driverId)
814 .makePermanent()
815 .forTable(PORT_TABLE).build();
816 ops = ops.add(tmisse);
817
818 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
819 @Override
820 public void onSuccess(FlowRuleOperations ops) {
821 log.info("Initialized port table");
822 }
823
824 @Override
825 public void onError(FlowRuleOperations ops) {
826 log.info("Failed to initialize port table");
827 }
828 }));
829 }
830
Saurav Das558afec2015-05-31 17:12:48 -0700831 protected void processTmacTable() {
832 //table miss entry
833 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
834 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
835 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das558afec2015-05-31 17:12:48 -0700836 treatment.transition(BRIDGING_TABLE);
837 FlowRule rule = DefaultFlowRule.builder()
838 .forDevice(deviceId)
839 .withSelector(selector.build())
840 .withTreatment(treatment.build())
841 .withPriority(LOWEST_PRIORITY)
842 .fromApp(driverId)
843 .makePermanent()
844 .forTable(TMAC_TABLE).build();
845 ops = ops.add(rule);
846 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
847 @Override
848 public void onSuccess(FlowRuleOperations ops) {
849 log.info("Initialized tmac table");
850 }
851
852 @Override
853 public void onError(FlowRuleOperations ops) {
854 log.info("Failed to initialize tmac table");
855 }
856 }));
857 }
858
Saurav Das558afec2015-05-31 17:12:48 -0700859 protected void processIpTable() {
860 //table miss entry
861 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
862 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
863 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das558afec2015-05-31 17:12:48 -0700864 treatment.transition(ACL_TABLE);
865 FlowRule rule = DefaultFlowRule.builder()
866 .forDevice(deviceId)
867 .withSelector(selector.build())
868 .withTreatment(treatment.build())
869 .withPriority(LOWEST_PRIORITY)
870 .fromApp(driverId)
871 .makePermanent()
872 .forTable(UNICAST_ROUTING_TABLE).build();
873 ops = ops.add(rule);
874 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
875 @Override
876 public void onSuccess(FlowRuleOperations ops) {
877 log.info("Initialized IP table");
878 }
879
880 @Override
881 public void onError(FlowRuleOperations ops) {
882 log.info("Failed to initialize unicast IP table");
883 }
884 }));
885 }
886
Jonathan Hart855179c2016-04-26 07:40:04 -0700887 protected void processMulticastIpTable() {
888 //table miss entry
889 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
890 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
891 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
892 treatment.transition(ACL_TABLE);
893 FlowRule rule = DefaultFlowRule.builder()
894 .forDevice(deviceId)
895 .withSelector(selector.build())
896 .withTreatment(treatment.build())
897 .withPriority(LOWEST_PRIORITY)
898 .fromApp(driverId)
899 .makePermanent()
900 .forTable(MULTICAST_ROUTING_TABLE).build();
901 ops = ops.add(rule);
902 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
903 @Override
904 public void onSuccess(FlowRuleOperations ops) {
905 log.info("Initialized multicast IP table");
906 }
907
908 @Override
909 public void onError(FlowRuleOperations ops) {
910 log.info("Failed to initialize multicast IP table");
911 }
912 }));
913 }
914
Saurav Das2857f382015-11-03 14:39:27 -0800915 protected void processMplsTable() {
916 //table miss entry
917 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
918 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
919 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
920 selector = DefaultTrafficSelector.builder();
921 treatment = DefaultTrafficTreatment.builder();
922 treatment.transition(MPLS_TABLE_1);
923 FlowRule rule = DefaultFlowRule.builder()
924 .forDevice(deviceId)
925 .withSelector(selector.build())
926 .withTreatment(treatment.build())
927 .withPriority(LOWEST_PRIORITY)
928 .fromApp(driverId)
929 .makePermanent()
930 .forTable(MPLS_TABLE_0).build();
931 ops = ops.add(rule);
932
933 treatment.transition(ACL_TABLE);
934 rule = DefaultFlowRule.builder()
935 .forDevice(deviceId)
936 .withSelector(selector.build())
937 .withTreatment(treatment.build())
938 .withPriority(LOWEST_PRIORITY)
939 .fromApp(driverId)
940 .makePermanent()
941 .forTable(MPLS_TABLE_1).build();
942 ops = ops.add(rule);
943
944 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
945 @Override
946 public void onSuccess(FlowRuleOperations ops) {
947 log.info("Initialized MPLS tables");
948 }
949
950 @Override
951 public void onError(FlowRuleOperations ops) {
952 log.info("Failed to initialize MPLS tables");
953 }
954 }));
955 }
956
Saurav Das558afec2015-05-31 17:12:48 -0700957 private void processBridgingTable() {
958 //table miss entry
959 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
960 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
961 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das558afec2015-05-31 17:12:48 -0700962 treatment.transition(ACL_TABLE);
963 FlowRule rule = DefaultFlowRule.builder()
964 .forDevice(deviceId)
965 .withSelector(selector.build())
966 .withTreatment(treatment.build())
967 .withPriority(LOWEST_PRIORITY)
968 .fromApp(driverId)
969 .makePermanent()
970 .forTable(BRIDGING_TABLE).build();
971 ops = ops.add(rule);
972 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
973 @Override
974 public void onSuccess(FlowRuleOperations ops) {
975 log.info("Initialized Bridging table");
976 }
977
978 @Override
979 public void onError(FlowRuleOperations ops) {
980 log.info("Failed to initialize Bridging table");
981 }
982 }));
Saurav Das337c7a42015-06-02 15:12:06 -0700983 }
Saurav Das558afec2015-05-31 17:12:48 -0700984
Saurav Dasa07f2032015-10-19 14:37:36 -0700985 protected void processAclTable() {
Saurav Das337c7a42015-06-02 15:12:06 -0700986 //table miss entry - catch all to executed action-set
987 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
988 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
989 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das337c7a42015-06-02 15:12:06 -0700990 FlowRule rule = DefaultFlowRule.builder()
991 .forDevice(deviceId)
992 .withSelector(selector.build())
993 .withTreatment(treatment.build())
994 .withPriority(LOWEST_PRIORITY)
995 .fromApp(driverId)
996 .makePermanent()
997 .forTable(ACL_TABLE).build();
998 ops = ops.add(rule);
999 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
1000 @Override
1001 public void onSuccess(FlowRuleOperations ops) {
1002 log.info("Initialized Acl table");
1003 }
1004
1005 @Override
1006 public void onError(FlowRuleOperations ops) {
1007 log.info("Failed to initialize Acl table");
1008 }
1009 }));
Saurav Das558afec2015-05-31 17:12:48 -07001010 }
1011
1012}