Committed by
Gerrit Code Review
Add driver support for Corsa Pipeline V3
Change-Id: If5c1aa9cec6093e3c9f2f908de6066957d9ad8fd
Showing
5 changed files
with
512 additions
and
14 deletions
... | @@ -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" | ... | ... |
-
Please register or login to post a comment