Saurav Das
Committed by Ray Milkey

Fixing emulated ofdpa in cpqd switches. Due to cpqd bugs in dealing with Vlans a…

…nd MPLS labels simultaneously,
we cannot emulate correct behavior in the same driver. This checkin separates the emulation, with one
driver meant for MPLS with untagged packets, and the other meant for untagged/tagged VLAN packets without MPLS.

Change-Id: Ia6112f4d26c7b32c93e1db2e9b1ae4673c553d87
...@@ -26,6 +26,7 @@ import java.util.Set; ...@@ -26,6 +26,7 @@ import java.util.Set;
26 import java.util.concurrent.ConcurrentHashMap; 26 import java.util.concurrent.ConcurrentHashMap;
27 27
28 import org.onlab.packet.Ethernet; 28 import org.onlab.packet.Ethernet;
29 +import org.onlab.packet.MacAddress;
29 import org.onlab.packet.VlanId; 30 import org.onlab.packet.VlanId;
30 import org.onosproject.core.ApplicationId; 31 import org.onosproject.core.ApplicationId;
31 import org.onosproject.net.Port; 32 import org.onosproject.net.Port;
...@@ -49,6 +50,9 @@ import org.onosproject.net.flow.criteria.MplsCriterion; ...@@ -49,6 +50,9 @@ import org.onosproject.net.flow.criteria.MplsCriterion;
49 import org.onosproject.net.flow.criteria.PortCriterion; 50 import org.onosproject.net.flow.criteria.PortCriterion;
50 import org.onosproject.net.flow.criteria.VlanIdCriterion; 51 import org.onosproject.net.flow.criteria.VlanIdCriterion;
51 import org.onosproject.net.flow.instructions.Instruction; 52 import org.onosproject.net.flow.instructions.Instruction;
53 +import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
54 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
55 +import org.onosproject.net.flowobjective.FilteringObjective;
52 import org.onosproject.net.flowobjective.ForwardingObjective; 56 import org.onosproject.net.flowobjective.ForwardingObjective;
53 import org.onosproject.net.flowobjective.ObjectiveError; 57 import org.onosproject.net.flowobjective.ObjectiveError;
54 import org.onosproject.net.group.Group; 58 import org.onosproject.net.group.Group;
...@@ -58,13 +62,152 @@ import org.slf4j.Logger; ...@@ -58,13 +62,152 @@ import org.slf4j.Logger;
58 62
59 /** 63 /**
60 * Driver for software switch emulation of the OFDPA 2.0 pipeline. 64 * Driver for software switch emulation of the OFDPA 2.0 pipeline.
61 - * The software switch is the CPqD OF 1.3 switch. 65 + * The software switch is the CPqD OF 1.3 switch. Unfortunately the CPqD switch
66 + * does not handle vlan tags and mpls labels simultaneously, which requires us
67 + * to do some workarounds in the driver. This driver is meant for the use of
68 + * the cpqd switch when MPLS is required. As a result this driver works only
69 + * on incoming untagged packets.
62 */ 70 */
63 public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { 71 public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline {
64 72
65 private final Logger log = getLogger(getClass()); 73 private final Logger log = getLogger(getClass());
66 74
67 /* 75 /*
76 + * CPQD emulation does not require special untagged packet handling, unlike
77 + * the real ofdpa.
78 + */
79 + @Override
80 + protected void processFilter(FilteringObjective filt,
81 + boolean install, ApplicationId applicationId) {
82 + // This driver only processes filtering criteria defined with switch
83 + // ports as the key
84 + PortCriterion portCriterion = null;
85 + EthCriterion ethCriterion = null;
86 + VlanIdCriterion vidCriterion = null;
87 + Collection<IPCriterion> ips = new ArrayList<IPCriterion>();
88 + if (!filt.key().equals(Criteria.dummy()) &&
89 + filt.key().type() == Criterion.Type.IN_PORT) {
90 + portCriterion = (PortCriterion) filt.key();
91 + } else {
92 + log.warn("No key defined in filtering objective from app: {}. Not"
93 + + "processing filtering objective", applicationId);
94 + fail(filt, ObjectiveError.UNKNOWN);
95 + return;
96 + }
97 + // convert filtering conditions for switch-intfs into flowrules
98 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
99 + for (Criterion criterion : filt.conditions()) {
100 + if (criterion.type() == Criterion.Type.ETH_DST) {
101 + ethCriterion = (EthCriterion) criterion;
102 + } else if (criterion.type() == Criterion.Type.VLAN_VID) {
103 + vidCriterion = (VlanIdCriterion) criterion;
104 + } else if (criterion.type() == Criterion.Type.IPV4_DST) {
105 + ips.add((IPCriterion) criterion);
106 + } else {
107 + log.error("Unsupported filter {}", criterion);
108 + fail(filt, ObjectiveError.UNSUPPORTED);
109 + return;
110 + }
111 + }
112 +
113 + VlanId assignedVlan = null;
114 + // For VLAN cross-connect packets, use the configured VLAN
115 + if (vidCriterion != null) {
116 + if (vidCriterion.vlanId() != VlanId.NONE) {
117 + assignedVlan = vidCriterion.vlanId();
118 +
119 + // For untagged packets, assign a VLAN ID
120 + } else {
121 + if (filt.meta() == null) {
122 + log.error("Missing metadata in filtering objective required " +
123 + "for vlan assignment in dev {}", deviceId);
124 + fail(filt, ObjectiveError.BADPARAMS);
125 + return;
126 + }
127 + for (Instruction i : filt.meta().allInstructions()) {
128 + if (i instanceof ModVlanIdInstruction) {
129 + assignedVlan = ((ModVlanIdInstruction) i).vlanId();
130 + }
131 + }
132 + if (assignedVlan == null) {
133 + log.error("Driver requires an assigned vlan-id to tag incoming "
134 + + "untagged packets. Not processing vlan filters on "
135 + + "device {}", deviceId);
136 + fail(filt, ObjectiveError.BADPARAMS);
137 + return;
138 + }
139 + }
140 + }
141 +
142 + if (ethCriterion == null || ethCriterion.mac().equals(MacAddress.NONE)) {
143 + log.debug("filtering objective missing dstMac, cannot program TMAC table");
144 + } else {
145 + for (FlowRule tmacRule : processEthDstFilter(portCriterion, ethCriterion,
146 + vidCriterion, assignedVlan,
147 + applicationId)) {
148 + log.debug("adding MAC filtering rules in TMAC table: {} for dev: {}",
149 + tmacRule, deviceId);
150 + ops = install ? ops.add(tmacRule) : ops.remove(tmacRule);
151 + }
152 + }
153 +
154 + if (ethCriterion == null || vidCriterion == null) {
155 + log.debug("filtering objective missing dstMac or VLAN, "
156 + + "cannot program VLAN Table");
157 + } else {
158 + List<FlowRule> allRules = processVlanIdFilter(
159 + portCriterion, vidCriterion, assignedVlan, applicationId);
160 + for (FlowRule rule : allRules) {
161 + log.debug("adding VLAN filtering rule in VLAN table: {} for dev: {}",
162 + rule, deviceId);
163 + ops = install ? ops.add(rule) : ops.remove(rule);
164 + }
165 + }
166 +
167 + for (IPCriterion ipaddr : ips) {
168 + // since we ignore port information for IP rules, and the same (gateway) IP
169 + // can be configured on multiple ports, we make sure that we send
170 + // only a single rule to the switch.
171 + if (!sentIpFilters.contains(ipaddr)) {
172 + sentIpFilters.add(ipaddr);
173 + log.debug("adding IP filtering rules in ACL table {} for dev: {}",
174 + ipaddr, deviceId);
175 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
176 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
177 + selector.matchEthType(Ethernet.TYPE_IPV4);
178 + selector.matchIPDst(ipaddr.ip());
179 + treatment.setOutput(PortNumber.CONTROLLER);
180 + FlowRule rule = DefaultFlowRule.builder()
181 + .forDevice(deviceId)
182 + .withSelector(selector.build())
183 + .withTreatment(treatment.build())
184 + .withPriority(HIGHEST_PRIORITY)
185 + .fromApp(applicationId)
186 + .makePermanent()
187 + .forTable(ACL_TABLE).build();
188 + ops = install ? ops.add(rule) : ops.remove(rule);
189 + }
190 + }
191 +
192 + // apply filtering flow rules
193 + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
194 + @Override
195 + public void onSuccess(FlowRuleOperations ops) {
196 + log.info("Applied {} filtering rules in device {}",
197 + ops.stages().get(0).size(), deviceId);
198 + pass(filt);
199 + }
200 +
201 + @Override
202 + public void onError(FlowRuleOperations ops) {
203 + log.info("Failed to apply all filtering rules in dev {}", deviceId);
204 + fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
205 + }
206 + }));
207 +
208 + }
209 +
210 + /*
68 * Cpqd emulation does not require the non-OF standard rules for 211 * Cpqd emulation does not require the non-OF standard rules for
69 * matching untagged packets. 212 * matching untagged packets.
70 * 213 *
...@@ -297,6 +440,89 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { ...@@ -297,6 +440,89 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline {
297 return Collections.singletonList(ruleBuilder.build()); 440 return Collections.singletonList(ruleBuilder.build());
298 } 441 }
299 442
443 + /*
444 + * In the OF-DPA 2.0 pipeline, versatile forwarding objectives go to the
445 + * ACL table. Because we pop off vlan tags in TMAC table,
446 + * we need to avoid matching on vlans in the ACL table.
447 + */
448 + @Override
449 + protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
450 + log.info("Processing versatile forwarding objective");
451 +
452 + EthTypeCriterion ethType =
453 + (EthTypeCriterion) fwd.selector().getCriterion(Criterion.Type.ETH_TYPE);
454 + if (ethType == null) {
455 + log.error("Versatile forwarding objective must include ethType");
456 + fail(fwd, ObjectiveError.BADPARAMS);
457 + return Collections.emptySet();
458 + }
459 + if (fwd.nextId() == null && fwd.treatment() == null) {
460 + log.error("Forwarding objective {} from {} must contain "
461 + + "nextId or Treatment", fwd.selector(), fwd.appId());
462 + return Collections.emptySet();
463 + }
464 +
465 + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
466 + fwd.selector().criteria().forEach(criterion -> {
467 + if (criterion instanceof VlanIdCriterion) {
468 + // avoid matching on vlans
469 + return;
470 + } else {
471 + sbuilder.add(criterion);
472 + }
473 + });
474 +
475 + // XXX driver does not currently do type checking as per Tables 65-67 in
476 + // OFDPA 2.0 spec. The only allowed treatment is a punt to the controller.
477 + TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
478 + if (fwd.treatment() != null) {
479 + for (Instruction ins : fwd.treatment().allInstructions()) {
480 + if (ins instanceof OutputInstruction) {
481 + OutputInstruction o = (OutputInstruction) ins;
482 + if (o.port() == PortNumber.CONTROLLER) {
483 + ttBuilder.add(o);
484 + } else {
485 + log.warn("Only allowed treatments in versatile forwarding "
486 + + "objectives are punts to the controller");
487 + }
488 + } else {
489 + log.warn("Cannot process instruction in versatile fwd {}", ins);
490 + }
491 + }
492 + }
493 + if (fwd.nextId() != null) {
494 + // overide case
495 + NextGroup next = getGroupForNextObjective(fwd.nextId());
496 + List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
497 + // we only need the top level group's key to point the flow to it
498 + Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
499 + if (group == null) {
500 + log.warn("Group with key:{} for next-id:{} not found in dev:{}",
501 + gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
502 + fail(fwd, ObjectiveError.GROUPMISSING);
503 + return Collections.emptySet();
504 + }
505 + ttBuilder.deferred().group(group.id());
506 + }
507 +
508 + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
509 + .fromApp(fwd.appId())
510 + .withPriority(fwd.priority())
511 + .forDevice(deviceId)
512 + .withSelector(sbuilder.build())
513 + .withTreatment(ttBuilder.build())
514 + .makePermanent()
515 + .forTable(ACL_TABLE);
516 + return Collections.singletonList(ruleBuilder.build());
517 + }
518 +
519 + /*
520 + * Cpqd emulation requires table-miss-entries in forwarding tables.
521 + * Real OFDPA does not require these rules as they are put in by default.
522 + *
523 + * (non-Javadoc)
524 + * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#initializePipeline()
525 + */
300 @Override 526 @Override
301 protected void initializePipeline() { 527 protected void initializePipeline() {
302 processPortTable(); 528 processPortTable();
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.driver.pipeline;
17 +
18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import java.util.ArrayList;
21 +import java.util.Collection;
22 +import java.util.Collections;
23 +import java.util.Deque;
24 +import java.util.List;
25 +import org.onlab.packet.Ethernet;
26 +import org.onlab.packet.VlanId;
27 +import org.onosproject.core.ApplicationId;
28 +import org.onosproject.net.Port;
29 +import org.onosproject.net.PortNumber;
30 +import org.onosproject.net.behaviour.NextGroup;
31 +import org.onosproject.net.flow.DefaultFlowRule;
32 +import org.onosproject.net.flow.DefaultTrafficSelector;
33 +import org.onosproject.net.flow.DefaultTrafficTreatment;
34 +import org.onosproject.net.flow.FlowRule;
35 +import org.onosproject.net.flow.TrafficSelector;
36 +import org.onosproject.net.flow.TrafficTreatment;
37 +import org.onosproject.net.flow.criteria.Criteria;
38 +import org.onosproject.net.flow.criteria.Criterion;
39 +import org.onosproject.net.flow.criteria.EthCriterion;
40 +import org.onosproject.net.flow.criteria.EthTypeCriterion;
41 +import org.onosproject.net.flow.criteria.PortCriterion;
42 +import org.onosproject.net.flow.criteria.VlanIdCriterion;
43 +import org.onosproject.net.flow.instructions.Instruction;
44 +import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
45 +import org.onosproject.net.flowobjective.ForwardingObjective;
46 +import org.onosproject.net.flowobjective.ObjectiveError;
47 +import org.onosproject.net.group.Group;
48 +import org.onosproject.net.group.GroupKey;
49 +import org.slf4j.Logger;
50 +
51 +
52 +/**
53 + * Driver for software switch emulation of the OFDPA 2.0 pipeline.
54 + * The software switch is the CPqD OF 1.3 switch. Unfortunately the CPqD switch
55 + * does not handle vlan tags and mpls labels simultaneously, which requires us
56 + * to do some workarounds in the driver. This driver is meant for the use of
57 + * the cpqd switch when MPLS is not a requirement from the ofdpa pipeline. As a
58 + * result this driver correctly handles both incoming untagged and vlan-tagged
59 + * packets.
60 + *
61 + */
62 +public class CpqdOFDPA2VlanPipeline extends CpqdOFDPA2Pipeline {
63 +
64 + private final Logger log = getLogger(getClass());
65 +
66 + /*
67 + * Cpqd emulation does not handle vlan tags and mpls labels correctly.
68 + * Since this driver does not deal with MPLS, there is no need for
69 + * working around VLAN tags. In particular we do not pop off vlan tags in
70 + * the middle of the pipeline.
71 + *
72 + * (non-Javadoc)
73 + * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthDstFilter
74 + */
75 + @Override
76 + protected List<FlowRule> processEthDstFilter(PortCriterion portCriterion,
77 + EthCriterion ethCriterion,
78 + VlanIdCriterion vidCriterion,
79 + VlanId assignedVlan,
80 + ApplicationId applicationId) {
81 + //handling untagged packets via assigned VLAN
82 + if (vidCriterion.vlanId() == VlanId.NONE) {
83 + vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan);
84 + }
85 + // ofdpa cannot match on ALL portnumber, so we need to use separate
86 + // rules for each port.
87 + List<PortNumber> portnums = new ArrayList<PortNumber>();
88 + if (portCriterion.port() == PortNumber.ALL) {
89 + for (Port port : deviceService.getPorts(deviceId)) {
90 + if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
91 + portnums.add(port.number());
92 + }
93 + }
94 + } else {
95 + portnums.add(portCriterion.port());
96 + }
97 +
98 + List<FlowRule> rules = new ArrayList<FlowRule>();
99 + for (PortNumber pnum : portnums) {
100 + // for unicast IP packets
101 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
102 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
103 + selector.matchInPort(pnum);
104 + selector.matchVlanId(vidCriterion.vlanId());
105 + selector.matchEthType(Ethernet.TYPE_IPV4);
106 + selector.matchEthDst(ethCriterion.mac());
107 +
108 + treatment.transition(UNICAST_ROUTING_TABLE);
109 + FlowRule rule = DefaultFlowRule.builder()
110 + .forDevice(deviceId)
111 + .withSelector(selector.build())
112 + .withTreatment(treatment.build())
113 + .withPriority(DEFAULT_PRIORITY)
114 + .fromApp(applicationId)
115 + .makePermanent()
116 + .forTable(TMAC_TABLE).build();
117 + rules.add(rule);
118 + }
119 + return rules;
120 + }
121 +
122 + /*
123 + * In the OF-DPA 2.0 pipeline, versatile forwarding objectives go to the
124 + * ACL table. Since we do not pop off vlans in the TMAC table we can continue
125 + * to match on vlans in the ACL table if necessary.
126 + */
127 + @Override
128 + protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
129 + log.info("Processing versatile forwarding objective");
130 +
131 + EthTypeCriterion ethType =
132 + (EthTypeCriterion) fwd.selector().getCriterion(Criterion.Type.ETH_TYPE);
133 + if (ethType == null) {
134 + log.error("Versatile forwarding objective must include ethType");
135 + fail(fwd, ObjectiveError.BADPARAMS);
136 + return Collections.emptySet();
137 + }
138 + if (fwd.nextId() == null && fwd.treatment() == null) {
139 + log.error("Forwarding objective {} from {} must contain "
140 + + "nextId or Treatment", fwd.selector(), fwd.appId());
141 + return Collections.emptySet();
142 + }
143 +
144 + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
145 + fwd.selector().criteria().forEach(criterion -> {
146 + if (criterion instanceof VlanIdCriterion) {
147 + VlanId vlanId = ((VlanIdCriterion) criterion).vlanId();
148 + // ensure that match does not include vlan = NONE as OF-DPA does not
149 + // match untagged packets this way in the ACL table.
150 + if (vlanId.equals(VlanId.NONE)) {
151 + return;
152 + }
153 + }
154 + sbuilder.add(criterion);
155 + });
156 +
157 + // XXX driver does not currently do type checking as per Tables 65-67 in
158 + // OFDPA 2.0 spec. The only allowed treatment is a punt to the controller.
159 + TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
160 + if (fwd.treatment() != null) {
161 + for (Instruction ins : fwd.treatment().allInstructions()) {
162 + if (ins instanceof OutputInstruction) {
163 + OutputInstruction o = (OutputInstruction) ins;
164 + if (o.port() == PortNumber.CONTROLLER) {
165 + ttBuilder.add(o);
166 + } else {
167 + log.warn("Only allowed treatments in versatile forwarding "
168 + + "objectives are punts to the controller");
169 + }
170 + } else {
171 + log.warn("Cannot process instruction in versatile fwd {}", ins);
172 + }
173 + }
174 + }
175 + if (fwd.nextId() != null) {
176 + // overide case
177 + NextGroup next = getGroupForNextObjective(fwd.nextId());
178 + List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
179 + // we only need the top level group's key to point the flow to it
180 + Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
181 + if (group == null) {
182 + log.warn("Group with key:{} for next-id:{} not found in dev:{}",
183 + gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
184 + fail(fwd, ObjectiveError.GROUPMISSING);
185 + return Collections.emptySet();
186 + }
187 + ttBuilder.deferred().group(group.id());
188 + }
189 +
190 + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
191 + .fromApp(fwd.appId())
192 + .withPriority(fwd.priority())
193 + .forDevice(deviceId)
194 + .withSelector(sbuilder.build())
195 + .withTreatment(ttBuilder.build())
196 + .makePermanent()
197 + .forTable(ACL_TABLE);
198 + return Collections.singletonList(ruleBuilder.build());
199 + }
200 +
201 +
202 +}
...@@ -101,7 +101,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ...@@ -101,7 +101,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
101 protected static final int MAC_LEARNING_TABLE = 254; 101 protected static final int MAC_LEARNING_TABLE = 254;
102 protected static final long OFPP_MAX = 0xffffff00L; 102 protected static final long OFPP_MAX = 0xffffff00L;
103 103
104 - private static final int HIGHEST_PRIORITY = 0xffff; 104 + protected static final int HIGHEST_PRIORITY = 0xffff;
105 protected static final int DEFAULT_PRIORITY = 0x8000; 105 protected static final int DEFAULT_PRIORITY = 0x8000;
106 protected static final int LOWEST_PRIORITY = 0x0; 106 protected static final int LOWEST_PRIORITY = 0x0;
107 107
...@@ -125,7 +125,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ...@@ -125,7 +125,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
125 125
126 protected OFDPA2GroupHandler ofdpa2GroupHandler; 126 protected OFDPA2GroupHandler ofdpa2GroupHandler;
127 127
128 - private Set<IPCriterion> sentIpFilters = Collections.newSetFromMap( 128 + protected Set<IPCriterion> sentIpFilters = Collections.newSetFromMap(
129 new ConcurrentHashMap<>()); 129 new ConcurrentHashMap<>());
130 130
131 @Override 131 @Override
...@@ -276,7 +276,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ...@@ -276,7 +276,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
276 * @param install indicates whether to add or remove the objective 276 * @param install indicates whether to add or remove the objective
277 * @param applicationId the application that sent this objective 277 * @param applicationId the application that sent this objective
278 */ 278 */
279 - private void processFilter(FilteringObjective filt, 279 + protected void processFilter(FilteringObjective filt,
280 boolean install, ApplicationId applicationId) { 280 boolean install, ApplicationId applicationId) {
281 // This driver only processes filtering criteria defined with switch 281 // This driver only processes filtering criteria defined with switch
282 // ports as the key 282 // ports as the key
...@@ -357,7 +357,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ...@@ -357,7 +357,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
357 /* 357 /*
358 * NOTE: Separate vlan filtering rules and assignment rules 358 * NOTE: Separate vlan filtering rules and assignment rules
359 * into different stage in order to guarantee that filtering rules 359 * into different stage in order to guarantee that filtering rules
360 - * always go first. 360 + * always go first, as required by ofdpa.
361 */ 361 */
362 List<FlowRule> allRules = processVlanIdFilter( 362 List<FlowRule> allRules = processVlanIdFilter(
363 portCriterion, vidCriterion, assignedVlan, applicationId); 363 portCriterion, vidCriterion, assignedVlan, applicationId);
...@@ -464,9 +464,11 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ...@@ -464,9 +464,11 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
464 selector.extension(ofdpaMatchVlanVid, deviceId); 464 selector.extension(ofdpaMatchVlanVid, deviceId);
465 OfdpaSetVlanVid ofdpaSetVlanVid = new OfdpaSetVlanVid(assignedVlan); 465 OfdpaSetVlanVid ofdpaSetVlanVid = new OfdpaSetVlanVid(assignedVlan);
466 treatment.extension(ofdpaSetVlanVid, deviceId); 466 treatment.extension(ofdpaSetVlanVid, deviceId);
467 - // XXX ofdpa will require an additional vlan match on the assigned vlan 467 + // ofdpa requires an additional vlan match rule for the assigned vlan
468 - // and it may not require the push. This is not in compliance with OF 468 + // and it does not require the push when setting the assigned vlan.
469 - // standard. Waiting on what the exact flows are going to look like. 469 + // It also requires the extra rule to be sent to the switch before we
470 + // send the untagged match rule.
471 + // None of this in compliance with OF standard.
470 storeVlan = assignedVlan; 472 storeVlan = assignedVlan;
471 473
472 preSelector = DefaultTrafficSelector.builder(); 474 preSelector = DefaultTrafficSelector.builder();
...@@ -630,7 +632,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ...@@ -630,7 +632,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
630 * collection may be returned if there is a problem in processing 632 * collection may be returned if there is a problem in processing
631 * the flow rule 633 * the flow rule
632 */ 634 */
633 - private Collection<FlowRule> processVersatile(ForwardingObjective fwd) { 635 + protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
634 log.info("Processing versatile forwarding objective"); 636 log.info("Processing versatile forwarding objective");
635 637
636 EthTypeCriterion ethType = 638 EthTypeCriterion ethType =
......
...@@ -141,6 +141,7 @@ ...@@ -141,6 +141,7 @@
141 manufacturer="NoviFlow Inc" hwVersion="NS.*" swVersion="NW.*"> 141 manufacturer="NoviFlow Inc" hwVersion="NS.*" swVersion="NW.*">
142 </driver> 142 </driver>
143 <!-- Emulation of the ofdpa pipeline using a CPqD OF 1.3 software switch. 143 <!-- Emulation of the ofdpa pipeline using a CPqD OF 1.3 software switch.
144 + ~ Use this driver when MPLS functionality is required.
144 ~ To use this driver, configure ONOS with the dpid of the device. 145 ~ To use this driver, configure ONOS with the dpid of the device.
145 --> 146 -->
146 <driver name="ofdpa-cpqd" extends="default" 147 <driver name="ofdpa-cpqd" extends="default"
...@@ -149,6 +150,16 @@ ...@@ -149,6 +150,16 @@
149 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 150 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
150 impl="org.onosproject.driver.pipeline.CpqdOFDPA2Pipeline"/> 151 impl="org.onosproject.driver.pipeline.CpqdOFDPA2Pipeline"/>
151 </driver> 152 </driver>
153 + <!-- Emulation of the ofdpa pipeline using a CPqD OF 1.3 software switch.
154 + ~ Use this driver when VLAN functionality is required.
155 + ~ To use this driver, configure ONOS with the dpid of the device.
156 + -->
157 + <driver name="ofdpa-cpqd-vlan" extends="default"
158 + manufacturer="ONF"
159 + hwVersion="OF1.3 Software Switch from CPqD" swVersion="for Group Chaining">
160 + <behaviour api="org.onosproject.net.behaviour.Pipeliner"
161 + impl="org.onosproject.driver.pipeline.CpqdOFDPA2VlanPipeline"/>
162 + </driver>
152 <driver name="calient" extends="default" 163 <driver name="calient" extends="default"
153 manufacturer="calient inc" hwVersion="calient hardware" 164 manufacturer="calient inc" hwVersion="calient hardware"
154 swVersion="ocs switch"> 165 swVersion="ocs switch">
......