Jonathan Gravel
Committed by Gerrit Code Review

Add driver support for Corsa Pipeline V3

Change-Id: If5c1aa9cec6093e3c9f2f908de6066957d9ad8fd
...@@ -15,13 +15,17 @@ ...@@ -15,13 +15,17 @@
15 */ 15 */
16 package org.onosproject.driver.handshaker; 16 package org.onosproject.driver.handshaker;
17 17
18 +import org.onosproject.net.meter.MeterId;
18 import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; 19 import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
19 import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted; 20 import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
20 import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted; 21 import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
21 import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted; 22 import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
22 import org.projectfloodlight.openflow.protocol.OFBarrierRequest; 23 import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
23 import org.projectfloodlight.openflow.protocol.OFFlowMod; 24 import org.projectfloodlight.openflow.protocol.OFFlowMod;
25 +import org.projectfloodlight.openflow.protocol.OFGroupMod;
26 +import org.projectfloodlight.openflow.protocol.OFGroupType;
24 import org.projectfloodlight.openflow.protocol.OFMessage; 27 import org.projectfloodlight.openflow.protocol.OFMessage;
28 +import org.projectfloodlight.openflow.protocol.OFMeterMod;
25 import org.projectfloodlight.openflow.protocol.OFType; 29 import org.projectfloodlight.openflow.protocol.OFType;
26 import org.projectfloodlight.openflow.types.OFGroup; 30 import org.projectfloodlight.openflow.types.OFGroup;
27 import org.projectfloodlight.openflow.types.TableId; 31 import org.projectfloodlight.openflow.types.TableId;
...@@ -58,6 +62,19 @@ public class CorsaSwitchHandshaker extends AbstractOpenFlowSwitch { ...@@ -58,6 +62,19 @@ public class CorsaSwitchHandshaker extends AbstractOpenFlowSwitch {
58 62
59 sendMsg(Collections.singletonList(fm)); 63 sendMsg(Collections.singletonList(fm));
60 64
65 + OFGroupMod gm = factory().buildGroupDelete()
66 + .setGroup(OFGroup.ALL)
67 + .setGroupType(OFGroupType.ALL)
68 + .build();
69 +
70 + sendMsg(Collections.singletonList(gm));
71 +
72 + OFMeterMod mm = factory().buildMeterMod()
73 + .setMeterId(MeterId.ALL.id())
74 + .build();
75 +
76 + sendMsg(Collections.singletonList(mm));
77 +
61 barrierXid = getNextTransactionId(); 78 barrierXid = getNextTransactionId();
62 OFBarrierRequest barrier = factory().buildBarrierRequest() 79 OFBarrierRequest barrier = factory().buildBarrierRequest()
63 .setXid(barrierXid).build(); 80 .setXid(barrierXid).build();
......
...@@ -26,8 +26,13 @@ import org.onosproject.net.flow.FlowRuleOperations; ...@@ -26,8 +26,13 @@ import org.onosproject.net.flow.FlowRuleOperations;
26 import org.onosproject.net.flow.FlowRuleOperationsContext; 26 import org.onosproject.net.flow.FlowRuleOperationsContext;
27 import org.onosproject.net.flow.TrafficSelector; 27 import org.onosproject.net.flow.TrafficSelector;
28 import org.onosproject.net.flow.TrafficTreatment; 28 import org.onosproject.net.flow.TrafficTreatment;
29 +import org.onosproject.net.flowobjective.ForwardingObjective;
30 +import org.onosproject.net.flowobjective.ObjectiveError;
29 import org.slf4j.Logger; 31 import org.slf4j.Logger;
30 32
33 +import java.util.Collection;
34 +import java.util.Collections;
35 +
31 /** 36 /**
32 * Driver for Corsa TTP. 37 * Driver for Corsa TTP.
33 * 38 *
...@@ -70,7 +75,14 @@ public class CorsaPipeline extends OVSCorsaPipeline { ...@@ -70,7 +75,14 @@ public class CorsaPipeline extends OVSCorsaPipeline {
70 "Failed to provision vlan/mpls table"); 75 "Failed to provision vlan/mpls table");
71 } 76 }
72 })); 77 }));
78 + }
73 79
80 + @Override
81 + protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
82 + /* Not supported by until CorsaPipelineV3 */
83 + log.warn("Vlan switching not supported in corsa-v1 driver");
84 + fail(fwd, ObjectiveError.UNSUPPORTED);
85 + return Collections.emptySet();
74 } 86 }
75 87
76 } 88 }
......
1 +package org.onosproject.driver.pipeline;
2 +
3 +import org.onlab.packet.Ethernet;
4 +import org.onlab.packet.MacAddress;
5 +import org.onlab.packet.VlanId;
6 +import org.onosproject.core.ApplicationId;
7 +import org.onosproject.net.flow.DefaultFlowRule;
8 +import org.onosproject.net.flow.DefaultTrafficSelector;
9 +import org.onosproject.net.flow.DefaultTrafficTreatment;
10 +import org.onosproject.net.flow.FlowRule;
11 +import org.onosproject.net.flow.FlowRuleOperations;
12 +import org.onosproject.net.flow.FlowRuleOperationsContext;
13 +import org.onosproject.net.flow.TrafficSelector;
14 +import org.onosproject.net.flow.TrafficTreatment;
15 +import org.onosproject.net.flow.criteria.Criteria;
16 +import org.onosproject.net.flow.criteria.Criterion;
17 +import org.onosproject.net.flow.criteria.EthCriterion;
18 +import org.onosproject.net.flow.criteria.IPCriterion;
19 +import org.onosproject.net.flow.criteria.PortCriterion;
20 +import org.onosproject.net.flow.criteria.VlanIdCriterion;
21 +import org.onosproject.net.flow.instructions.Instructions;
22 +import org.onosproject.net.flow.instructions.L2ModificationInstruction;
23 +import org.onosproject.net.flowobjective.FilteringObjective;
24 +import org.onosproject.net.flowobjective.ForwardingObjective;
25 +import org.onosproject.net.flowobjective.ObjectiveError;
26 +import org.onosproject.net.meter.Band;
27 +import org.onosproject.net.meter.DefaultBand;
28 +import org.onosproject.net.meter.DefaultMeterRequest;
29 +import org.onosproject.net.meter.Meter;
30 +import org.onosproject.net.meter.MeterId;
31 +import org.onosproject.net.meter.MeterRequest;
32 +import org.slf4j.Logger;
33 +
34 +import java.util.Collection;
35 +import java.util.Collections;
36 +
37 +import static org.slf4j.LoggerFactory.getLogger;
38 +
39 +public class CorsaPipelineV3 extends OVSCorsaPipeline {
40 +
41 + private final Logger log = getLogger(getClass());
42 +
43 + protected static final int PORT_BASED_PROTO_TABLE = 0;
44 + protected static final int VLAN_CHECK_TABLE = 1;
45 + protected static final int VLAN_MAC_XLATE_TABLE = 2;
46 + protected static final int VLAN_CIRCUIT_TABLE = 3;
47 + protected static final int PRIORITY_MAP_TABLE = 4;
48 + protected static final int L3_IF_MAC_DA_TABLE = 5;
49 + protected static final int ETHER_TABLE = 6;
50 + protected static final int FIB_TABLE = 7;
51 + protected static final int LOCAL_TABLE = 9;
52 +
53 + protected static final byte MAX_VLAN_PCP = 7;
54 +
55 + private MeterId defaultMeterId = null;
56 +
57 + @Override
58 + protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
59 + TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
60 +
61 + treatment.immediate().stream()
62 + .filter(i -> i instanceof L2ModificationInstruction.ModVlanIdInstruction ||
63 + i instanceof L2ModificationInstruction.ModEtherInstruction ||
64 + i instanceof Instructions.OutputInstruction)
65 + .forEach(i -> tb.add(i));
66 + return tb.build();
67 + }
68 +
69 + @Override
70 + protected TrafficTreatment.Builder processSpecificRoutingTreatment() {
71 + return DefaultTrafficTreatment.builder().deferred();
72 + }
73 +
74 + @Override
75 + protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) {
76 + return rb.forTable(FIB_TABLE);
77 + }
78 +
79 + @Override
80 + protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
81 + TrafficSelector filteredSelector =
82 + DefaultTrafficSelector.builder()
83 + .matchInPort(
84 + ((PortCriterion) fwd.selector().getCriterion(Criterion.Type.IN_PORT)).port())
85 + .matchVlanId(
86 + ((VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID)).vlanId())
87 + .build();
88 +
89 + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
90 + .fromApp(fwd.appId())
91 + .withPriority(fwd.priority())
92 + .forDevice(deviceId)
93 + .withSelector(filteredSelector)
94 + .withTreatment(fwd.treatment())
95 + .forTable(VLAN_CIRCUIT_TABLE);
96 +
97 + if (fwd.permanent()) {
98 + ruleBuilder.makePermanent();
99 + } else {
100 + ruleBuilder.makeTemporary(fwd.timeout());
101 + }
102 +
103 + return Collections.singletonList(ruleBuilder.build());
104 + }
105 +
106 + @Override
107 + protected void processFilter(FilteringObjective filt, boolean install,
108 + ApplicationId applicationId) {
109 + // This driver only processes filtering criteria defined with switch
110 + // ports as the key
111 + PortCriterion p;
112 + if (!filt.key().equals(Criteria.dummy()) &&
113 + filt.key().type() == Criterion.Type.IN_PORT) {
114 + p = (PortCriterion) filt.key();
115 + } else {
116 + log.warn("No key defined in filtering objective from app: {}. Not"
117 + + "processing filtering objective", applicationId);
118 + fail(filt, ObjectiveError.UNKNOWN);
119 + return;
120 + }
121 + // convert filtering conditions for switch-intfs into flowrules
122 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
123 + for (Criterion c : filt.conditions()) {
124 + if (c.type() == Criterion.Type.ETH_DST) {
125 + EthCriterion e = (EthCriterion) c;
126 + log.debug("adding rule for MAC: {}", e.mac());
127 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
128 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
129 + selector.matchEthDst(e.mac());
130 + selector.matchInPort(p.port());
131 + treatment.transition(ETHER_TABLE);
132 + FlowRule rule = DefaultFlowRule.builder()
133 + .forDevice(deviceId)
134 + .withSelector(selector.build())
135 + .withTreatment(treatment.build())
136 + .withPriority(CONTROLLER_PRIORITY)
137 + .fromApp(applicationId)
138 + .makePermanent()
139 + .forTable(L3_IF_MAC_DA_TABLE).build();
140 + ops = install ? ops.add(rule) : ops.remove(rule);
141 + } else if (c.type() == Criterion.Type.VLAN_VID) {
142 + VlanIdCriterion v = (VlanIdCriterion) c;
143 + log.debug("adding rule for VLAN: {}", v.vlanId());
144 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
145 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
146 + selector.matchVlanId(v.vlanId());
147 + selector.matchInPort(p.port());
148 + /* Static treatment for VLAN_CIRCUIT_TABLE */
149 + treatment.setVlanPcp(MAX_VLAN_PCP);
150 + treatment.setQueue(0);
151 + treatment.meter(MeterId.meterId(defaultMeterId.id())); /* use default meter (Green) */
152 + treatment.transition(L3_IF_MAC_DA_TABLE);
153 + FlowRule rule = DefaultFlowRule.builder()
154 + .forDevice(deviceId)
155 + .withSelector(selector.build())
156 + .withTreatment(treatment.build())
157 + .withPriority(CONTROLLER_PRIORITY)
158 + .fromApp(applicationId)
159 + .makePermanent()
160 + .forTable(VLAN_CIRCUIT_TABLE).build();
161 + ops = install ? ops.add(rule) : ops.remove(rule);
162 + } else if (c.type() == Criterion.Type.IPV4_DST) {
163 + IPCriterion ip = (IPCriterion) c;
164 + log.debug("adding rule for IP: {}", ip.ip());
165 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
166 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
167 + selector.matchEthType(Ethernet.TYPE_IPV4);
168 + selector.matchIPDst(ip.ip());
169 + treatment.transition(LOCAL_TABLE);
170 + FlowRule rule = DefaultFlowRule.builder()
171 + .forDevice(deviceId)
172 + .withSelector(selector.build())
173 + .withTreatment(treatment.build())
174 + .withPriority(HIGHEST_PRIORITY)
175 + .fromApp(applicationId)
176 + .makePermanent()
177 + .forTable(FIB_TABLE).build();
178 +
179 + ops = install ? ops.add(rule) : ops.remove(rule);
180 + } else {
181 + log.warn("Driver does not currently process filtering condition"
182 + + " of type: {}", c.type());
183 + fail(filt, ObjectiveError.UNSUPPORTED);
184 + }
185 + }
186 + // apply filtering flow rules
187 + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
188 + @Override
189 + public void onSuccess(FlowRuleOperations ops) {
190 + pass(filt);
191 + log.info("Applied filtering rules");
192 + }
193 +
194 + @Override
195 + public void onError(FlowRuleOperations ops) {
196 + fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
197 + log.info("Failed to apply filtering rules");
198 + }
199 + }));
200 + }
201 +
202 + public void initializePipeline() {
203 + processMeterTable(true);
204 + processPortBasedProtoTable(true); /* Table 0 */
205 + processVlanCheckTable(true); /* Table 1 */
206 + processVlanMacXlateTable(true); /* Table 2 */
207 + processVlanCircuitTable(true); /* Table 3 */
208 + processPriorityMapTable(true); /* Table 4 */
209 + processL3IFMacDATable(true); /* Table 5 */
210 + processEtherTable(true); /* Table 6 */
211 + processFibTable(true); /* Table 7 */
212 + processLocalTable(true); /* Table 9 */
213 + }
214 +
215 + private void processMeterTable(boolean install) {
216 + /* Green meter : Pass all traffic */
217 + Band dropBand = DefaultBand.builder()
218 + .ofType(Band.Type.DROP)
219 + .withRate(0xFFFFFFFF) /* Max Rate */
220 + .build();
221 + MeterRequest.Builder ops = DefaultMeterRequest.builder()
222 + .forDevice(deviceId)
223 + .withBands(Collections.singletonList(dropBand))
224 + .fromApp(appId);
225 +
226 + Meter meter = meterService.submit(install ? ops.add() : ops.remove());
227 + defaultMeterId = meter.id();
228 + }
229 +
230 + private void processPortBasedProtoTable(boolean install) {
231 + /* Default action */
232 + processTableMissGoTo(install, PORT_BASED_PROTO_TABLE, VLAN_CHECK_TABLE);
233 + }
234 +
235 + private void processVlanCheckTable(boolean install) {
236 + int table = VLAN_CHECK_TABLE;
237 +
238 + /* Default action */
239 + processTableMissDrop(install, table);
240 +
241 + /* Tagged packets to VLAN_MAC_XLATE */
242 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
243 + selector.matchVlanId(VlanId.ANY);
244 +
245 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
246 + treatment.transition(VLAN_MAC_XLATE_TABLE);
247 +
248 + FlowRule rule = DefaultFlowRule.builder()
249 + .forDevice(deviceId)
250 + .withSelector(selector.build())
251 + .withTreatment(treatment.build())
252 + .withPriority(CONTROLLER_PRIORITY)
253 + .fromApp(appId)
254 + .makePermanent()
255 + .forTable(table).build();
256 + processFlowRule(install, rule);
257 + }
258 +
259 + private void processVlanMacXlateTable(boolean install) {
260 + /* Default action */
261 + processTableMissGoTo(install, VLAN_MAC_XLATE_TABLE, VLAN_CIRCUIT_TABLE);
262 + }
263 +
264 + private void processVlanCircuitTable(boolean install) {
265 + /* Default action */
266 + processTableMissDrop(install, VLAN_CIRCUIT_TABLE);
267 + }
268 +
269 + private void processPriorityMapTable(boolean install) {
270 + /* Not required currently */
271 + }
272 +
273 + private void processL3IFMacDATable(boolean install) {
274 + int table = L3_IF_MAC_DA_TABLE;
275 +
276 + /* Default action */
277 + processTableMissDrop(install, table);
278 +
279 + /* Allow MAC broadcast frames on all ports */
280 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
281 + selector.matchEthDst(MacAddress.BROADCAST);
282 +
283 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
284 + treatment.transition(ETHER_TABLE);
285 +
286 + FlowRule rule = DefaultFlowRule.builder()
287 + .forDevice(deviceId)
288 + .withSelector(selector.build())
289 + .withTreatment(treatment.build())
290 + .withPriority(CONTROLLER_PRIORITY)
291 + .fromApp(appId)
292 + .makePermanent()
293 + .forTable(table).build();
294 + processFlowRule(install, rule);
295 + }
296 +
297 +
298 + private void processEtherTable(boolean install) {
299 + int table = ETHER_TABLE;
300 +
301 + /* Default action */
302 + processTableMissDrop(install, table);
303 +
304 + /* Arp to controller */
305 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
306 + selector.matchEthType(Ethernet.TYPE_ARP);
307 +
308 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
309 + treatment.punt();
310 +
311 + FlowRule rule = DefaultFlowRule.builder()
312 + .forDevice(deviceId)
313 + .withSelector(selector.build())
314 + .withTreatment(treatment.build())
315 + .withPriority(CONTROLLER_PRIORITY)
316 + .fromApp(appId)
317 + .makePermanent()
318 + .forTable(table).build();
319 + processFlowRule(install, rule);
320 +
321 + /* IP to FIB_TABLE */
322 + selector = DefaultTrafficSelector.builder();
323 + selector.matchEthType(Ethernet.TYPE_IPV4);
324 +
325 + treatment = DefaultTrafficTreatment.builder();
326 + treatment.transition(FIB_TABLE);
327 +
328 + rule = DefaultFlowRule.builder()
329 + .forDevice(deviceId)
330 + .withSelector(selector.build())
331 + .withTreatment(treatment.build())
332 + .withPriority(CONTROLLER_PRIORITY)
333 + .fromApp(appId)
334 + .makePermanent()
335 + .forTable(table).build();
336 + processFlowRule(install, rule);
337 + }
338 +
339 + private void processFibTable(boolean install) {
340 + /* Default action */
341 + processTableMissDrop(install, FIB_TABLE);
342 + }
343 +
344 + private void processLocalTable(boolean install) {
345 + int table = LOCAL_TABLE;
346 + /* Default action */
347 + processTableMissDrop(install, table);
348 +
349 + /* Send all protocols to controller */
350 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
351 +
352 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
353 + treatment.punt();
354 +
355 + FlowRule rule = DefaultFlowRule.builder()
356 + .forDevice(deviceId)
357 + .withSelector(selector.build())
358 + .withTreatment(treatment.build())
359 + .withPriority(CONTROLLER_PRIORITY)
360 + .fromApp(appId)
361 + .makePermanent()
362 + .forTable(table).build();
363 + processFlowRule(install, rule);
364 + }
365 +
366 + /* Init helper: Apply flow rule */
367 + private void processFlowRule(boolean install, FlowRule rule) {
368 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
369 + ops = install ? ops.add(rule) : ops.remove(rule);
370 +
371 + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
372 + @Override
373 + public void onSuccess(FlowRuleOperations ops) {
374 + log.info("Flow provision success: " + ops.toString() + ", " + rule.toString());
375 + }
376 +
377 + @Override
378 + public void onError(FlowRuleOperations ops) {
379 + log.info("Flow provision error: " + ops.toString() + ", " + rule.toString());
380 + }
381 + }));
382 + }
383 +
384 + /* Init helper: Table Miss = Drop */
385 + private void processTableMissDrop(boolean install, int table) {
386 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
387 +
388 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
389 + treatment.drop();
390 +
391 + FlowRule rule = DefaultFlowRule.builder()
392 + .forDevice(deviceId)
393 + .withSelector(selector.build())
394 + .withTreatment(treatment.build())
395 + .withPriority(DROP_PRIORITY)
396 + .fromApp(appId)
397 + .makePermanent()
398 + .forTable(table).build();
399 +
400 + processFlowRule(install, rule);
401 + }
402 +
403 + /* Init helper: Table Miss = GoTo */
404 + private void processTableMissGoTo(boolean install, int table, int goTo) {
405 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
406 +
407 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
408 + treatment.transition(goTo);
409 +
410 + FlowRule rule = DefaultFlowRule.builder()
411 + .forDevice(deviceId)
412 + .withSelector(selector.build())
413 + .withTreatment(treatment.build())
414 + .withPriority(DROP_PRIORITY)
415 + .fromApp(appId)
416 + .makePermanent()
417 + .forTable(table).build();
418 +
419 + processFlowRule(install, rule);
420 + }
421 +}
...@@ -67,6 +67,7 @@ import org.onosproject.net.group.GroupEvent; ...@@ -67,6 +67,7 @@ import org.onosproject.net.group.GroupEvent;
67 import org.onosproject.net.group.GroupKey; 67 import org.onosproject.net.group.GroupKey;
68 import org.onosproject.net.group.GroupListener; 68 import org.onosproject.net.group.GroupListener;
69 import org.onosproject.net.group.GroupService; 69 import org.onosproject.net.group.GroupService;
70 +import org.onosproject.net.meter.MeterService;
70 import org.slf4j.Logger; 71 import org.slf4j.Logger;
71 72
72 import java.util.Collection; 73 import java.util.Collection;
...@@ -96,8 +97,8 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -96,8 +97,8 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
96 97
97 98
98 protected static final int CONTROLLER_PRIORITY = 255; 99 protected static final int CONTROLLER_PRIORITY = 255;
99 - private static final int DROP_PRIORITY = 0; 100 + protected static final int DROP_PRIORITY = 0;
100 - private static final int HIGHEST_PRIORITY = 0xffff; 101 + protected static final int HIGHEST_PRIORITY = 0xffff;
101 102
102 private final Logger log = getLogger(getClass()); 103 private final Logger log = getLogger(getClass());
103 104
...@@ -105,6 +106,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -105,6 +106,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
105 protected FlowRuleService flowRuleService; 106 protected FlowRuleService flowRuleService;
106 private CoreService coreService; 107 private CoreService coreService;
107 private GroupService groupService; 108 private GroupService groupService;
109 + protected MeterService meterService;
108 private FlowObjectiveStore flowObjectiveStore; 110 private FlowObjectiveStore flowObjectiveStore;
109 protected DeviceId deviceId; 111 protected DeviceId deviceId;
110 protected ApplicationId appId; 112 protected ApplicationId appId;
...@@ -140,6 +142,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -140,6 +142,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
140 coreService = serviceDirectory.get(CoreService.class); 142 coreService = serviceDirectory.get(CoreService.class);
141 flowRuleService = serviceDirectory.get(FlowRuleService.class); 143 flowRuleService = serviceDirectory.get(FlowRuleService.class);
142 groupService = serviceDirectory.get(GroupService.class); 144 groupService = serviceDirectory.get(GroupService.class);
145 + meterService = serviceDirectory.get(MeterService.class);
143 flowObjectiveStore = context.store(); 146 flowObjectiveStore = context.store();
144 147
145 groupService.addListener(new InnerGroupListener()); 148 groupService.addListener(new InnerGroupListener());
...@@ -205,6 +208,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -205,6 +208,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
205 Collection<TrafficTreatment> treatments = nextObjective.next(); 208 Collection<TrafficTreatment> treatments = nextObjective.next();
206 if (treatments.size() == 1) { 209 if (treatments.size() == 1) {
207 TrafficTreatment treatment = treatments.iterator().next(); 210 TrafficTreatment treatment = treatments.iterator().next();
211 + treatment = processNextTreatment(treatment);
208 GroupBucket bucket = 212 GroupBucket bucket =
209 DefaultGroupBucket.createIndirectGroupBucket(treatment); 213 DefaultGroupBucket.createIndirectGroupBucket(treatment);
210 final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id())); 214 final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
...@@ -233,6 +237,11 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -233,6 +237,11 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
233 237
234 } 238 }
235 239
240 + /* Hook for altering the NextObjective treatment */
241 + protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
242 + return treatment; /* Keep treatment as is for OVSCorsaPipeline */
243 + }
244 +
236 private Collection<FlowRule> processForward(ForwardingObjective fwd) { 245 private Collection<FlowRule> processForward(ForwardingObjective fwd) {
237 switch (fwd.flag()) { 246 switch (fwd.flag()) {
238 case SPECIFIC: 247 case SPECIFIC:
...@@ -301,22 +310,32 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -301,22 +310,32 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
301 private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { 310 private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
302 log.debug("Processing specific forwarding objective"); 311 log.debug("Processing specific forwarding objective");
303 TrafficSelector selector = fwd.selector(); 312 TrafficSelector selector = fwd.selector();
313 +
304 EthTypeCriterion ethType = 314 EthTypeCriterion ethType =
305 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); 315 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
306 - if (ethType == null || ethType.ethType().toShort() != Ethernet.TYPE_IPV4) { 316 + if (ethType != null) {
307 - fail(fwd, ObjectiveError.UNSUPPORTED); 317 + short et = ethType.ethType().toShort();
308 - return Collections.emptySet(); 318 + if (et == Ethernet.TYPE_IPV4) {
319 + return processSpecificRoute(fwd);
320 + } else if (et == Ethernet.TYPE_VLAN) {
321 + /* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */
322 + return processSpecificSwitch(fwd);
323 + }
309 } 324 }
310 325
326 + fail(fwd, ObjectiveError.UNSUPPORTED);
327 + return Collections.emptySet();
328 + }
329 +
330 + private Collection<FlowRule> processSpecificRoute(ForwardingObjective fwd) {
311 TrafficSelector filteredSelector = 331 TrafficSelector filteredSelector =
312 DefaultTrafficSelector.builder() 332 DefaultTrafficSelector.builder()
313 .matchEthType(Ethernet.TYPE_IPV4) 333 .matchEthType(Ethernet.TYPE_IPV4)
314 .matchIPDst( 334 .matchIPDst(
315 - ((IPCriterion) 335 + ((IPCriterion) fwd.selector().getCriterion(Criterion.Type.IPV4_DST)).ip())
316 - selector.getCriterion(Criterion.Type.IPV4_DST)).ip())
317 .build(); 336 .build();
318 337
319 - TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); 338 + TrafficTreatment.Builder tb = processSpecificRoutingTreatment();
320 339
321 if (fwd.nextId() != null) { 340 if (fwd.nextId() != null) {
322 NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); 341 NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
...@@ -337,20 +356,35 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -337,20 +356,35 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
337 .withSelector(filteredSelector) 356 .withSelector(filteredSelector)
338 .withTreatment(tb.build()); 357 .withTreatment(tb.build());
339 358
359 + ruleBuilder = processSpecificRoutingRule(ruleBuilder);
360 +
340 if (fwd.permanent()) { 361 if (fwd.permanent()) {
341 ruleBuilder.makePermanent(); 362 ruleBuilder.makePermanent();
342 } else { 363 } else {
343 ruleBuilder.makeTemporary(fwd.timeout()); 364 ruleBuilder.makeTemporary(fwd.timeout());
344 } 365 }
345 366
346 - ruleBuilder.forTable(FIB_TABLE); 367 + return Collections.singletonList(ruleBuilder.build());
368 + }
347 369
370 + /* Hook for modifying Route traffic treatment */
371 + protected TrafficTreatment.Builder processSpecificRoutingTreatment() {
372 + return DefaultTrafficTreatment.builder();
373 + }
348 374
349 - return Collections.singletonList(ruleBuilder.build()); 375 + /* Hook for modifying Route flow rule */
376 + protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) {
377 + return rb.forTable(FIB_TABLE);
378 + }
350 379
380 + protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
381 + /* Not supported by until CorsaPipelineV3 */
382 + log.warn("Vlan switching not supported in ovs-corsa driver");
383 + fail(fwd, ObjectiveError.UNSUPPORTED);
384 + return Collections.emptySet();
351 } 385 }
352 386
353 - private void processFilter(FilteringObjective filt, boolean install, 387 + protected void processFilter(FilteringObjective filt, boolean install,
354 ApplicationId applicationId) { 388 ApplicationId applicationId) {
355 // This driver only processes filtering criteria defined with switch 389 // This driver only processes filtering criteria defined with switch
356 // ports as the key 390 // ports as the key
...@@ -441,19 +475,19 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -441,19 +475,19 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
441 })); 475 }));
442 } 476 }
443 477
444 - private void pass(Objective obj) { 478 + protected void pass(Objective obj) {
445 if (obj.context().isPresent()) { 479 if (obj.context().isPresent()) {
446 obj.context().get().onSuccess(obj); 480 obj.context().get().onSuccess(obj);
447 } 481 }
448 } 482 }
449 483
450 - private void fail(Objective obj, ObjectiveError error) { 484 + protected void fail(Objective obj, ObjectiveError error) {
451 if (obj.context().isPresent()) { 485 if (obj.context().isPresent()) {
452 obj.context().get().onError(obj, error); 486 obj.context().get().onError(obj, error);
453 } 487 }
454 } 488 }
455 489
456 - private void initializePipeline() { 490 + protected void initializePipeline() {
457 processMacTable(true); 491 processMacTable(true);
458 processVlanMplsTable(true); 492 processVlanMplsTable(true);
459 processVlanTable(true); 493 processVlanTable(true);
......
...@@ -84,6 +84,20 @@ ...@@ -84,6 +84,20 @@
84 <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" 84 <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
85 impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/> 85 impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/>
86 </driver> 86 </driver>
87 + <driver name="corsa-v1"
88 + manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
89 + <behaviour api="org.onosproject.net.behaviour.Pipeliner"
90 + impl="org.onosproject.driver.pipeline.CorsaPipeline"/>
91 + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
92 + impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/>
93 + </driver>
94 + <driver name="corsa-v3"
95 + manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1">
96 + <behaviour api="org.onosproject.net.behaviour.Pipeliner"
97 + impl="org.onosproject.driver.pipeline.CorsaPipelineV3"/>
98 + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
99 + impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/>
100 + </driver>
87 <driver name="ofdpa" extends="default" 101 <driver name="ofdpa" extends="default"
88 manufacturer="Broadcom Corp." hwVersion="OF-DPA.*" swVersion="OF-DPA.*"> 102 manufacturer="Broadcom Corp." hwVersion="OF-DPA.*" swVersion="OF-DPA.*">
89 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 103 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
......