blob: 997c2079487f8667bbf1661a3c3b85a93d2eee24 [file] [log] [blame]
alshabibaebe7752015-04-07 17:45:42 -07001/*
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 */
16package org.onosproject.driver.pipeline;
17
alshabib910aff12015-04-09 16:55:57 -070018import com.google.common.collect.Sets;
19import com.google.common.util.concurrent.SettableFuture;
alshabibaebe7752015-04-07 17:45:42 -070020import org.onlab.osgi.ServiceDirectory;
21import org.onlab.packet.Ethernet;
22import org.onlab.packet.MacAddress;
23import org.onlab.packet.VlanId;
24import org.onosproject.core.ApplicationId;
25import org.onosproject.core.CoreService;
26import org.onosproject.net.DeviceId;
27import org.onosproject.net.behaviour.Pipeliner;
Thomas Vachuskaca88bb72015-04-08 19:38:02 -070028import org.onosproject.net.behaviour.PipelinerContext;
Thomas Vachuskafacc3f52015-04-10 08:58:36 -070029import org.onosproject.net.driver.AbstractHandlerBehaviour;
alshabibaebe7752015-04-07 17:45:42 -070030import org.onosproject.net.flow.DefaultFlowRule;
31import org.onosproject.net.flow.DefaultTrafficSelector;
32import org.onosproject.net.flow.DefaultTrafficTreatment;
33import org.onosproject.net.flow.FlowRule;
34import org.onosproject.net.flow.FlowRuleOperations;
35import org.onosproject.net.flow.FlowRuleOperationsContext;
36import org.onosproject.net.flow.FlowRuleService;
37import org.onosproject.net.flow.TrafficSelector;
38import org.onosproject.net.flow.TrafficTreatment;
alshabib910aff12015-04-09 16:55:57 -070039import org.onosproject.net.flow.criteria.Criteria;
40import org.onosproject.net.flow.criteria.Criterion;
alshabibaebe7752015-04-07 17:45:42 -070041import org.onosproject.net.flowobjective.FilteringObjective;
42import org.onosproject.net.flowobjective.ForwardingObjective;
43import org.onosproject.net.flowobjective.NextObjective;
alshabib910aff12015-04-09 16:55:57 -070044import org.onosproject.net.flowobjective.Objective;
alshabibaebe7752015-04-07 17:45:42 -070045import org.slf4j.Logger;
46
47import java.util.Collection;
48import java.util.concurrent.Future;
49
50import static org.slf4j.LoggerFactory.getLogger;
51
52/**
Thomas Vachuska5c2f8132015-04-08 23:09:08 -070053 * Corsa pipeline handler.
alshabibaebe7752015-04-07 17:45:42 -070054 */
Thomas Vachuskafacc3f52015-04-10 08:58:36 -070055public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeliner {
alshabibaebe7752015-04-07 17:45:42 -070056
57 private static final int CONTROLLER_PRIORITY = 255;
58 private static final int DROP_PRIORITY = 0;
59 private static final int HIGHEST_PRIORITY = 0xffff;
60
61 private final Logger log = getLogger(getClass());
62
63 private ServiceDirectory serviceDirectory;
64 private FlowRuleService flowRuleService;
65 private CoreService coreService;
66 private DeviceId deviceId;
67 private ApplicationId appId;
68
69 @Override
Thomas Vachuskaca88bb72015-04-08 19:38:02 -070070 public void init(DeviceId deviceId, PipelinerContext context) {
71 this.serviceDirectory = context.directory();
alshabibaebe7752015-04-07 17:45:42 -070072 this.deviceId = deviceId;
73
74
75 coreService = serviceDirectory.get(CoreService.class);
76 flowRuleService = serviceDirectory.get(FlowRuleService.class);
77
78 appId = coreService.registerApplication(
79 "org.onosproject.driver.OVSCorsaPipeline");
80
81 pushDefaultRules();
alshabibaebe7752015-04-07 17:45:42 -070082 }
83
84 @Override
85 public Future<Boolean> filter(Collection<FilteringObjective> filteringObjectives) {
Saurav Dascfd63d22015-04-13 16:08:24 -070086 Collection<Future<Boolean>> results = Sets.newHashSet();
alshabib910aff12015-04-09 16:55:57 -070087 filteringObjectives.stream()
88 .filter(obj -> obj.type() == FilteringObjective.Type.PERMIT)
Saurav Dascfd63d22015-04-13 16:08:24 -070089 .forEach(filtobj -> results.add(processFilter(filtobj,
90 filtobj.op() == Objective.Operation.ADD,
91 filtobj.appId()
92 )));
alshabib910aff12015-04-09 16:55:57 -070093
94 //TODO: return something more helpful/sensible in the future (no pun intended)
95 return results.iterator().next();
96
97 }
98
Saurav Dascfd63d22015-04-13 16:08:24 -070099 private Future<Boolean> processFilter(FilteringObjective filt, boolean install,
alshabib910aff12015-04-09 16:55:57 -0700100 ApplicationId applicationId) {
101 SettableFuture<Boolean> result = SettableFuture.create();
Saurav Dascfd63d22015-04-13 16:08:24 -0700102 // This driver only processes filtering criteria defined with switch
103 // ports as the key
104 Criteria.PortCriterion p = null;
105 if (!filt.key().equals(Criteria.dummy()) &&
106 filt.key().type() == Criterion.Type.IN_PORT) {
107 p = (Criteria.PortCriterion) filt.key();
108 } else {
109 log.warn("No key defined in filtering objective from app: {}. Not"
110 + "processing filtering objective", applicationId);
111 return null;
alshabib910aff12015-04-09 16:55:57 -0700112 }
Saurav Dascfd63d22015-04-13 16:08:24 -0700113 // convert filtering conditions for switch-intfs into flowrules
114 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
115 for (Criterion c : filt.conditions()) {
116 if (c.type() == Criterion.Type.ETH_DST) {
117 Criteria.EthCriterion e = (Criteria.EthCriterion) c;
118 log.debug("adding rule for MAC: {}", e.mac());
119 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
120 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
121 selector.matchEthDst(e.mac());
122 treatment.transition(FlowRule.Type.VLAN_MPLS);
123 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
124 treatment.build(),
125 CONTROLLER_PRIORITY, applicationId,
126 0, true, FlowRule.Type.FIRST);
127 ops = install ? ops.add(rule) : ops.remove(rule);
128 } else if (c.type() == Criterion.Type.VLAN_VID) {
129 Criteria.VlanIdCriterion v = (Criteria.VlanIdCriterion) c;
130 log.debug("adding rule for VLAN: {}", v.vlanId());
131 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
132 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
133 selector.matchVlanId(v.vlanId());
134 selector.matchInPort(p.port());
135 treatment.transition(FlowRule.Type.ETHER);
136 treatment.deferred().popVlan();
137 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
138 treatment.build(),
139 CONTROLLER_PRIORITY, applicationId,
140 0, true, FlowRule.Type.VLAN);
141 ops = install ? ops.add(rule) : ops.remove(rule);
142 } else if (c.type() == Criterion.Type.IPV4_DST) {
143 Criteria.IPCriterion ip = (Criteria.IPCriterion) c;
144 log.debug("adding rule for IP: {}", ip.ip());
145 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
146 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
147 selector.matchEthType(Ethernet.TYPE_IPV4);
148 selector.matchIPDst(ip.ip());
149 treatment.transition(FlowRule.Type.ACL);
150 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
151 treatment.build(), HIGHEST_PRIORITY, appId,
152 0, true, FlowRule.Type.IP);
153 ops = install ? ops.add(rule) : ops.remove(rule);
154 } else {
155 log.warn("Driver does not currently process filtering condition"
156 + " of type: {}", c.type());
157 }
158 }
159 // apply filtering flow rules
160 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
161 @Override
162 public void onSuccess(FlowRuleOperations ops) {
163 result.set(true);
164 log.info("Provisioned default table for bgp router");
165 }
166
167 @Override
168 public void onError(FlowRuleOperations ops) {
169 result.set(false);
170 log.info("Failed to provision default table for bgp router");
171 }
172 }));
173
alshabib910aff12015-04-09 16:55:57 -0700174 return result;
alshabibaebe7752015-04-07 17:45:42 -0700175 }
176
177 @Override
178 public Future<Boolean> forward(Collection<ForwardingObjective> forwardObjectives) {
179 return null;
180 }
181
182 @Override
183 public Future<Boolean> next(Collection<NextObjective> nextObjectives) {
184 return null;
185 }
186
alshabibaebe7752015-04-07 17:45:42 -0700187 private void pushDefaultRules() {
188 boolean install = true;
189 processTableZero(install);
190 processTableOne(install);
191 processTableTwo(install);
192 processTableFour(install);
193 processTableFive(install);
194 processTableSix(install);
195 processTableNine(install);
196 }
197
198 private void processTableZero(boolean install) {
199 TrafficSelector.Builder selector;
200 TrafficTreatment.Builder treatment;
201
202 // Bcast rule
203 selector = DefaultTrafficSelector.builder();
204 treatment = DefaultTrafficTreatment.builder();
205
206 selector.matchEthDst(MacAddress.BROADCAST);
207 treatment.transition(FlowRule.Type.VLAN_MPLS);
208
209 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
210 treatment.build(),
211 CONTROLLER_PRIORITY, appId, 0,
212 true, FlowRule.Type.FIRST);
213
214 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
215
216 ops = install ? ops.add(rule) : ops.remove(rule);
217
218
alshabibaebe7752015-04-07 17:45:42 -0700219 //Drop rule
220 selector = DefaultTrafficSelector.builder();
221 treatment = DefaultTrafficTreatment.builder();
222
223 treatment.drop();
224
225 rule = new DefaultFlowRule(deviceId, selector.build(),
226 treatment.build(), DROP_PRIORITY, appId,
227 0, true, FlowRule.Type.FIRST);
228
229 ops = install ? ops.add(rule) : ops.remove(rule);
230
231 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
232 @Override
233 public void onSuccess(FlowRuleOperations ops) {
234 log.info("Provisioned default table for bgp router");
235 }
236
237 @Override
238 public void onError(FlowRuleOperations ops) {
239 log.info("Failed to provision default table for bgp router");
240 }
241 }));
242
243 }
244
245 private void processTableOne(boolean install) {
246 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
247 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
248 .builder();
249 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
250 FlowRule rule;
251
252 selector.matchVlanId(VlanId.ANY);
253 treatment.transition(FlowRule.Type.VLAN);
254
255 rule = new DefaultFlowRule(deviceId, selector.build(),
256 treatment.build(), CONTROLLER_PRIORITY,
257 appId, 0, true, FlowRule.Type.VLAN_MPLS);
258
259 ops = install ? ops.add(rule) : ops.remove(rule);
260
261 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
262 @Override
263 public void onSuccess(FlowRuleOperations ops) {
264 log.info("Provisioned vlan/mpls table for bgp router");
265 }
266
267 @Override
268 public void onError(FlowRuleOperations ops) {
269 log.info(
270 "Failed to provision vlan/mpls table for bgp router");
271 }
272 }));
273
274 }
275
276 private void processTableTwo(boolean install) {
277 TrafficSelector.Builder selector;
278 TrafficTreatment.Builder treatment;
279 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
280 FlowRule rule;
281
282
alshabibaebe7752015-04-07 17:45:42 -0700283 //Drop rule
284 selector = DefaultTrafficSelector.builder();
285 treatment = DefaultTrafficTreatment.builder();
286
287 treatment.drop();
288
289 rule = new DefaultFlowRule(deviceId, selector.build(),
290 treatment.build(), DROP_PRIORITY, appId,
291 0, true, FlowRule.Type.VLAN);
292
293 ops = install ? ops.add(rule) : ops.remove(rule);
294
295 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
296 @Override
297 public void onSuccess(FlowRuleOperations ops) {
298 log.info("Provisioned vlan table for bgp router");
299 }
300
301 @Override
302 public void onError(FlowRuleOperations ops) {
303 log.info("Failed to provision vlan table for bgp router");
304 }
305 }));
306 }
307
308 private void processTableFour(boolean install) {
309 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
310 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
311 .builder();
312 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
313 FlowRule rule;
314
315 selector.matchEthType(Ethernet.TYPE_ARP);
316 treatment.punt();
317
318 rule = new DefaultFlowRule(deviceId, selector.build(),
319 treatment.build(), CONTROLLER_PRIORITY,
320 appId, 0, true, FlowRule.Type.ETHER);
321
322 ops = install ? ops.add(rule) : ops.remove(rule);
323
324 selector = DefaultTrafficSelector.builder();
325 treatment = DefaultTrafficTreatment.builder();
326
327 selector.matchEthType(Ethernet.TYPE_IPV4);
328 treatment.transition(FlowRule.Type.COS);
329
330 rule = new DefaultFlowRule(deviceId, selector.build(),
331 treatment.build(), CONTROLLER_PRIORITY,
332 appId, 0, true, FlowRule.Type.ETHER);
333
334 ops = install ? ops.add(rule) : ops.remove(rule);
335
336 //Drop rule
337 selector = DefaultTrafficSelector.builder();
338 treatment = DefaultTrafficTreatment.builder();
339
340 treatment.drop();
341
342 rule = new DefaultFlowRule(deviceId, selector.build(),
343 treatment.build(), DROP_PRIORITY, appId,
344 0, true, FlowRule.Type.ETHER);
345
346 ops = install ? ops.add(rule) : ops.remove(rule);
347
348 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
349 @Override
350 public void onSuccess(FlowRuleOperations ops) {
351 log.info("Provisioned ether table for bgp router");
352 }
353
354 @Override
355 public void onError(FlowRuleOperations ops) {
356 log.info("Failed to provision ether table for bgp router");
357 }
358 }));
359
360 }
361
362 private void processTableFive(boolean install) {
363 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
364 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
365 .builder();
366 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
367 FlowRule rule;
368
369 treatment.transition(FlowRule.Type.IP);
370
371 rule = new DefaultFlowRule(deviceId, selector.build(),
372 treatment.build(), DROP_PRIORITY, appId,
373 0, true, FlowRule.Type.COS);
374
375 ops = install ? ops.add(rule) : ops.remove(rule);
376
377 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
378 @Override
379 public void onSuccess(FlowRuleOperations ops) {
380 log.info("Provisioned cos table for bgp router");
381 }
382
383 @Override
384 public void onError(FlowRuleOperations ops) {
385 log.info("Failed to provision cos table for bgp router");
386 }
387 }));
388
389 }
390
391 private void processTableSix(boolean install) {
392 TrafficSelector.Builder selector;
393 TrafficTreatment.Builder treatment;
394 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
395 FlowRule rule;
396
397 //Drop rule
398 selector = DefaultTrafficSelector.builder();
399 treatment = DefaultTrafficTreatment.builder();
400
401 treatment.drop();
402
403 rule = new DefaultFlowRule(deviceId, selector.build(),
404 treatment.build(), DROP_PRIORITY, appId,
405 0, true, FlowRule.Type.IP);
406
407 ops = install ? ops.add(rule) : ops.remove(rule);
408
409 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
410 @Override
411 public void onSuccess(FlowRuleOperations ops) {
412 log.info("Provisioned FIB table for bgp router");
413 }
414
415 @Override
416 public void onError(FlowRuleOperations ops) {
417 log.info("Failed to provision FIB table for bgp router");
418 }
419 }));
420 }
421
422 private void processTableNine(boolean install) {
423 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
424 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
425 .builder();
426 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
427 FlowRule rule;
428
429 treatment.punt();
430
431 rule = new DefaultFlowRule(deviceId, selector.build(),
432 treatment.build(), CONTROLLER_PRIORITY,
433 appId, 0, true, FlowRule.Type.DEFAULT);
434
435 ops = install ? ops.add(rule) : ops.remove(rule);
436
437 flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
438 @Override
439 public void onSuccess(FlowRuleOperations ops) {
440 log.info("Provisioned Local table for bgp router");
441 }
442
443 @Override
444 public void onError(FlowRuleOperations ops) {
445 log.info("Failed to provision Local table for bgp router");
446 }
447 }));
448 }
449
450}