blob: 32cc4eb34a25d018e596cf70fa378a6b911e79fa [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;
Saurav Das2857f382015-11-03 14:39:27 -080022import org.onlab.packet.VlanId;
23import org.onosproject.core.ApplicationId;
24import org.onosproject.net.Port;
25import org.onosproject.net.PortNumber;
Saurav Das8a0732e2015-11-20 15:27:53 -080026import org.onosproject.net.behaviour.NextGroup;
Charles Chan425854b2016-04-11 15:32:12 -070027import org.onosproject.net.behaviour.PipelinerContext;
Saurav Das558afec2015-05-31 17:12:48 -070028import org.onosproject.net.flow.DefaultFlowRule;
29import org.onosproject.net.flow.DefaultTrafficSelector;
30import org.onosproject.net.flow.DefaultTrafficTreatment;
31import org.onosproject.net.flow.FlowRule;
32import org.onosproject.net.flow.FlowRuleOperations;
33import org.onosproject.net.flow.FlowRuleOperationsContext;
34import org.onosproject.net.flow.TrafficSelector;
35import org.onosproject.net.flow.TrafficTreatment;
Saurav Das4ce45962015-11-24 23:21:05 -080036import org.onosproject.net.flow.criteria.Criteria;
Saurav Das8a0732e2015-11-20 15:27:53 -080037import org.onosproject.net.flow.criteria.Criterion;
Saurav Das4ce45962015-11-24 23:21:05 -080038import org.onosproject.net.flow.criteria.EthCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080039import org.onosproject.net.flow.criteria.EthTypeCriterion;
40import org.onosproject.net.flow.criteria.IPCriterion;
Pier Ventree0ae7a32016-11-23 09:57:42 -080041import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
42import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080043import org.onosproject.net.flow.criteria.MplsBosCriterion;
44import org.onosproject.net.flow.criteria.MplsCriterion;
Saurav Das2857f382015-11-03 14:39:27 -080045import org.onosproject.net.flow.criteria.PortCriterion;
46import org.onosproject.net.flow.criteria.VlanIdCriterion;
Saurav Das8a0732e2015-11-20 15:27:53 -080047import org.onosproject.net.flow.instructions.Instruction;
Saurav Das52025962016-01-28 22:30:01 -080048import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
Charles Chan40132b32017-01-22 00:19:37 -080049import org.onosproject.net.flow.instructions.L3ModificationInstruction;
Saurav Das52025962016-01-28 22:30:01 -080050import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
51import org.onosproject.net.flowobjective.FilteringObjective;
Saurav Das8a0732e2015-11-20 15:27:53 -080052import org.onosproject.net.flowobjective.ForwardingObjective;
53import org.onosproject.net.flowobjective.ObjectiveError;
54import org.onosproject.net.group.Group;
55import org.onosproject.net.group.GroupKey;
Charles Chanf57a8252016-06-29 19:12:37 -070056import org.onosproject.net.packet.PacketPriority;
Saurav Das558afec2015-05-31 17:12:48 -070057import org.slf4j.Logger;
58
Jonathan Hart855179c2016-04-26 07:40:04 -070059import java.util.ArrayList;
60import java.util.Collection;
61import java.util.Collections;
62import java.util.Deque;
63import java.util.List;
64
Pier Ventree0ae7a32016-11-23 09:57:42 -080065import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
Charles Chand05f54b2017-02-13 11:56:54 -080066import static org.onlab.packet.MacAddress.BROADCAST;
67import static org.onlab.packet.MacAddress.NONE;
Jonathan Hart855179c2016-04-26 07:40:04 -070068import static org.slf4j.LoggerFactory.getLogger;
69
Saurav Das558afec2015-05-31 17:12:48 -070070
71/**
Charles Chan40132b32017-01-22 00:19:37 -080072 * Driver for software switch emulation of the OFDPA pipeline.
Saurav Das52025962016-01-28 22:30:01 -080073 * The software switch is the CPqD OF 1.3 switch. Unfortunately the CPqD switch
74 * does not handle vlan tags and mpls labels simultaneously, which requires us
75 * to do some workarounds in the driver. This driver is meant for the use of
76 * the cpqd switch when MPLS is required. As a result this driver works only
77 * on incoming untagged packets.
Saurav Das558afec2015-05-31 17:12:48 -070078 */
Charles Chan361154b2016-03-24 10:23:39 -070079public class CpqdOfdpa2Pipeline extends Ofdpa2Pipeline {
Saurav Das558afec2015-05-31 17:12:48 -070080
81 private final Logger log = getLogger(getClass());
82
Charles Chan40132b32017-01-22 00:19:37 -080083 /**
84 * Determines whether this pipeline support copy ttl instructions or not.
85 *
86 * @return true if copy ttl instructions are supported
87 */
88 protected boolean supportCopyTtl() {
89 return true;
90 }
91
Charles Chan425854b2016-04-11 15:32:12 -070092 @Override
Charles Chan40132b32017-01-22 00:19:37 -080093 protected void initDriverId() {
Charles Chan425854b2016-04-11 15:32:12 -070094 driverId = coreService.registerApplication(
95 "org.onosproject.driver.CpqdOfdpa2Pipeline");
Charles Chan40132b32017-01-22 00:19:37 -080096 }
Charles Chan425854b2016-04-11 15:32:12 -070097
Charles Chan40132b32017-01-22 00:19:37 -080098 @Override
99 protected void initGroupHander(PipelinerContext context) {
100 groupHandler = new CpqdOfdpa2GroupHandler();
101 groupHandler.init(deviceId, context);
Charles Chan425854b2016-04-11 15:32:12 -0700102 }
103
Saurav Das4ce45962015-11-24 23:21:05 -0800104 /*
Saurav Das52025962016-01-28 22:30:01 -0800105 * CPQD emulation does not require special untagged packet handling, unlike
106 * the real ofdpa.
107 */
108 @Override
109 protected void processFilter(FilteringObjective filt,
110 boolean install, ApplicationId applicationId) {
111 // This driver only processes filtering criteria defined with switch
112 // ports as the key
113 PortCriterion portCriterion = null;
114 EthCriterion ethCriterion = null;
115 VlanIdCriterion vidCriterion = null;
116 Collection<IPCriterion> ips = new ArrayList<IPCriterion>();
117 if (!filt.key().equals(Criteria.dummy()) &&
118 filt.key().type() == Criterion.Type.IN_PORT) {
119 portCriterion = (PortCriterion) filt.key();
120 } else {
121 log.warn("No key defined in filtering objective from app: {}. Not"
122 + "processing filtering objective", applicationId);
123 fail(filt, ObjectiveError.UNKNOWN);
124 return;
125 }
126 // convert filtering conditions for switch-intfs into flowrules
127 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
128 for (Criterion criterion : filt.conditions()) {
Charles Chan5b9df8d2016-03-28 22:21:40 -0700129 if (criterion.type() == Criterion.Type.ETH_DST ||
130 criterion.type() == Criterion.Type.ETH_DST_MASKED) {
Saurav Das52025962016-01-28 22:30:01 -0800131 ethCriterion = (EthCriterion) criterion;
132 } else if (criterion.type() == Criterion.Type.VLAN_VID) {
133 vidCriterion = (VlanIdCriterion) criterion;
134 } else if (criterion.type() == Criterion.Type.IPV4_DST) {
135 ips.add((IPCriterion) criterion);
136 } else {
137 log.error("Unsupported filter {}", criterion);
138 fail(filt, ObjectiveError.UNSUPPORTED);
139 return;
140 }
141 }
142
143 VlanId assignedVlan = null;
144 // For VLAN cross-connect packets, use the configured VLAN
145 if (vidCriterion != null) {
146 if (vidCriterion.vlanId() != VlanId.NONE) {
147 assignedVlan = vidCriterion.vlanId();
148
149 // For untagged packets, assign a VLAN ID
150 } else {
151 if (filt.meta() == null) {
152 log.error("Missing metadata in filtering objective required " +
153 "for vlan assignment in dev {}", deviceId);
154 fail(filt, ObjectiveError.BADPARAMS);
155 return;
156 }
157 for (Instruction i : filt.meta().allInstructions()) {
158 if (i instanceof ModVlanIdInstruction) {
159 assignedVlan = ((ModVlanIdInstruction) i).vlanId();
160 }
161 }
162 if (assignedVlan == null) {
163 log.error("Driver requires an assigned vlan-id to tag incoming "
164 + "untagged packets. Not processing vlan filters on "
165 + "device {}", deviceId);
166 fail(filt, ObjectiveError.BADPARAMS);
167 return;
168 }
169 }
170 }
171
Charles Chand05f54b2017-02-13 11:56:54 -0800172 if (ethCriterion == null || ethCriterion.mac().equals(NONE)) {
Saurav Das52025962016-01-28 22:30:01 -0800173 log.debug("filtering objective missing dstMac, cannot program TMAC table");
174 } else {
175 for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion,
176 vidCriterion, assignedVlan,
177 applicationId)) {
178 log.debug("adding MAC filtering rules in TMAC table: {} for dev: {}",
179 tmacRule, deviceId);
180 ops = install ? ops.add(tmacRule) : ops.remove(tmacRule);
181 }
182 }
183
184 if (ethCriterion == null || vidCriterion == null) {
185 log.debug("filtering objective missing dstMac or VLAN, "
186 + "cannot program VLAN Table");
187 } else {
188 List<FlowRule> allRules = processVlanIdFilter(
189 portCriterion, vidCriterion, assignedVlan, applicationId);
190 for (FlowRule rule : allRules) {
191 log.debug("adding VLAN filtering rule in VLAN table: {} for dev: {}",
192 rule, deviceId);
193 ops = install ? ops.add(rule) : ops.remove(rule);
194 }
195 }
196
197 for (IPCriterion ipaddr : ips) {
198 // since we ignore port information for IP rules, and the same (gateway) IP
199 // can be configured on multiple ports, we make sure that we send
200 // only a single rule to the switch.
201 if (!sentIpFilters.contains(ipaddr)) {
202 sentIpFilters.add(ipaddr);
203 log.debug("adding IP filtering rules in ACL table {} for dev: {}",
204 ipaddr, deviceId);
205 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
206 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
207 selector.matchEthType(Ethernet.TYPE_IPV4);
208 selector.matchIPDst(ipaddr.ip());
209 treatment.setOutput(PortNumber.CONTROLLER);
210 FlowRule rule = DefaultFlowRule.builder()
211 .forDevice(deviceId)
212 .withSelector(selector.build())
213 .withTreatment(treatment.build())
214 .withPriority(HIGHEST_PRIORITY)
215 .fromApp(applicationId)
216 .makePermanent()
217 .forTable(ACL_TABLE).build();
218 ops = install ? ops.add(rule) : ops.remove(rule);
219 }
220 }
221
222 // apply filtering flow rules
223 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
224 @Override
225 public void onSuccess(FlowRuleOperations ops) {
226 log.info("Applied {} filtering rules in device {}",
227 ops.stages().get(0).size(), deviceId);
228 pass(filt);
229 }
230
231 @Override
232 public void onError(FlowRuleOperations ops) {
233 log.info("Failed to apply all filtering rules in dev {}", deviceId);
234 fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
235 }
236 }));
237
238 }
239
240 /*
Saurav Das1ce0a7b2016-10-21 14:06:29 -0700241 * Cpqd emulation does not require the non OF-standard rules for
242 * matching untagged packets that ofdpa uses.
Saurav Das4ce45962015-11-24 23:21:05 -0800243 *
244 * (non-Javadoc)
245 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processVlanIdFilter
246 */
Saurav Das558afec2015-05-31 17:12:48 -0700247 @Override
Saurav Das2857f382015-11-03 14:39:27 -0800248 protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion,
249 VlanIdCriterion vidCriterion,
250 VlanId assignedVlan,
251 ApplicationId applicationId) {
Charles Chan79769232016-07-05 16:34:39 -0700252 List<FlowRule> rules = new ArrayList<>();
Saurav Das2857f382015-11-03 14:39:27 -0800253 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
254 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
255 selector.matchVlanId(vidCriterion.vlanId());
Saurav Das4f980082015-11-05 13:39:15 -0800256 treatment.transition(TMAC_TABLE);
257
Saurav Das2857f382015-11-03 14:39:27 -0800258 if (vidCriterion.vlanId() == VlanId.NONE) {
259 // untagged packets are assigned vlans
260 treatment.pushVlan().setVlanId(assignedVlan);
Charles Chan79769232016-07-05 16:34:39 -0700261
262 // Emulating OFDPA behavior by popping off internal assigned VLAN
263 // before sending to controller
Pier Ventree0ae7a32016-11-23 09:57:42 -0800264 rules.add(buildArpPunt(assignedVlan, applicationId));
265 rules.add(buildIcmpV6Punt(assignedVlan, applicationId));
Saurav Das2857f382015-11-03 14:39:27 -0800266 }
Saurav Das2857f382015-11-03 14:39:27 -0800267
268 // ofdpa cannot match on ALL portnumber, so we need to use separate
269 // rules for each port.
270 List<PortNumber> portnums = new ArrayList<PortNumber>();
271 if (portCriterion.port() == PortNumber.ALL) {
272 for (Port port : deviceService.getPorts(deviceId)) {
273 if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
274 portnums.add(port.number());
275 }
276 }
277 } else {
278 portnums.add(portCriterion.port());
279 }
Saurav Das4f980082015-11-05 13:39:15 -0800280
Saurav Das2857f382015-11-03 14:39:27 -0800281 for (PortNumber pnum : portnums) {
Saurav Das4f980082015-11-05 13:39:15 -0800282 // create rest of flowrule
Saurav Das2857f382015-11-03 14:39:27 -0800283 selector.matchInPort(pnum);
284 FlowRule rule = DefaultFlowRule.builder()
285 .forDevice(deviceId)
286 .withSelector(selector.build())
287 .withTreatment(treatment.build())
288 .withPriority(DEFAULT_PRIORITY)
289 .fromApp(applicationId)
290 .makePermanent()
291 .forTable(VLAN_TABLE).build();
292 rules.add(rule);
293 }
Charles Chanf57a8252016-06-29 19:12:37 -0700294
Saurav Das2857f382015-11-03 14:39:27 -0800295 return rules;
296 }
297
Pier Ventree0ae7a32016-11-23 09:57:42 -0800298 /**
299 * Builds a punt to the controller rule for the arp protocol.
300 *
301 * @param assignedVlan the internal assigned vlan id
302 * @param applicationId the application id
303 * @return the punt flow rule for the arp
304 */
305 private FlowRule buildArpPunt(VlanId assignedVlan, ApplicationId applicationId) {
306 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
307 .matchEthType(Ethernet.TYPE_ARP)
308 .matchVlanId(assignedVlan);
309 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder()
310 .popVlan()
311 .punt();
312
313 return DefaultFlowRule.builder()
314 .forDevice(deviceId)
315 .withSelector(sbuilder.build())
316 .withTreatment(tbuilder.build())
317 .withPriority(PacketPriority.CONTROL.priorityValue() + 1)
318 .fromApp(applicationId)
319 .makePermanent()
320 .forTable(ACL_TABLE).build();
321 }
322
323 /**
324 * Builds a punt to the controller rule for the icmp v6 messages.
325 *
326 * @param assignedVlan the internal assigned vlan id
327 * @param applicationId the application id
328 * @return the punt flow rule for the icmp v6 messages
329 */
330 private FlowRule buildIcmpV6Punt(VlanId assignedVlan, ApplicationId applicationId) {
331 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
332 .matchVlanId(assignedVlan)
333 .matchEthType(Ethernet.TYPE_IPV6)
334 .matchIPProtocol(PROTOCOL_ICMP6);
335 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder()
336 .popVlan()
337 .punt();
338
339 return DefaultFlowRule.builder()
340 .forDevice(deviceId)
341 .withSelector(sbuilder.build())
342 .withTreatment(tbuilder.build())
343 .withPriority(PacketPriority.CONTROL.priorityValue() + 1)
344 .fromApp(applicationId)
345 .makePermanent()
346 .forTable(ACL_TABLE).build();
347 }
348
Saurav Das4ce45962015-11-24 23:21:05 -0800349 /*
350 * Cpqd emulation does not handle vlan tags and mpls labels correctly.
351 * Workaround requires popping off the VLAN tags in the TMAC table.
352 *
353 * (non-Javadoc)
354 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthDstFilter
355 */
Saurav Das8a0732e2015-11-20 15:27:53 -0800356 @Override
Saurav Das4ce45962015-11-24 23:21:05 -0800357 protected List<FlowRule> processEthDstFilter(PortCriterion portCriterion,
358 EthCriterion ethCriterion,
359 VlanIdCriterion vidCriterion,
360 VlanId assignedVlan,
361 ApplicationId applicationId) {
Charles Chan5270ed02016-01-30 23:22:37 -0800362 // Consider PortNumber.ANY as wildcard. Match ETH_DST only
363 if (portCriterion != null && portCriterion.port() == PortNumber.ANY) {
364 return processEthDstOnlyFilter(ethCriterion, applicationId);
365 }
366
Charles Chan5b9df8d2016-03-28 22:21:40 -0700367 // Multicast MAC
368 if (ethCriterion.mask() != null) {
369 return processMcastEthDstFilter(ethCriterion, applicationId);
370 }
371
Saurav Das4ce45962015-11-24 23:21:05 -0800372 //handling untagged packets via assigned VLAN
373 if (vidCriterion.vlanId() == VlanId.NONE) {
374 vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan);
375 }
376 // ofdpa cannot match on ALL portnumber, so we need to use separate
377 // rules for each port.
378 List<PortNumber> portnums = new ArrayList<PortNumber>();
379 if (portCriterion.port() == PortNumber.ALL) {
380 for (Port port : deviceService.getPorts(deviceId)) {
381 if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
382 portnums.add(port.number());
383 }
384 }
385 } else {
386 portnums.add(portCriterion.port());
387 }
388
389 List<FlowRule> rules = new ArrayList<FlowRule>();
390 for (PortNumber pnum : portnums) {
391 // for unicast IP packets
392 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
393 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
394 selector.matchInPort(pnum);
395 selector.matchVlanId(vidCriterion.vlanId());
396 selector.matchEthType(Ethernet.TYPE_IPV4);
397 selector.matchEthDst(ethCriterion.mac());
398 /*
399 * Note: CpqD switches do not handle MPLS-related operation properly
400 * for a packet with VLAN tag. We pop VLAN here as a workaround.
401 * Side effect: HostService learns redundant hosts with same MAC but
402 * different VLAN. No known side effect on the network reachability.
403 */
404 treatment.popVlan();
405 treatment.transition(UNICAST_ROUTING_TABLE);
406 FlowRule rule = DefaultFlowRule.builder()
407 .forDevice(deviceId)
408 .withSelector(selector.build())
409 .withTreatment(treatment.build())
410 .withPriority(DEFAULT_PRIORITY)
411 .fromApp(applicationId)
412 .makePermanent()
413 .forTable(TMAC_TABLE).build();
414 rules.add(rule);
415 //for MPLS packets
416 selector = DefaultTrafficSelector.builder();
417 treatment = DefaultTrafficTreatment.builder();
418 selector.matchInPort(pnum);
419 selector.matchVlanId(vidCriterion.vlanId());
420 selector.matchEthType(Ethernet.MPLS_UNICAST);
421 selector.matchEthDst(ethCriterion.mac());
422 // workaround here again
423 treatment.popVlan();
424 treatment.transition(MPLS_TABLE_0);
425 rule = DefaultFlowRule.builder()
426 .forDevice(deviceId)
427 .withSelector(selector.build())
428 .withTreatment(treatment.build())
429 .withPriority(DEFAULT_PRIORITY)
430 .fromApp(applicationId)
431 .makePermanent()
432 .forTable(TMAC_TABLE).build();
433 rules.add(rule);
Pier Ventree0ae7a32016-11-23 09:57:42 -0800434 /*
435 * TMAC rules for IPv6 packets
436 */
437 selector = DefaultTrafficSelector.builder();
438 treatment = DefaultTrafficTreatment.builder();
439 selector.matchInPort(pnum);
440 selector.matchVlanId(vidCriterion.vlanId());
441 selector.matchEthType(Ethernet.TYPE_IPV6);
442 selector.matchEthDst(ethCriterion.mac());
443 /*
444 * workaround here again, we are removing
445 * the vlan tag before to go through the
446 * rest of the pipeline
447 */
448 treatment.popVlan();
449 treatment.transition(UNICAST_ROUTING_TABLE);
450 rule = DefaultFlowRule.builder()
451 .forDevice(deviceId)
452 .withSelector(selector.build())
453 .withTreatment(treatment.build())
454 .withPriority(DEFAULT_PRIORITY)
455 .fromApp(applicationId)
456 .makePermanent()
457 .forTable(TMAC_TABLE).build();
458 rules.add(rule);
Saurav Das4ce45962015-11-24 23:21:05 -0800459 }
460 return rules;
461 }
462
Charles Chan5270ed02016-01-30 23:22:37 -0800463 @Override
464 protected List<FlowRule> processEthDstOnlyFilter(EthCriterion ethCriterion,
465 ApplicationId applicationId) {
466 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
467 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
468 selector.matchEthType(Ethernet.TYPE_IPV4);
469 selector.matchEthDst(ethCriterion.mac());
470 /*
471 * Note: CpqD switches do not handle MPLS-related operation properly
472 * for a packet with VLAN tag. We pop VLAN here as a workaround.
473 * Side effect: HostService learns redundant hosts with same MAC but
474 * different VLAN. No known side effect on the network reachability.
475 */
476 treatment.popVlan();
477 treatment.transition(UNICAST_ROUTING_TABLE);
478 FlowRule rule = DefaultFlowRule.builder()
479 .forDevice(deviceId)
480 .withSelector(selector.build())
481 .withTreatment(treatment.build())
482 .withPriority(DEFAULT_PRIORITY)
483 .fromApp(applicationId)
484 .makePermanent()
485 .forTable(TMAC_TABLE).build();
486 return ImmutableList.<FlowRule>builder().add(rule).build();
487 }
488
Saurav Das4ce45962015-11-24 23:21:05 -0800489 /*
490 * Cpqd emulation allows MPLS ecmp.
491 *
492 * (non-Javadoc)
493 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthTypeSpecific
494 */
495 @Override
496 protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
Saurav Das8a0732e2015-11-20 15:27:53 -0800497 TrafficSelector selector = fwd.selector();
498 EthTypeCriterion ethType =
499 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
500 if ((ethType == null) ||
501 (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) &&
Pier Ventree0ae7a32016-11-23 09:57:42 -0800502 (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST) &&
503 (ethType.ethType().toShort() != Ethernet.TYPE_IPV6)) {
Saurav Das4ce45962015-11-24 23:21:05 -0800504 log.warn("processSpecific: Unsupported forwarding objective criteria"
505 + "ethType:{} in dev:{}", ethType, deviceId);
Saurav Das8a0732e2015-11-20 15:27:53 -0800506 fail(fwd, ObjectiveError.UNSUPPORTED);
507 return Collections.emptySet();
508 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800509 boolean defaultRule = false;
Saurav Das8a0732e2015-11-20 15:27:53 -0800510 int forTableId = -1;
511 TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder();
Flavio Castroe10fa242016-01-15 12:43:51 -0800512 TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
513
Saurav Das8a0732e2015-11-20 15:27:53 -0800514 if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
Flavio Castroe10fa242016-01-15 12:43:51 -0800515 IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
Charles Chan5b9df8d2016-03-28 22:21:40 -0700516 if (ipv4Dst.isMulticast()) {
517 if (ipv4Dst.prefixLength() != 32) {
518 log.warn("Multicast specific forwarding objective can only be /32");
519 fail(fwd, ObjectiveError.BADPARAMS);
520 return ImmutableSet.of();
521 }
522 VlanId assignedVlan = readVlanFromSelector(fwd.meta());
523 if (assignedVlan == null) {
524 log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
525 fail(fwd, ObjectiveError.BADPARAMS);
526 return ImmutableSet.of();
527 }
528 filteredSelector.matchVlanId(assignedVlan);
529 filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
530 forTableId = MULTICAST_ROUTING_TABLE;
531 log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}"
532 + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
Flavio Castroe10fa242016-01-15 12:43:51 -0800533 } else {
Charles Chanf9e98652016-09-07 16:54:23 -0700534 if (ipv4Dst.prefixLength() == 0) {
535 // The entire IPV4_DST field is wildcarded intentionally
536 filteredSelector.matchEthType(Ethernet.TYPE_IPV4);
Charles Chan5b9df8d2016-03-28 22:21:40 -0700537 } else {
Charles Chanf9e98652016-09-07 16:54:23 -0700538 filteredSelector.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
Charles Chan5b9df8d2016-03-28 22:21:40 -0700539 }
540 forTableId = UNICAST_ROUTING_TABLE;
541 log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}"
542 + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
Flavio Castroe10fa242016-01-15 12:43:51 -0800543 }
Pier Ventree0ae7a32016-11-23 09:57:42 -0800544 } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
545 if (buildIpv6Selector(filteredSelector, fwd) < 0) {
546 return Collections.emptyList();
547 }
548 forTableId = UNICAST_ROUTING_TABLE;
Saurav Das8a0732e2015-11-20 15:27:53 -0800549 } else {
550 filteredSelector
551 .matchEthType(Ethernet.MPLS_UNICAST)
552 .matchMplsLabel(((MplsCriterion)
553 selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
554 MplsBosCriterion bos = (MplsBosCriterion) selector
555 .getCriterion(Criterion.Type.MPLS_BOS);
556 if (bos != null) {
557 filteredSelector.matchMplsBos(bos.mplsBos());
558 }
559 forTableId = MPLS_TABLE_1;
Saurav Das4ce45962015-11-24 23:21:05 -0800560 log.debug("processing MPLS specific forwarding objective {} -> next:{}"
561 + " in dev {}", fwd.id(), fwd.nextId(), deviceId);
Saurav Das8a0732e2015-11-20 15:27:53 -0800562 }
563
564 TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
565 if (fwd.treatment() != null) {
566 for (Instruction i : fwd.treatment().allInstructions()) {
Charles Chan40132b32017-01-22 00:19:37 -0800567 if (!supportCopyTtl() && i instanceof L3ModificationInstruction) {
568 L3ModificationInstruction l3instr = (L3ModificationInstruction) i;
569 if (l3instr.subtype().equals(L3ModificationInstruction.L3SubType.TTL_IN) ||
570 l3instr.subtype().equals(L3ModificationInstruction.L3SubType.TTL_OUT)) {
571 continue;
572 }
573 }
Charles Chan7d10b162015-12-07 18:54:45 -0800574 /*
575 * NOTE: OF-DPA does not support immediate instruction in
576 * L3 unicast and MPLS table.
577 */
578 tb.deferred().add(i);
Saurav Das8a0732e2015-11-20 15:27:53 -0800579 }
580 }
581
582 if (fwd.nextId() != null) {
Saurav Das423fe2b2015-12-04 10:52:59 -0800583 NextGroup next = getGroupForNextObjective(fwd.nextId());
584 if (next != null) {
585 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
586 // we only need the top level group's key to point the flow to it
587 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
588 if (group == null) {
Saurav Das1ce0a7b2016-10-21 14:06:29 -0700589 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
590 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
Saurav Das423fe2b2015-12-04 10:52:59 -0800591 fail(fwd, ObjectiveError.GROUPMISSING);
592 return Collections.emptySet();
593 }
594 tb.deferred().group(group.id());
Saurav Das8a0732e2015-11-20 15:27:53 -0800595 }
Saurav Das8a0732e2015-11-20 15:27:53 -0800596 }
597 tb.transition(ACL_TABLE);
598 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
599 .fromApp(fwd.appId())
600 .withPriority(fwd.priority())
601 .forDevice(deviceId)
602 .withSelector(filteredSelector.build())
603 .withTreatment(tb.build())
604 .forTable(forTableId);
605
606 if (fwd.permanent()) {
607 ruleBuilder.makePermanent();
608 } else {
609 ruleBuilder.makeTemporary(fwd.timeout());
610 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800611 Collection<FlowRule> flowRuleCollection = new ArrayList<>();
612 flowRuleCollection.add(ruleBuilder.build());
613 if (defaultRule) {
Pier Ventree0ae7a32016-11-23 09:57:42 -0800614 flowRuleCollection.add(
615 defaultRoute(fwd, complementarySelector, forTableId, tb)
616 );
Flavio Castroe10fa242016-01-15 12:43:51 -0800617 log.debug("Default rule 0.0.0.0/0 is being installed two rules");
618 }
Flavio Castroe10fa242016-01-15 12:43:51 -0800619 return flowRuleCollection;
Saurav Das8a0732e2015-11-20 15:27:53 -0800620 }
621
Charles Chan1e492d32016-01-30 23:22:37 -0800622 @Override
623 protected Collection<FlowRule> processEthDstSpecific(ForwardingObjective fwd) {
624 List<FlowRule> rules = new ArrayList<>();
625
626 // Build filtered selector
627 TrafficSelector selector = fwd.selector();
628 EthCriterion ethCriterion = (EthCriterion) selector
629 .getCriterion(Criterion.Type.ETH_DST);
630 VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) selector
631 .getCriterion(Criterion.Type.VLAN_VID);
632
633 if (vlanIdCriterion == null) {
634 log.warn("Forwarding objective for bridging requires vlan. Not "
635 + "installing fwd:{} in dev:{}", fwd.id(), deviceId);
636 fail(fwd, ObjectiveError.BADPARAMS);
637 return Collections.emptySet();
638 }
639
640 TrafficSelector.Builder filteredSelectorBuilder =
641 DefaultTrafficSelector.builder();
642 // Do not match MacAddress for subnet broadcast entry
Charles Chand05f54b2017-02-13 11:56:54 -0800643 if (!ethCriterion.mac().equals(NONE) && !ethCriterion.mac().equals(BROADCAST)) {
Charles Chan1e492d32016-01-30 23:22:37 -0800644 filteredSelectorBuilder.matchEthDst(ethCriterion.mac());
645 log.debug("processing L2 forwarding objective:{} -> next:{} in dev:{}",
646 fwd.id(), fwd.nextId(), deviceId);
647 } else {
648 log.debug("processing L2 Broadcast forwarding objective:{} -> next:{} "
649 + "in dev:{} for vlan:{}",
650 fwd.id(), fwd.nextId(), deviceId, vlanIdCriterion.vlanId());
651 }
652 filteredSelectorBuilder.matchVlanId(vlanIdCriterion.vlanId());
653 TrafficSelector filteredSelector = filteredSelectorBuilder.build();
654
655 if (fwd.treatment() != null) {
656 log.warn("Ignoring traffic treatment in fwd rule {} meant for L2 table"
657 + "for dev:{}. Expecting only nextId", fwd.id(), deviceId);
658 }
659
660 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
661 if (fwd.nextId() != null) {
662 NextGroup next = getGroupForNextObjective(fwd.nextId());
663 if (next != null) {
664 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
665 // we only need the top level group's key to point the flow to it
666 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
667 if (group != null) {
668 treatmentBuilder.deferred().group(group.id());
669 } else {
670 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
671 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
672 fail(fwd, ObjectiveError.GROUPMISSING);
673 return Collections.emptySet();
674 }
675 }
676 }
677 treatmentBuilder.immediate().transition(ACL_TABLE);
678 TrafficTreatment filteredTreatment = treatmentBuilder.build();
679
680 // Build bridging table entries
681 FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();
682 flowRuleBuilder.fromApp(fwd.appId())
683 .withPriority(fwd.priority())
684 .forDevice(deviceId)
685 .withSelector(filteredSelector)
686 .withTreatment(filteredTreatment)
687 .forTable(BRIDGING_TABLE);
688 if (fwd.permanent()) {
689 flowRuleBuilder.makePermanent();
690 } else {
691 flowRuleBuilder.makeTemporary(fwd.timeout());
692 }
693 rules.add(flowRuleBuilder.build());
694 return rules;
695 }
696
Saurav Das52025962016-01-28 22:30:01 -0800697 /*
698 * In the OF-DPA 2.0 pipeline, versatile forwarding objectives go to the
699 * ACL table. Because we pop off vlan tags in TMAC table,
700 * we need to avoid matching on vlans in the ACL table.
701 */
702 @Override
703 protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
704 log.info("Processing versatile forwarding objective");
705
706 EthTypeCriterion ethType =
707 (EthTypeCriterion) fwd.selector().getCriterion(Criterion.Type.ETH_TYPE);
708 if (ethType == null) {
709 log.error("Versatile forwarding objective must include ethType");
710 fail(fwd, ObjectiveError.BADPARAMS);
711 return Collections.emptySet();
712 }
713 if (fwd.nextId() == null && fwd.treatment() == null) {
714 log.error("Forwarding objective {} from {} must contain "
715 + "nextId or Treatment", fwd.selector(), fwd.appId());
716 return Collections.emptySet();
717 }
718
719 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
720 fwd.selector().criteria().forEach(criterion -> {
721 if (criterion instanceof VlanIdCriterion) {
722 // avoid matching on vlans
723 return;
Pier Ventree0ae7a32016-11-23 09:57:42 -0800724 } else if (criterion instanceof Icmpv6TypeCriterion ||
725 criterion instanceof Icmpv6CodeCriterion) {
726 /*
727 * We silenty discard these criterions, our current
728 * OFDPA platform does not support these matches on
729 * the ACL table.
730 */
731 log.warn("ICMPv6 Type and ICMPv6 Code are not supported");
Saurav Das52025962016-01-28 22:30:01 -0800732 } else {
733 sbuilder.add(criterion);
734 }
735 });
736
737 // XXX driver does not currently do type checking as per Tables 65-67 in
738 // OFDPA 2.0 spec. The only allowed treatment is a punt to the controller.
739 TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
740 if (fwd.treatment() != null) {
741 for (Instruction ins : fwd.treatment().allInstructions()) {
742 if (ins instanceof OutputInstruction) {
743 OutputInstruction o = (OutputInstruction) ins;
744 if (o.port() == PortNumber.CONTROLLER) {
745 ttBuilder.add(o);
746 } else {
747 log.warn("Only allowed treatments in versatile forwarding "
748 + "objectives are punts to the controller");
749 }
750 } else {
751 log.warn("Cannot process instruction in versatile fwd {}", ins);
752 }
753 }
Charles Chan2df0e8a2017-01-09 11:45:08 -0800754 if (fwd.treatment().clearedDeferred()) {
755 ttBuilder.wipeDeferred();
756 }
Saurav Das52025962016-01-28 22:30:01 -0800757 }
758 if (fwd.nextId() != null) {
759 // overide case
760 NextGroup next = getGroupForNextObjective(fwd.nextId());
761 List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
762 // we only need the top level group's key to point the flow to it
763 Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
764 if (group == null) {
765 log.warn("Group with key:{} for next-id:{} not found in dev:{}",
766 gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
767 fail(fwd, ObjectiveError.GROUPMISSING);
768 return Collections.emptySet();
769 }
770 ttBuilder.deferred().group(group.id());
771 }
772
773 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
774 .fromApp(fwd.appId())
775 .withPriority(fwd.priority())
776 .forDevice(deviceId)
777 .withSelector(sbuilder.build())
778 .withTreatment(ttBuilder.build())
779 .makePermanent()
780 .forTable(ACL_TABLE);
781 return Collections.singletonList(ruleBuilder.build());
782 }
783
784 /*
785 * Cpqd emulation requires table-miss-entries in forwarding tables.
786 * Real OFDPA does not require these rules as they are put in by default.
787 *
788 * (non-Javadoc)
789 * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#initializePipeline()
790 */
Saurav Das2857f382015-11-03 14:39:27 -0800791 @Override
Saurav Das558afec2015-05-31 17:12:48 -0700792 protected void initializePipeline() {
793 processPortTable();
Charles Chanb7504392017-02-10 12:51:04 -0800794 processVlanTable();
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) {
Charles Chanb7504392017-02-10 12:51:04 -0800821 log.info("Initialized port table on {}", deviceId);
Saurav Das558afec2015-05-31 17:12:48 -0700822 }
823
824 @Override
825 public void onError(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800826 log.warn("Failed to initialize port table on {}", deviceId);
827 }
828 }));
829 }
830
831 protected void processVlanTable() {
832 //table miss entry
833 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
834 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
835 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder().wipeDeferred();
836 treatment.transition(ACL_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(VLAN_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 vlan table on {}", deviceId);
850 }
851
852 @Override
853 public void onError(FlowRuleOperations ops) {
854 log.warn("Failed to initialize vlan table on {}", deviceId);
Saurav Das558afec2015-05-31 17:12:48 -0700855 }
856 }));
857 }
858
Saurav Das558afec2015-05-31 17:12:48 -0700859 protected void processTmacTable() {
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(BRIDGING_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(TMAC_TABLE).build();
873 ops = ops.add(rule);
874 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
875 @Override
876 public void onSuccess(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800877 log.info("Initialized tmac table on {}", deviceId);
Saurav Das558afec2015-05-31 17:12:48 -0700878 }
879
880 @Override
881 public void onError(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800882 log.warn("Failed to initialize tmac table on {}", deviceId);
Saurav Das558afec2015-05-31 17:12:48 -0700883 }
884 }));
885 }
886
Saurav Das558afec2015-05-31 17:12:48 -0700887 protected void processIpTable() {
888 //table miss entry
889 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
890 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
891 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das558afec2015-05-31 17:12:48 -0700892 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(UNICAST_ROUTING_TABLE).build();
901 ops = ops.add(rule);
902 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
903 @Override
904 public void onSuccess(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800905 log.info("Initialized IP table on {}", deviceId);
Saurav Das558afec2015-05-31 17:12:48 -0700906 }
907
908 @Override
909 public void onError(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800910 log.warn("Failed to initialize unicast IP table on {}", deviceId);
Saurav Das558afec2015-05-31 17:12:48 -0700911 }
912 }));
913 }
914
Jonathan Hart855179c2016-04-26 07:40:04 -0700915 protected void processMulticastIpTable() {
916 //table miss entry
917 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
918 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
919 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
920 treatment.transition(ACL_TABLE);
921 FlowRule rule = DefaultFlowRule.builder()
922 .forDevice(deviceId)
923 .withSelector(selector.build())
924 .withTreatment(treatment.build())
925 .withPriority(LOWEST_PRIORITY)
926 .fromApp(driverId)
927 .makePermanent()
928 .forTable(MULTICAST_ROUTING_TABLE).build();
929 ops = ops.add(rule);
930 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
931 @Override
932 public void onSuccess(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800933 log.info("Initialized multicast IP table on {}", deviceId);
Jonathan Hart855179c2016-04-26 07:40:04 -0700934 }
935
936 @Override
937 public void onError(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800938 log.warn("Failed to initialize multicast IP table on {}", deviceId);
Jonathan Hart855179c2016-04-26 07:40:04 -0700939 }
940 }));
941 }
942
Saurav Das2857f382015-11-03 14:39:27 -0800943 protected void processMplsTable() {
944 //table miss entry
945 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
946 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
947 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
948 selector = DefaultTrafficSelector.builder();
949 treatment = DefaultTrafficTreatment.builder();
950 treatment.transition(MPLS_TABLE_1);
951 FlowRule rule = DefaultFlowRule.builder()
952 .forDevice(deviceId)
953 .withSelector(selector.build())
954 .withTreatment(treatment.build())
955 .withPriority(LOWEST_PRIORITY)
956 .fromApp(driverId)
957 .makePermanent()
958 .forTable(MPLS_TABLE_0).build();
959 ops = ops.add(rule);
960
961 treatment.transition(ACL_TABLE);
962 rule = DefaultFlowRule.builder()
963 .forDevice(deviceId)
964 .withSelector(selector.build())
965 .withTreatment(treatment.build())
966 .withPriority(LOWEST_PRIORITY)
967 .fromApp(driverId)
968 .makePermanent()
969 .forTable(MPLS_TABLE_1).build();
970 ops = ops.add(rule);
971
972 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
973 @Override
974 public void onSuccess(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800975 log.info("Initialized MPLS tables on {}", deviceId);
Saurav Das2857f382015-11-03 14:39:27 -0800976 }
977
978 @Override
979 public void onError(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -0800980 log.warn("Failed to initialize MPLS tables on {}", deviceId);
Saurav Das2857f382015-11-03 14:39:27 -0800981 }
982 }));
983 }
984
Saurav Das558afec2015-05-31 17:12:48 -0700985 private void processBridgingTable() {
986 //table miss entry
987 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
988 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
989 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das558afec2015-05-31 17:12:48 -0700990 treatment.transition(ACL_TABLE);
991 FlowRule rule = DefaultFlowRule.builder()
992 .forDevice(deviceId)
993 .withSelector(selector.build())
994 .withTreatment(treatment.build())
995 .withPriority(LOWEST_PRIORITY)
996 .fromApp(driverId)
997 .makePermanent()
998 .forTable(BRIDGING_TABLE).build();
999 ops = ops.add(rule);
1000 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
1001 @Override
1002 public void onSuccess(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -08001003 log.info("Initialized Bridging table on {}", deviceId);
Saurav Das558afec2015-05-31 17:12:48 -07001004 }
1005
1006 @Override
1007 public void onError(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -08001008 log.warn("Failed to initialize Bridging table on {}", deviceId);
Saurav Das558afec2015-05-31 17:12:48 -07001009 }
1010 }));
Saurav Das337c7a42015-06-02 15:12:06 -07001011 }
Saurav Das558afec2015-05-31 17:12:48 -07001012
Saurav Dasa07f2032015-10-19 14:37:36 -07001013 protected void processAclTable() {
Saurav Das337c7a42015-06-02 15:12:06 -07001014 //table miss entry - catch all to executed action-set
1015 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
1016 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
1017 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Saurav Das337c7a42015-06-02 15:12:06 -07001018 FlowRule rule = DefaultFlowRule.builder()
1019 .forDevice(deviceId)
1020 .withSelector(selector.build())
1021 .withTreatment(treatment.build())
1022 .withPriority(LOWEST_PRIORITY)
1023 .fromApp(driverId)
1024 .makePermanent()
1025 .forTable(ACL_TABLE).build();
1026 ops = ops.add(rule);
1027 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
1028 @Override
1029 public void onSuccess(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -08001030 log.info("Initialized Acl table on {}", deviceId);
Saurav Das337c7a42015-06-02 15:12:06 -07001031 }
1032
1033 @Override
1034 public void onError(FlowRuleOperations ops) {
Charles Chanb7504392017-02-10 12:51:04 -08001035 log.warn("Failed to initialize Acl table on {}", deviceId);
Saurav Das337c7a42015-06-02 15:12:06 -07001036 }
1037 }));
Saurav Das558afec2015-05-31 17:12:48 -07001038 }
1039
1040}