blob: 7e22501f1328024c9d6a42d2443e777c695f2550 [file] [log] [blame]
alshabibfaa1e362015-04-02 15:01:54 -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
alshabibfaa1e362015-04-02 15:01:54 -070018import org.onlab.osgi.ServiceDirectory;
alshabibfaa1e362015-04-02 15:01:54 -070019import org.onosproject.net.DeviceId;
20import org.onosproject.net.behaviour.Pipeliner;
Thomas Vachuskaca88bb72015-04-08 19:38:02 -070021import org.onosproject.net.behaviour.PipelinerContext;
Thomas Vachuskafacc3f52015-04-10 08:58:36 -070022import org.onosproject.net.driver.AbstractHandlerBehaviour;
alshabibfaa1e362015-04-02 15:01:54 -070023import org.onosproject.net.flow.DefaultFlowRule;
alshabibc61e18c2016-02-02 23:05:25 -080024import org.onosproject.net.flow.DefaultTrafficSelector;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070025import org.onosproject.net.flow.DefaultTrafficTreatment;
alshabibfaa1e362015-04-02 15:01:54 -070026import org.onosproject.net.flow.FlowRule;
27import org.onosproject.net.flow.FlowRuleOperations;
28import org.onosproject.net.flow.FlowRuleOperationsContext;
29import org.onosproject.net.flow.FlowRuleService;
30import org.onosproject.net.flow.TrafficSelector;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070031import org.onosproject.net.flow.TrafficTreatment;
32import org.onosproject.net.flow.instructions.Instructions;
alshabibfaa1e362015-04-02 15:01:54 -070033import org.onosproject.net.flowobjective.FilteringObjective;
34import org.onosproject.net.flowobjective.ForwardingObjective;
alshabib77b88482015-04-07 15:47:50 -070035import org.onosproject.net.flowobjective.NextObjective;
alshabibc61e18c2016-02-02 23:05:25 -080036import org.onosproject.net.flowobjective.Objective;
alshabib2a441c62015-04-13 18:39:38 -070037import org.onosproject.net.flowobjective.ObjectiveError;
alshabibfaa1e362015-04-02 15:01:54 -070038import org.slf4j.Logger;
39
alshabibfaa1e362015-04-02 15:01:54 -070040import static org.slf4j.LoggerFactory.getLogger;
41
42/**
43 * Simple single table pipeline abstraction.
44 */
Thomas Vachuskafacc3f52015-04-10 08:58:36 -070045public class DefaultSingleTablePipeline extends AbstractHandlerBehaviour implements Pipeliner {
alshabibfaa1e362015-04-02 15:01:54 -070046
47 private final Logger log = getLogger(getClass());
48
49 private ServiceDirectory serviceDirectory;
50 private FlowRuleService flowRuleService;
51 private DeviceId deviceId;
52
53 @Override
Thomas Vachuskaca88bb72015-04-08 19:38:02 -070054 public void init(DeviceId deviceId, PipelinerContext context) {
55 this.serviceDirectory = context.directory();
alshabibfaa1e362015-04-02 15:01:54 -070056 this.deviceId = deviceId;
57
58 flowRuleService = serviceDirectory.get(FlowRuleService.class);
alshabibfaa1e362015-04-02 15:01:54 -070059 }
60
61 @Override
alshabibc61e18c2016-02-02 23:05:25 -080062 public void filter(FilteringObjective filter) {
63
64 TrafficTreatment.Builder actions;
65 switch (filter.type()) {
66 case PERMIT:
67 actions = (filter.meta() == null) ?
68 DefaultTrafficTreatment.builder().punt() :
69 DefaultTrafficTreatment.builder(filter.meta());
70 break;
71 case DENY:
72 actions = (filter.meta() == null) ?
73 DefaultTrafficTreatment.builder() :
74 DefaultTrafficTreatment.builder(filter.meta());
75 actions.drop();
76 break;
77 default:
78 log.warn("Unknown filter type: {}", filter.type());
79 actions = DefaultTrafficTreatment.builder().drop();
80 }
81
82 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
83
84 filter.conditions().stream().forEach(selector::add);
85
86 if (filter.key() != null) {
87 selector.add(filter.key());
88 }
89
90 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
91 .forDevice(deviceId)
92 .withSelector(selector.build())
93 .withTreatment(actions.build())
94 .fromApp(filter.appId())
95 .withPriority(filter.priority());
96
97 if (filter.permanent()) {
98 ruleBuilder.makePermanent();
99 } else {
100 ruleBuilder.makeTemporary(filter.timeout());
101 }
102
103 installObjective(ruleBuilder, filter);
104
105 }
alshabibfaa1e362015-04-02 15:01:54 -0700106
107 @Override
alshabib2a441c62015-04-13 18:39:38 -0700108 public void forward(ForwardingObjective fwd) {
alshabib2a441c62015-04-13 18:39:38 -0700109 if (fwd.flag() != ForwardingObjective.Flag.VERSATILE) {
110 throw new UnsupportedOperationException(
111 "Only VERSATILE is supported.");
112 }
alshabibfaa1e362015-04-02 15:01:54 -0700113
alshabib2a441c62015-04-13 18:39:38 -0700114 TrafficSelector selector = fwd.selector();
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700115 TrafficTreatment treatment = fwd.treatment();
116 if ((fwd.treatment().deferred().size() == 0) &&
117 (fwd.treatment().immediate().size() == 0) &&
118 (fwd.treatment().tableTransition() == null) &&
119 (!fwd.treatment().clearedDeferred())) {
120 TrafficTreatment.Builder flowTreatment = DefaultTrafficTreatment.builder();
121 flowTreatment.add(Instructions.createDrop());
122 treatment = flowTreatment.build();
123 }
alshabibfaa1e362015-04-02 15:01:54 -0700124
alshabibb452fd72015-04-22 20:46:20 -0700125 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
126 .forDevice(deviceId)
127 .withSelector(selector)
Charles M.C. Chanef3f39e2015-07-14 22:21:46 +0800128 .withTreatment(treatment)
alshabibb452fd72015-04-22 20:46:20 -0700129 .fromApp(fwd.appId())
130 .withPriority(fwd.priority());
131
132 if (fwd.permanent()) {
133 ruleBuilder.makePermanent();
134 } else {
135 ruleBuilder.makeTemporary(fwd.timeout());
136 }
137
alshabibc61e18c2016-02-02 23:05:25 -0800138 installObjective(ruleBuilder, fwd);
alshabibfaa1e362015-04-02 15:01:54 -0700139
alshabibc61e18c2016-02-02 23:05:25 -0800140 }
141
142 private void installObjective(FlowRule.Builder ruleBuilder, Objective objective) {
143 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
144 switch (objective.op()) {
alshabibfaa1e362015-04-02 15:01:54 -0700145
alshabib2a441c62015-04-13 18:39:38 -0700146 case ADD:
alshabibb452fd72015-04-22 20:46:20 -0700147 flowBuilder.add(ruleBuilder.build());
alshabib2a441c62015-04-13 18:39:38 -0700148 break;
149 case REMOVE:
alshabibb452fd72015-04-22 20:46:20 -0700150 flowBuilder.remove(ruleBuilder.build());
alshabib2a441c62015-04-13 18:39:38 -0700151 break;
152 default:
alshabibc61e18c2016-02-02 23:05:25 -0800153 log.warn("Unknown operation {}", objective.op());
alshabib2a441c62015-04-13 18:39:38 -0700154 }
155
alshabibfaa1e362015-04-02 15:01:54 -0700156 flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
157 @Override
158 public void onSuccess(FlowRuleOperations ops) {
alshabibc61e18c2016-02-02 23:05:25 -0800159 if (objective.context().isPresent()) {
160 objective.context().get().onSuccess(objective);
alshabib2a441c62015-04-13 18:39:38 -0700161 }
alshabibfaa1e362015-04-02 15:01:54 -0700162 }
163
164 @Override
165 public void onError(FlowRuleOperations ops) {
alshabibc61e18c2016-02-02 23:05:25 -0800166 if (objective.context().isPresent()) {
167 objective.context().get().onError(objective, ObjectiveError.FLOWINSTALLATIONFAILED);
alshabib2a441c62015-04-13 18:39:38 -0700168 }
alshabibfaa1e362015-04-02 15:01:54 -0700169 }
170 }));
alshabibfaa1e362015-04-02 15:01:54 -0700171 }
alshabib77b88482015-04-07 15:47:50 -0700172
173 @Override
alshabibc61e18c2016-02-02 23:05:25 -0800174 public void next(NextObjective nextObjective) {
175 }
alshabib77b88482015-04-07 15:47:50 -0700176
alshabibfaa1e362015-04-02 15:01:54 -0700177}