blob: c735af3f62e04e1fdd573ec311d20f7e95eb8ebc [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;
Jonathan Hartdfc3b862015-07-01 14:49:56 -070019import org.onlab.packet.EthType;
20import org.onosproject.core.ApplicationId;
21import org.onosproject.core.CoreService;
alshabib2cc73cb2015-06-30 20:26:56 -070022import org.onosproject.net.DefaultAnnotations;
23import org.onosproject.net.Device;
alshabib0ccde6d2015-05-30 18:22:36 -070024import org.onosproject.net.DeviceId;
alshabib2cc73cb2015-06-30 20:26:56 -070025import org.onosproject.net.MastershipRole;
alshabib0ccde6d2015-05-30 18:22:36 -070026import org.onosproject.net.PortNumber;
27import org.onosproject.net.behaviour.Pipeliner;
28import org.onosproject.net.behaviour.PipelinerContext;
alshabib2cc73cb2015-06-30 20:26:56 -070029import org.onosproject.net.device.DefaultDeviceDescription;
30import org.onosproject.net.device.DeviceDescription;
31import org.onosproject.net.device.DeviceProvider;
32import org.onosproject.net.device.DeviceProviderRegistry;
alshabib2cc73cb2015-06-30 20:26:56 -070033import org.onosproject.net.device.DeviceService;
alshabib0ccde6d2015-05-30 18:22:36 -070034import org.onosproject.net.driver.AbstractHandlerBehaviour;
35import org.onosproject.net.flow.DefaultFlowRule;
Jonathan Hartdfc3b862015-07-01 14:49:56 -070036import org.onosproject.net.flow.DefaultTrafficSelector;
alshabib0ccde6d2015-05-30 18:22:36 -070037import org.onosproject.net.flow.DefaultTrafficTreatment;
38import org.onosproject.net.flow.FlowRule;
39import org.onosproject.net.flow.FlowRuleOperations;
40import org.onosproject.net.flow.FlowRuleOperationsContext;
41import org.onosproject.net.flow.FlowRuleService;
42import org.onosproject.net.flow.TrafficSelector;
43import org.onosproject.net.flow.TrafficTreatment;
44import org.onosproject.net.flow.instructions.Instructions;
45import org.onosproject.net.flowobjective.FilteringObjective;
46import org.onosproject.net.flowobjective.ForwardingObjective;
47import org.onosproject.net.flowobjective.NextObjective;
48import org.onosproject.net.flowobjective.ObjectiveError;
Jonathan Hartdfc3b862015-07-01 14:49:56 -070049import org.onosproject.net.packet.PacketPriority;
alshabib2cc73cb2015-06-30 20:26:56 -070050import org.onosproject.net.provider.AbstractProvider;
51import org.onosproject.net.provider.ProviderId;
alshabib0ccde6d2015-05-30 18:22:36 -070052import org.slf4j.Logger;
53
alshabib2cc73cb2015-06-30 20:26:56 -070054import static com.google.common.base.Preconditions.checkNotNull;
alshabib0ccde6d2015-05-30 18:22:36 -070055import static org.slf4j.LoggerFactory.getLogger;
56
57/**
Jonathan Hart64da69d2015-07-15 15:10:28 -070058 * Pipeliner for OLT device.
alshabib0ccde6d2015-05-30 18:22:36 -070059 */
60public class OLTPipeline extends AbstractHandlerBehaviour implements Pipeliner {
61
62 private final Logger log = getLogger(getClass());
63
alshabib2cc73cb2015-06-30 20:26:56 -070064 static final ProviderId PID = new ProviderId("olt", "org.onosproject.olt", true);
65
66 static final String DEVICE = "isAccess";
67 static final String OLT = "true";
68
alshabib0ccde6d2015-05-30 18:22:36 -070069 private ServiceDirectory serviceDirectory;
70 private FlowRuleService flowRuleService;
71 private DeviceId deviceId;
Jonathan Hartdfc3b862015-07-01 14:49:56 -070072 private CoreService coreService;
73
74 private ApplicationId appId;
alshabib0ccde6d2015-05-30 18:22:36 -070075
alshabib2cc73cb2015-06-30 20:26:56 -070076 private DeviceProvider provider = new AnnotationProvider();
77
alshabibb32cefe2015-06-08 18:15:05 -070078
alshabib0ccde6d2015-05-30 18:22:36 -070079 @Override
80 public void init(DeviceId deviceId, PipelinerContext context) {
81 this.serviceDirectory = context.directory();
82 this.deviceId = deviceId;
alshabib2cc73cb2015-06-30 20:26:56 -070083 DeviceProviderRegistry registry =
84 serviceDirectory.get(DeviceProviderRegistry.class);
alshabib0ccde6d2015-05-30 18:22:36 -070085 flowRuleService = serviceDirectory.get(FlowRuleService.class);
Jonathan Hartdfc3b862015-07-01 14:49:56 -070086 coreService = serviceDirectory.get(CoreService.class);
alshabibb32cefe2015-06-08 18:15:05 -070087
Jonathan Hart3e594642015-10-20 17:31:24 -070088 /*try {
alshabib2cc73cb2015-06-30 20:26:56 -070089 DeviceProviderService providerService = registry.register(provider);
90 providerService.deviceConnected(deviceId,
91 description(deviceId, DEVICE, OLT));
92 } finally {
93 registry.unregister(provider);
Jonathan Hart3e594642015-10-20 17:31:24 -070094 }*/
alshabib2cc73cb2015-06-30 20:26:56 -070095
Jonathan Hartdfc3b862015-07-01 14:49:56 -070096 appId = coreService.registerApplication(
97 "org.onosproject.driver.OLTPipeline");
98
99 TrafficSelector selector = DefaultTrafficSelector.builder()
100 .matchEthType(EthType.EtherType.EAPOL.ethType().toShort())
101 .build();
102
103 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
104 .punt()
105 .build();
106
107 FlowRule flowRule = new DefaultFlowRule(deviceId, selector, treatment,
108 PacketPriority.CONTROL.priorityValue(),
109 appId, 0, true, null);
110
Jonathan Hart3e594642015-10-20 17:31:24 -0700111 //flowRuleService.applyFlowRules(flowRule);
alshabibb32cefe2015-06-08 18:15:05 -0700112 }
113
alshabib0ccde6d2015-05-30 18:22:36 -0700114 @Override
115 public void filter(FilteringObjective filter) {
Jonathan Hart3e594642015-10-20 17:31:24 -0700116 throw new UnsupportedOperationException("OLT does not filter.");
alshabib0ccde6d2015-05-30 18:22:36 -0700117 }
118
119 @Override
120 public void forward(ForwardingObjective fwd) {
alshabib0ccde6d2015-05-30 18:22:36 -0700121 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
122
123 if (fwd.flag() != ForwardingObjective.Flag.VERSATILE) {
124 throw new UnsupportedOperationException(
125 "Only VERSATILE is supported.");
126 }
127
128 boolean isPunt = fwd.treatment().immediate().stream().anyMatch(i -> {
129 if (i instanceof Instructions.OutputInstruction) {
130 Instructions.OutputInstruction out = (Instructions.OutputInstruction) i;
131 return out.port().equals(PortNumber.CONTROLLER);
132 }
133 return false;
134 });
135
136 if (isPunt) {
137 return;
138 }
139
140 TrafficSelector selector = fwd.selector();
141 TrafficTreatment treatment = fwd.treatment();
alshabib0ccde6d2015-05-30 18:22:36 -0700142
143 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
144 .forDevice(deviceId)
145 .withSelector(selector)
Jonathan Hart3e594642015-10-20 17:31:24 -0700146 .withTreatment(treatment)
alshabib0ccde6d2015-05-30 18:22:36 -0700147 .fromApp(fwd.appId())
148 .withPriority(fwd.priority());
149
150 if (fwd.permanent()) {
151 ruleBuilder.makePermanent();
152 } else {
153 ruleBuilder.makeTemporary(fwd.timeout());
154 }
155
alshabib0ccde6d2015-05-30 18:22:36 -0700156 switch (fwd.op()) {
alshabib0ccde6d2015-05-30 18:22:36 -0700157 case ADD:
158 flowBuilder.add(ruleBuilder.build());
159 break;
160 case REMOVE:
161 flowBuilder.remove(ruleBuilder.build());
162 break;
163 default:
164 log.warn("Unknown operation {}", fwd.op());
165 }
166
167 flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
168 @Override
169 public void onSuccess(FlowRuleOperations ops) {
170 if (fwd.context().isPresent()) {
171 fwd.context().get().onSuccess(fwd);
172 }
173 }
174
175 @Override
176 public void onError(FlowRuleOperations ops) {
177 if (fwd.context().isPresent()) {
178 fwd.context().get().onError(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
179 }
180 }
181 }));
alshabib0ccde6d2015-05-30 18:22:36 -0700182 }
183
184 @Override
185 public void next(NextObjective nextObjective) {
Jonathan Hart3e594642015-10-20 17:31:24 -0700186 throw new UnsupportedOperationException("OLT does not next hop.");
alshabib0ccde6d2015-05-30 18:22:36 -0700187 }
188
alshabib2cc73cb2015-06-30 20:26:56 -0700189 /**
190 * Build a device description.
Jonathan Hart3e594642015-10-20 17:31:24 -0700191 *
alshabib2cc73cb2015-06-30 20:26:56 -0700192 * @param deviceId a deviceId
193 * @param key the key of the annotation
194 * @param value the value for the annotation
195 * @return a device description
196 */
197 private DeviceDescription description(DeviceId deviceId, String key, String value) {
198 DeviceService deviceService = serviceDirectory.get(DeviceService.class);
199 Device device = deviceService.getDevice(deviceId);
200
201 checkNotNull(device, "Device not found in device service.");
202
203 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
204 if (value != null) {
205 builder.set(key, value);
206 } else {
207 builder.remove(key);
208 }
209 return new DefaultDeviceDescription(device.id().uri(), device.type(),
210 device.manufacturer(), device.hwVersion(),
211 device.swVersion(), device.serialNumber(),
212 device.chassisId(), builder.build());
213 }
214
215 /**
216 * Simple ancillary provider used to annotate device.
217 */
218 private static final class AnnotationProvider
219 extends AbstractProvider implements DeviceProvider {
220 private AnnotationProvider() {
221 super(PID);
222 }
223
224 @Override
225 public void triggerProbe(DeviceId deviceId) {
226 }
227
228 @Override
229 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
230 }
231
232 @Override
233 public boolean isReachable(DeviceId deviceId) {
234 return false;
235 }
236 }
237
alshabib0ccde6d2015-05-30 18:22:36 -0700238}