blob: ab03c0b279b44c3bad9263b2bedbe46e09a60106 [file] [log] [blame]
alshabibf0e7e702015-05-30 18:22:36 -07001/*
2 * Copyright 2014 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 */
Srikanth Vavilapalli2e684912016-01-16 19:21:59 -080016package org.onosproject.olt.impl;
alshabibf0e7e702015-05-30 18:22:36 -070017
alshabibbf23a1f2016-01-14 17:27:11 -080018import com.google.common.collect.Maps;
19import com.google.common.collect.Sets;
alshabibf0e7e702015-05-30 18:22:36 -070020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
alshabibe0559672016-02-21 14:49:51 -080023import org.apache.felix.scr.annotations.Modified;
24import org.apache.felix.scr.annotations.Property;
alshabibf0e7e702015-05-30 18:22:36 -070025import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
Jonathan Harte533a422015-10-20 17:31:24 -070027import org.apache.felix.scr.annotations.Service;
alshabibdec2e252016-01-15 12:20:25 -080028import org.onlab.packet.EthType;
alshabibf0e7e702015-05-30 18:22:36 -070029import org.onlab.packet.VlanId;
alshabibe0559672016-02-21 14:49:51 -080030import org.onosproject.cfg.ComponentConfigService;
alshabibf0e7e702015-05-30 18:22:36 -070031import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreService;
alshabib8e4fd2f2016-01-12 15:55:53 -080033import org.onosproject.event.AbstractListenerManager;
Jonathan Harte533a422015-10-20 17:31:24 -070034import org.onosproject.net.ConnectPoint;
alshabibf0e7e702015-05-30 18:22:36 -070035import org.onosproject.net.DeviceId;
alshabibdec2e252016-01-15 12:20:25 -080036import org.onosproject.net.Port;
alshabibf0e7e702015-05-30 18:22:36 -070037import org.onosproject.net.PortNumber;
Jonathan Harte533a422015-10-20 17:31:24 -070038import org.onosproject.net.config.ConfigFactory;
39import org.onosproject.net.config.NetworkConfigEvent;
40import org.onosproject.net.config.NetworkConfigListener;
41import org.onosproject.net.config.NetworkConfigRegistry;
42import org.onosproject.net.config.basics.SubjectFactories;
alshabibf0e7e702015-05-30 18:22:36 -070043import org.onosproject.net.device.DeviceEvent;
44import org.onosproject.net.device.DeviceListener;
45import org.onosproject.net.device.DeviceService;
46import org.onosproject.net.flow.DefaultTrafficSelector;
47import org.onosproject.net.flow.DefaultTrafficTreatment;
48import org.onosproject.net.flow.TrafficSelector;
49import org.onosproject.net.flow.TrafficTreatment;
alshabibdec2e252016-01-15 12:20:25 -080050import org.onosproject.net.flow.criteria.Criteria;
51import org.onosproject.net.flowobjective.DefaultFilteringObjective;
alshabibf0e7e702015-05-30 18:22:36 -070052import org.onosproject.net.flowobjective.DefaultForwardingObjective;
alshabibdec2e252016-01-15 12:20:25 -080053import org.onosproject.net.flowobjective.FilteringObjective;
alshabibf0e7e702015-05-30 18:22:36 -070054import org.onosproject.net.flowobjective.FlowObjectiveService;
55import org.onosproject.net.flowobjective.ForwardingObjective;
alshabib3ea82642016-01-12 18:06:53 -080056import org.onosproject.net.flowobjective.Objective;
57import org.onosproject.net.flowobjective.ObjectiveContext;
58import org.onosproject.net.flowobjective.ObjectiveError;
alshabib000b6fc2016-02-01 17:25:00 -080059import org.onosproject.olt.AccessDeviceConfig;
60import org.onosproject.olt.AccessDeviceData;
Srikanth Vavilapalli2e684912016-01-16 19:21:59 -080061import org.onosproject.olt.AccessDeviceEvent;
62import org.onosproject.olt.AccessDeviceListener;
63import org.onosproject.olt.AccessDeviceService;
alshabibe0559672016-02-21 14:49:51 -080064import org.osgi.service.component.ComponentContext;
alshabibf0e7e702015-05-30 18:22:36 -070065import org.slf4j.Logger;
66
alshabibe0559672016-02-21 14:49:51 -080067import java.util.Dictionary;
alshabibbb83aa22016-02-10 15:08:23 -080068import java.util.List;
Jonathan Harte533a422015-10-20 17:31:24 -070069import java.util.Map;
Jonathan Hart52998382015-11-10 16:09:22 -080070import java.util.Optional;
alshabibe0559672016-02-21 14:49:51 -080071import java.util.Properties;
alshabibbf23a1f2016-01-14 17:27:11 -080072import java.util.Set;
alshabib3ea82642016-01-12 18:06:53 -080073import java.util.concurrent.CompletableFuture;
Jonathan Harte533a422015-10-20 17:31:24 -070074import java.util.concurrent.ConcurrentHashMap;
alshabib3ea82642016-01-12 18:06:53 -080075import java.util.concurrent.ExecutorService;
76import java.util.concurrent.Executors;
alshabibf0e7e702015-05-30 18:22:36 -070077
alshabibe0559672016-02-21 14:49:51 -080078import static com.google.common.base.Strings.isNullOrEmpty;
79import static org.onlab.util.Tools.get;
alshabib3ea82642016-01-12 18:06:53 -080080import static org.onlab.util.Tools.groupedThreads;
alshabibf0e7e702015-05-30 18:22:36 -070081import static org.slf4j.LoggerFactory.getLogger;
82
83/**
Jonathan Harte533a422015-10-20 17:31:24 -070084 * Provisions rules on access devices.
alshabibf0e7e702015-05-30 18:22:36 -070085 */
Jonathan Harte533a422015-10-20 17:31:24 -070086@Service
alshabibf0e7e702015-05-30 18:22:36 -070087@Component(immediate = true)
alshabib8e4fd2f2016-01-12 15:55:53 -080088public class Olt
89 extends AbstractListenerManager<AccessDeviceEvent, AccessDeviceListener>
90 implements AccessDeviceService {
alshabibe0559672016-02-21 14:49:51 -080091
92 private static final short DEFAULT_VLAN = 0;
93
alshabibf0e7e702015-05-30 18:22:36 -070094 private final Logger log = getLogger(getClass());
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected FlowObjectiveService flowObjectiveService;
98
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 protected DeviceService deviceService;
101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected CoreService coreService;
104
Jonathan Harte533a422015-10-20 17:31:24 -0700105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 protected NetworkConfigRegistry networkConfig;
107
alshabibe0559672016-02-21 14:49:51 -0800108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 protected ComponentConfigService componentConfigService;
110
111
112 @Property(name = "defaultVlan", intValue = DEFAULT_VLAN,
113 label = "Default VLAN RG<->ONU traffic")
114 private int defaultVlan = DEFAULT_VLAN;
115
alshabibf0e7e702015-05-30 18:22:36 -0700116 private final DeviceListener deviceListener = new InternalDeviceListener();
117
118 private ApplicationId appId;
119
alshabib3ea82642016-01-12 18:06:53 -0800120 private ExecutorService oltInstallers = Executors.newFixedThreadPool(4,
alshabibbf23a1f2016-01-14 17:27:11 -0800121 groupedThreads("onos/olt-service",
122 "olt-installer-%d"));
alshabib4ae2b402015-06-05 14:55:24 -0700123
Jonathan Harte533a422015-10-20 17:31:24 -0700124 private Map<DeviceId, AccessDeviceData> oltData = new ConcurrentHashMap<>();
125
alshabibbf23a1f2016-01-14 17:27:11 -0800126 private Map<ConnectPoint, Set<ForwardingObjective.Builder>> objectives =
127 Maps.newConcurrentMap();
128
129 private Map<ConnectPoint, VlanId> subscribers = Maps.newConcurrentMap();
130
Jonathan Harte533a422015-10-20 17:31:24 -0700131 private InternalNetworkConfigListener configListener =
132 new InternalNetworkConfigListener();
133 private static final Class<AccessDeviceConfig> CONFIG_CLASS =
134 AccessDeviceConfig.class;
135
136 private ConfigFactory<DeviceId, AccessDeviceConfig> configFactory =
137 new ConfigFactory<DeviceId, AccessDeviceConfig>(
138 SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") {
alshabibbf23a1f2016-01-14 17:27:11 -0800139 @Override
140 public AccessDeviceConfig createConfig() {
141 return new AccessDeviceConfig();
142 }
143 };
144
alshabibf0e7e702015-05-30 18:22:36 -0700145
146 @Activate
alshabibe0559672016-02-21 14:49:51 -0800147 public void activate(ComponentContext context) {
148 modified(context);
alshabib4ae2b402015-06-05 14:55:24 -0700149 appId = coreService.registerApplication("org.onosproject.olt");
alshabibe0559672016-02-21 14:49:51 -0800150 componentConfigService.registerProperties(getClass());
alshabibc4dfe852015-06-05 13:35:13 -0700151
alshabib8e4fd2f2016-01-12 15:55:53 -0800152 eventDispatcher.addSink(AccessDeviceEvent.class, listenerRegistry);
153
Jonathan Harte533a422015-10-20 17:31:24 -0700154 networkConfig.registerConfigFactory(configFactory);
155 networkConfig.addListener(configListener);
156
alshabibdec2e252016-01-15 12:20:25 -0800157
Jonathan Harte533a422015-10-20 17:31:24 -0700158 networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach(
159 subject -> {
160 AccessDeviceConfig config = networkConfig.getConfig(subject, AccessDeviceConfig.class);
161 if (config != null) {
162 AccessDeviceData data = config.getOlt();
163 oltData.put(data.deviceId(), data);
164 }
165 }
166 );
167
alshabibdec2e252016-01-15 12:20:25 -0800168 oltData.keySet().stream()
169 .flatMap(did -> deviceService.getPorts(did).stream())
alshabib62e9ce72016-02-11 17:31:36 -0800170 .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number()))
alshabibdec2e252016-01-15 12:20:25 -0800171 .filter(p -> p.isEnabled())
alshabib50d9fc52016-02-12 15:47:20 -0800172 .forEach(p -> processFilteringObjectives((DeviceId) p.element().id(),
173 p.number(), true));
alshabibdec2e252016-01-15 12:20:25 -0800174
alshabibba357492016-01-27 13:49:46 -0800175 deviceService.addListener(deviceListener);
176
alshabibf0e7e702015-05-30 18:22:36 -0700177 log.info("Started with Application ID {}", appId.id());
178 }
179
180 @Deactivate
181 public void deactivate() {
alshabibe0559672016-02-21 14:49:51 -0800182 componentConfigService.unregisterProperties(getClass(), false);
alshabib62e9ce72016-02-11 17:31:36 -0800183 deviceService.removeListener(deviceListener);
Jonathan Harte533a422015-10-20 17:31:24 -0700184 networkConfig.removeListener(configListener);
185 networkConfig.unregisterConfigFactory(configFactory);
alshabibf0e7e702015-05-30 18:22:36 -0700186 log.info("Stopped");
187 }
188
alshabibe0559672016-02-21 14:49:51 -0800189 @Modified
190 public void modified(ComponentContext context) {
191 Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
192
193 try {
194 String s = get(properties, "defaultVlan");
195 defaultVlan = isNullOrEmpty(s) ? DEFAULT_VLAN : Integer.parseInt(s.trim());
196 } catch (Exception e) {
197 defaultVlan = DEFAULT_VLAN;
198 }
199 }
200
201 @Override
Jonathan Harte533a422015-10-20 17:31:24 -0700202 public void provisionSubscriber(ConnectPoint port, VlanId vlan) {
203 AccessDeviceData olt = oltData.get(port.deviceId());
204
205 if (olt == null) {
206 log.warn("No data found for OLT device {}", port.deviceId());
207 return;
208 }
209
Jonathan Hart52998382015-11-10 16:09:22 -0800210 provisionVlans(olt.deviceId(), olt.uplink(), port.port(), vlan, olt.vlan(),
alshabibb7a9e172016-01-13 11:23:53 -0800211 olt.defaultVlan());
212 }
213
214 @Override
215 public void removeSubscriber(ConnectPoint port) {
alshabibbf23a1f2016-01-14 17:27:11 -0800216 AccessDeviceData olt = oltData.get(port.deviceId());
217
218 if (olt == null) {
219 log.warn("No data found for OLT device {}", port.deviceId());
220 return;
221 }
222
223 unprovisionSubscriber(olt.deviceId(), olt.uplink(), port.port(), olt.vlan());
224
225 }
226
alshabibe0559672016-02-21 14:49:51 -0800227 @Override
228 public Map<DeviceId, AccessDeviceData> fetchOlts() {
229 return Maps.newHashMap(oltData);
230 }
231
alshabibbf23a1f2016-01-14 17:27:11 -0800232 private void unprovisionSubscriber(DeviceId deviceId, PortNumber uplink,
233 PortNumber subscriberPort, VlanId deviceVlan) {
234
235 //FIXME: This method is slightly ugly but it'll do until we have a better
236 // way to remove flows from the flow store.
237
238 CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
239 CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
240
241 ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
242
243 VlanId subscriberVlan = subscribers.remove(cp);
244
245 Set<ForwardingObjective.Builder> fwds = objectives.remove(cp);
246
247 if (fwds == null || fwds.size() != 2) {
248 log.warn("Unknown or incomplete subscriber at {}", cp);
249 return;
250 }
251
252
253 fwds.stream().forEach(
254 fwd -> flowObjectiveService.forward(deviceId,
alshabibdec2e252016-01-15 12:20:25 -0800255 fwd.remove(new ObjectiveContext() {
256 @Override
257 public void onSuccess(Objective objective) {
258 upFuture.complete(null);
259 }
alshabibbf23a1f2016-01-14 17:27:11 -0800260
alshabibdec2e252016-01-15 12:20:25 -0800261 @Override
262 public void onError(Objective objective, ObjectiveError error) {
263 upFuture.complete(error);
264 }
265 })));
alshabibbf23a1f2016-01-14 17:27:11 -0800266
267 upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
268 if (upStatus == null && downStatus == null) {
269 post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_UNREGISTERED,
270 deviceId,
271 deviceVlan,
272 subscriberVlan));
273 } else if (downStatus != null) {
274 log.error("Subscriber with vlan {} on device {} " +
275 "on port {} failed downstream uninstallation: {}",
276 subscriberVlan, deviceId, subscriberPort, downStatus);
277 } else if (upStatus != null) {
278 log.error("Subscriber with vlan {} on device {} " +
279 "on port {} failed upstream uninstallation: {}",
280 subscriberVlan, deviceId, subscriberPort, upStatus);
281 }
282 }, oltInstallers);
alshabibb7a9e172016-01-13 11:23:53 -0800283
Jonathan Harte533a422015-10-20 17:31:24 -0700284 }
285
286 private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort,
287 PortNumber subscriberPort,
Jonathan Hart52998382015-11-10 16:09:22 -0800288 VlanId subscriberVlan, VlanId deviceVlan,
289 Optional<VlanId> defaultVlan) {
Jonathan Harte533a422015-10-20 17:31:24 -0700290
alshabib3ea82642016-01-12 18:06:53 -0800291 CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
292 CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
293
Jonathan Harte533a422015-10-20 17:31:24 -0700294 TrafficSelector upstream = DefaultTrafficSelector.builder()
alshabibe0559672016-02-21 14:49:51 -0800295 .matchVlanId(defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan)))
Jonathan Harte533a422015-10-20 17:31:24 -0700296 .matchInPort(subscriberPort)
297 .build();
298
299 TrafficSelector downstream = DefaultTrafficSelector.builder()
300 .matchVlanId(deviceVlan)
301 .matchInPort(uplinkPort)
alshabibb7a9e172016-01-13 11:23:53 -0800302 .matchInnerVlanId(subscriberVlan)
Jonathan Harte533a422015-10-20 17:31:24 -0700303 .build();
304
305 TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder()
alshabib3ea82642016-01-12 18:06:53 -0800306 .pushVlan()
Jonathan Harte533a422015-10-20 17:31:24 -0700307 .setVlanId(subscriberVlan)
308 .pushVlan()
309 .setVlanId(deviceVlan)
310 .setOutput(uplinkPort)
311 .build();
312
313 TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder()
314 .popVlan()
alshabibe0559672016-02-21 14:49:51 -0800315 .setVlanId(defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan)))
Jonathan Harte533a422015-10-20 17:31:24 -0700316 .setOutput(subscriberPort)
317 .build();
318
319
alshabibbf23a1f2016-01-14 17:27:11 -0800320 ForwardingObjective.Builder upFwd = DefaultForwardingObjective.builder()
Jonathan Harte533a422015-10-20 17:31:24 -0700321 .withFlag(ForwardingObjective.Flag.VERSATILE)
322 .withPriority(1000)
323 .makePermanent()
324 .withSelector(upstream)
325 .fromApp(appId)
alshabibbf23a1f2016-01-14 17:27:11 -0800326 .withTreatment(upstreamTreatment);
alshabib3ea82642016-01-12 18:06:53 -0800327
Jonathan Harte533a422015-10-20 17:31:24 -0700328
alshabibbf23a1f2016-01-14 17:27:11 -0800329 ForwardingObjective.Builder downFwd = DefaultForwardingObjective.builder()
Jonathan Harte533a422015-10-20 17:31:24 -0700330 .withFlag(ForwardingObjective.Flag.VERSATILE)
331 .withPriority(1000)
332 .makePermanent()
333 .withSelector(downstream)
334 .fromApp(appId)
alshabibbf23a1f2016-01-14 17:27:11 -0800335 .withTreatment(downstreamTreatment);
alshabib3ea82642016-01-12 18:06:53 -0800336
alshabibbf23a1f2016-01-14 17:27:11 -0800337 ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
Jonathan Harte533a422015-10-20 17:31:24 -0700338
alshabibbf23a1f2016-01-14 17:27:11 -0800339 subscribers.put(cp, subscriberVlan);
340 objectives.put(cp, Sets.newHashSet(upFwd, downFwd));
341
342
343 flowObjectiveService.forward(deviceId, upFwd.add(new ObjectiveContext() {
344 @Override
345 public void onSuccess(Objective objective) {
346 upFuture.complete(null);
347 }
348
349 @Override
350 public void onError(Objective objective, ObjectiveError error) {
351 upFuture.complete(error);
352 }
353 }));
354
355
356 flowObjectiveService.forward(deviceId, downFwd.add(new ObjectiveContext() {
357 @Override
358 public void onSuccess(Objective objective) {
359 downFuture.complete(null);
360 }
361
362 @Override
363 public void onError(Objective objective, ObjectiveError error) {
364 downFuture.complete(error);
365 }
366 }));
alshabib3ea82642016-01-12 18:06:53 -0800367
368 upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
369 if (upStatus == null && downStatus == null) {
370 post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_REGISTERED,
371 deviceId,
372 deviceVlan,
373 subscriberVlan));
alshabib50d9fc52016-02-12 15:47:20 -0800374
alshabib3ea82642016-01-12 18:06:53 -0800375 } else if (downStatus != null) {
376 log.error("Subscriber with vlan {} on device {} " +
377 "on port {} failed downstream installation: {}",
378 subscriberVlan, deviceId, subscriberPort, downStatus);
379 } else if (upStatus != null) {
380 log.error("Subscriber with vlan {} on device {} " +
381 "on port {} failed upstream installation: {}",
382 subscriberVlan, deviceId, subscriberPort, upStatus);
383 }
384 }, oltInstallers);
385
Jonathan Harte533a422015-10-20 17:31:24 -0700386 }
387
alshabib50d9fc52016-02-12 15:47:20 -0800388 private void processFilteringObjectives(DeviceId devId, PortNumber port, boolean install) {
alshabibbb83aa22016-02-10 15:08:23 -0800389 DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
390
391 FilteringObjective eapol = (install ? builder.permit() : builder.deny())
alshabib50d9fc52016-02-12 15:47:20 -0800392 .withKey(Criteria.matchInPort(port))
alshabibdec2e252016-01-15 12:20:25 -0800393 .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
394 .withMeta(DefaultTrafficTreatment.builder()
395 .setOutput(PortNumber.CONTROLLER).build())
396 .fromApp(appId)
397 .withPriority(1000)
398 .add(new ObjectiveContext() {
399 @Override
400 public void onSuccess(Objective objective) {
401 log.info("Eapol filter for {} on {} installed.",
402 devId, port);
403 }
404
405 @Override
406 public void onError(Objective objective, ObjectiveError error) {
407 log.info("Eapol filter for {} on {} failed because {}",
408 devId, port, error);
409 }
410 });
411
alshabibdec2e252016-01-15 12:20:25 -0800412 flowObjectiveService.filter(devId, eapol);
alshabib000b6fc2016-02-01 17:25:00 -0800413
alshabibdec2e252016-01-15 12:20:25 -0800414 }
415
alshabibf0e7e702015-05-30 18:22:36 -0700416 private class InternalDeviceListener implements DeviceListener {
417 @Override
418 public void event(DeviceEvent event) {
alshabib3ea82642016-01-12 18:06:53 -0800419 DeviceId devId = event.subject().id();
420 if (!oltData.containsKey(devId)) {
421 log.debug("Device {} is not an OLT", devId);
alshabib8e4fd2f2016-01-12 15:55:53 -0800422 return;
423 }
alshabibf0e7e702015-05-30 18:22:36 -0700424 switch (event.type()) {
alshabibdec2e252016-01-15 12:20:25 -0800425 //TODO: Port handling and bookkeeping should be inproved once
426 // olt firmware handles correct behaviour.
alshabibf0e7e702015-05-30 18:22:36 -0700427 case PORT_ADDED:
alshabibbb83aa22016-02-10 15:08:23 -0800428 if (!oltData.get(devId).uplink().equals(event.port().number()) &&
429 event.port().isEnabled()) {
alshabib50d9fc52016-02-12 15:47:20 -0800430 processFilteringObjectives(devId, event.port().number(), true);
alshabibdec2e252016-01-15 12:20:25 -0800431 }
432 break;
433 case PORT_REMOVED:
434 AccessDeviceData olt = oltData.get(devId);
435 unprovisionSubscriber(devId, olt.uplink(),
436 event.port().number(),
437 olt.vlan());
alshabibbb83aa22016-02-10 15:08:23 -0800438 if (!oltData.get(devId).uplink().equals(event.port().number()) &&
439 event.port().isEnabled()) {
alshabib50d9fc52016-02-12 15:47:20 -0800440 processFilteringObjectives(devId, event.port().number(), false);
alshabibbb83aa22016-02-10 15:08:23 -0800441 }
alshabibdec2e252016-01-15 12:20:25 -0800442 break;
alshabibf0e7e702015-05-30 18:22:36 -0700443 case PORT_UPDATED:
alshabibbb83aa22016-02-10 15:08:23 -0800444 if (oltData.get(devId).uplink().equals(event.port().number())) {
445 break;
446 }
447 if (event.port().isEnabled()) {
alshabib50d9fc52016-02-12 15:47:20 -0800448 processFilteringObjectives(devId, event.port().number(), true);
alshabibbb83aa22016-02-10 15:08:23 -0800449 } else {
alshabib50d9fc52016-02-12 15:47:20 -0800450 processFilteringObjectives(devId, event.port().number(), false);
alshabibbb83aa22016-02-10 15:08:23 -0800451 }
alshabibf0e7e702015-05-30 18:22:36 -0700452 break;
453 case DEVICE_ADDED:
alshabib8e4fd2f2016-01-12 15:55:53 -0800454 post(new AccessDeviceEvent(
455 AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
456 null, null));
alshabibe0559672016-02-21 14:49:51 -0800457 provisionDefaultFlows(devId);
alshabib8e4fd2f2016-01-12 15:55:53 -0800458 break;
alshabibf0e7e702015-05-30 18:22:36 -0700459 case DEVICE_REMOVED:
alshabib8e4fd2f2016-01-12 15:55:53 -0800460 post(new AccessDeviceEvent(
461 AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
462 null, null));
463 break;
alshabib7c190012016-02-09 18:22:33 -0800464 case DEVICE_AVAILABILITY_CHANGED:
465 if (deviceService.isAvailable(devId)) {
466 post(new AccessDeviceEvent(
467 AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
468 null, null));
469 } else {
470 post(new AccessDeviceEvent(
471 AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
472 null, null));
473 }
474 break;
alshabib8e4fd2f2016-01-12 15:55:53 -0800475 case DEVICE_UPDATED:
alshabibf0e7e702015-05-30 18:22:36 -0700476 case DEVICE_SUSPENDED:
alshabibf0e7e702015-05-30 18:22:36 -0700477 case PORT_STATS_UPDATED:
478 default:
479 return;
480 }
481 }
482 }
483
Jonathan Harte533a422015-10-20 17:31:24 -0700484 private class InternalNetworkConfigListener implements NetworkConfigListener {
485 @Override
486 public void event(NetworkConfigEvent event) {
487 switch (event.type()) {
488
alshabibbf23a1f2016-01-14 17:27:11 -0800489 case CONFIG_ADDED:
490 case CONFIG_UPDATED:
alshabibe0559672016-02-21 14:49:51 -0800491
492 AccessDeviceConfig config =
493 networkConfig.getConfig((DeviceId) event.subject(), CONFIG_CLASS);
494 if (config != null) {
495 oltData.put(config.getOlt().deviceId(), config.getOlt());
496 provisionDefaultFlows((DeviceId) event.subject());
Jonathan Harte533a422015-10-20 17:31:24 -0700497 }
alshabibe0559672016-02-21 14:49:51 -0800498
alshabibbf23a1f2016-01-14 17:27:11 -0800499 break;
alshabibe0559672016-02-21 14:49:51 -0800500 case CONFIG_REGISTERED:
alshabibbf23a1f2016-01-14 17:27:11 -0800501 case CONFIG_UNREGISTERED:
alshabibe0559672016-02-21 14:49:51 -0800502 break;
alshabibbf23a1f2016-01-14 17:27:11 -0800503 case CONFIG_REMOVED:
alshabibe0559672016-02-21 14:49:51 -0800504 oltData.remove(event.subject());
alshabibbf23a1f2016-01-14 17:27:11 -0800505 default:
506 break;
Jonathan Harte533a422015-10-20 17:31:24 -0700507 }
508 }
alshabibe0559672016-02-21 14:49:51 -0800509
510 @Override
511 public boolean isRelevant(NetworkConfigEvent event) {
512 return event.configClass().equals(CONFIG_CLASS);
513 }
Jonathan Harte533a422015-10-20 17:31:24 -0700514 }
alshabibf0e7e702015-05-30 18:22:36 -0700515
alshabibbb83aa22016-02-10 15:08:23 -0800516 private void provisionDefaultFlows(DeviceId deviceId) {
517 List<Port> ports = deviceService.getPorts(deviceId);
518
519 ports.stream()
520 .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number()))
521 .filter(p -> p.isEnabled())
alshabib50d9fc52016-02-12 15:47:20 -0800522 .forEach(p -> processFilteringObjectives((DeviceId) p.element().id(),
523 p.number(), true));
alshabibbb83aa22016-02-10 15:08:23 -0800524
525 }
526
alshabibf0e7e702015-05-30 18:22:36 -0700527}