blob: c1585114a8b37a2f172aa99dc2f1f635806ffc61 [file] [log] [blame]
alshabib0ccde6d2015-05-30 18:22:36 -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
18import org.onlab.osgi.ServiceDirectory;
alshabib2cc73cb2015-06-30 20:26:56 -070019import org.onosproject.net.DefaultAnnotations;
20import org.onosproject.net.Device;
alshabib0ccde6d2015-05-30 18:22:36 -070021import org.onosproject.net.DeviceId;
alshabib2cc73cb2015-06-30 20:26:56 -070022import org.onosproject.net.MastershipRole;
alshabib0ccde6d2015-05-30 18:22:36 -070023import org.onosproject.net.PortNumber;
24import org.onosproject.net.behaviour.Pipeliner;
25import org.onosproject.net.behaviour.PipelinerContext;
alshabib2cc73cb2015-06-30 20:26:56 -070026import org.onosproject.net.device.DefaultDeviceDescription;
27import org.onosproject.net.device.DeviceDescription;
28import org.onosproject.net.device.DeviceProvider;
29import org.onosproject.net.device.DeviceProviderRegistry;
30import org.onosproject.net.device.DeviceProviderService;
31import org.onosproject.net.device.DeviceService;
alshabib0ccde6d2015-05-30 18:22:36 -070032import org.onosproject.net.driver.AbstractHandlerBehaviour;
33import org.onosproject.net.flow.DefaultFlowRule;
34import org.onosproject.net.flow.DefaultTrafficTreatment;
35import org.onosproject.net.flow.FlowRule;
36import org.onosproject.net.flow.FlowRuleOperations;
37import org.onosproject.net.flow.FlowRuleOperationsContext;
38import org.onosproject.net.flow.FlowRuleService;
39import org.onosproject.net.flow.TrafficSelector;
40import org.onosproject.net.flow.TrafficTreatment;
41import org.onosproject.net.flow.instructions.Instructions;
42import org.onosproject.net.flowobjective.FilteringObjective;
43import org.onosproject.net.flowobjective.ForwardingObjective;
44import org.onosproject.net.flowobjective.NextObjective;
45import org.onosproject.net.flowobjective.ObjectiveError;
alshabib2cc73cb2015-06-30 20:26:56 -070046import org.onosproject.net.provider.AbstractProvider;
47import org.onosproject.net.provider.ProviderId;
alshabib0ccde6d2015-05-30 18:22:36 -070048import org.slf4j.Logger;
49
alshabib2cc73cb2015-06-30 20:26:56 -070050import static com.google.common.base.Preconditions.checkNotNull;
alshabib0ccde6d2015-05-30 18:22:36 -070051import static org.slf4j.LoggerFactory.getLogger;
52
53/**
54 * Simple single table pipeline abstraction.
55 */
56public class OLTPipeline extends AbstractHandlerBehaviour implements Pipeliner {
57
58 private final Logger log = getLogger(getClass());
59
alshabib2cc73cb2015-06-30 20:26:56 -070060 static final ProviderId PID = new ProviderId("olt", "org.onosproject.olt", true);
61
62 static final String DEVICE = "isAccess";
63 static final String OLT = "true";
64
alshabib0ccde6d2015-05-30 18:22:36 -070065 private ServiceDirectory serviceDirectory;
66 private FlowRuleService flowRuleService;
67 private DeviceId deviceId;
68
alshabib2cc73cb2015-06-30 20:26:56 -070069 private DeviceProvider provider = new AnnotationProvider();
70
alshabibb32cefe2015-06-08 18:15:05 -070071
alshabib0ccde6d2015-05-30 18:22:36 -070072 @Override
73 public void init(DeviceId deviceId, PipelinerContext context) {
74 this.serviceDirectory = context.directory();
75 this.deviceId = deviceId;
alshabib2cc73cb2015-06-30 20:26:56 -070076 DeviceProviderRegistry registry =
77 serviceDirectory.get(DeviceProviderRegistry.class);
alshabib0ccde6d2015-05-30 18:22:36 -070078 flowRuleService = serviceDirectory.get(FlowRuleService.class);
alshabibb32cefe2015-06-08 18:15:05 -070079
alshabib2cc73cb2015-06-30 20:26:56 -070080 try {
81 DeviceProviderService providerService = registry.register(provider);
82 providerService.deviceConnected(deviceId,
83 description(deviceId, DEVICE, OLT));
84 } finally {
85 registry.unregister(provider);
86 }
87
alshabibb32cefe2015-06-08 18:15:05 -070088 }
89
alshabib0ccde6d2015-05-30 18:22:36 -070090 @Override
91 public void filter(FilteringObjective filter) {
92 throw new UnsupportedOperationException("Single table does not filter.");
93 }
94
95 @Override
96 public void forward(ForwardingObjective fwd) {
alshabib0ccde6d2015-05-30 18:22:36 -070097 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
98
99 if (fwd.flag() != ForwardingObjective.Flag.VERSATILE) {
100 throw new UnsupportedOperationException(
101 "Only VERSATILE is supported.");
102 }
103
104 boolean isPunt = fwd.treatment().immediate().stream().anyMatch(i -> {
105 if (i instanceof Instructions.OutputInstruction) {
106 Instructions.OutputInstruction out = (Instructions.OutputInstruction) i;
107 return out.port().equals(PortNumber.CONTROLLER);
108 }
109 return false;
110 });
111
112 if (isPunt) {
113 return;
114 }
115
116 TrafficSelector selector = fwd.selector();
117 TrafficTreatment treatment = fwd.treatment();
118 if ((fwd.treatment().deferred().size() == 0) &&
119 (fwd.treatment().immediate().size() == 0) &&
120 (fwd.treatment().tableTransition() == null) &&
121 (!fwd.treatment().clearedDeferred())) {
122 TrafficTreatment.Builder flowTreatment = DefaultTrafficTreatment.builder();
123 flowTreatment.add(Instructions.createDrop());
124 treatment = flowTreatment.build();
125 }
126
127 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
128 .forDevice(deviceId)
129 .withSelector(selector)
130 .withTreatment(fwd.treatment())
131 .fromApp(fwd.appId())
132 .withPriority(fwd.priority());
133
134 if (fwd.permanent()) {
135 ruleBuilder.makePermanent();
136 } else {
137 ruleBuilder.makeTemporary(fwd.timeout());
138 }
139
140
141 switch (fwd.op()) {
142
143 case ADD:
144 flowBuilder.add(ruleBuilder.build());
145 break;
146 case REMOVE:
147 flowBuilder.remove(ruleBuilder.build());
148 break;
149 default:
150 log.warn("Unknown operation {}", fwd.op());
151 }
152
153 flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
154 @Override
155 public void onSuccess(FlowRuleOperations ops) {
156 if (fwd.context().isPresent()) {
157 fwd.context().get().onSuccess(fwd);
158 }
159 }
160
161 @Override
162 public void onError(FlowRuleOperations ops) {
163 if (fwd.context().isPresent()) {
164 fwd.context().get().onError(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
165 }
166 }
167 }));
168
169 }
170
171 @Override
172 public void next(NextObjective nextObjective) {
173 throw new UnsupportedOperationException("Single table does not next hop.");
174 }
175
alshabib2cc73cb2015-06-30 20:26:56 -0700176 /**
177 * Build a device description.
178 * @param deviceId a deviceId
179 * @param key the key of the annotation
180 * @param value the value for the annotation
181 * @return a device description
182 */
183 private DeviceDescription description(DeviceId deviceId, String key, String value) {
184 DeviceService deviceService = serviceDirectory.get(DeviceService.class);
185 Device device = deviceService.getDevice(deviceId);
186
187 checkNotNull(device, "Device not found in device service.");
188
189 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
190 if (value != null) {
191 builder.set(key, value);
192 } else {
193 builder.remove(key);
194 }
195 return new DefaultDeviceDescription(device.id().uri(), device.type(),
196 device.manufacturer(), device.hwVersion(),
197 device.swVersion(), device.serialNumber(),
198 device.chassisId(), builder.build());
199 }
200
201 /**
202 * Simple ancillary provider used to annotate device.
203 */
204 private static final class AnnotationProvider
205 extends AbstractProvider implements DeviceProvider {
206 private AnnotationProvider() {
207 super(PID);
208 }
209
210 @Override
211 public void triggerProbe(DeviceId deviceId) {
212 }
213
214 @Override
215 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
216 }
217
218 @Override
219 public boolean isReachable(DeviceId deviceId) {
220 return false;
221 }
222 }
223
alshabib0ccde6d2015-05-30 18:22:36 -0700224}