blob: 301039fd4292d3e47f4df07cb977483498d19f9c [file] [log] [blame]
alshabib0ccde6d2015-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 Vavilapalli0d21dd12016-01-16 19:21:59 -080016package org.onosproject.olt.impl;
alshabib0ccde6d2015-05-30 18:22:36 -070017
alshabib02cbe6a2016-01-14 17:27:11 -080018import com.google.common.collect.Maps;
19import com.google.common.collect.Sets;
alshabib0ccde6d2015-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;
alshabibf544c012016-02-21 14:49:51 -080023import org.apache.felix.scr.annotations.Modified;
24import org.apache.felix.scr.annotations.Property;
alshabib0ccde6d2015-05-30 18:22:36 -070025import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
Jonathan Hart3e594642015-10-20 17:31:24 -070027import org.apache.felix.scr.annotations.Service;
alshabibbb424232016-01-15 12:20:25 -080028import org.onlab.packet.EthType;
alshabib0ccde6d2015-05-30 18:22:36 -070029import org.onlab.packet.VlanId;
alshabibf544c012016-02-21 14:49:51 -080030import org.onosproject.cfg.ComponentConfigService;
alshabib0ccde6d2015-05-30 18:22:36 -070031import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreService;
alshabib6b139b42016-01-12 15:55:53 -080033import org.onosproject.event.AbstractListenerManager;
Jonathan Hart3e594642015-10-20 17:31:24 -070034import org.onosproject.net.ConnectPoint;
alshabib0ccde6d2015-05-30 18:22:36 -070035import org.onosproject.net.DeviceId;
alshabibbb424232016-01-15 12:20:25 -080036import org.onosproject.net.Port;
alshabib0ccde6d2015-05-30 18:22:36 -070037import org.onosproject.net.PortNumber;
Jonathan Hart3e594642015-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;
alshabib0ccde6d2015-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;
alshabibbb424232016-01-15 12:20:25 -080050import org.onosproject.net.flow.criteria.Criteria;
51import org.onosproject.net.flowobjective.DefaultFilteringObjective;
alshabib0ccde6d2015-05-30 18:22:36 -070052import org.onosproject.net.flowobjective.DefaultForwardingObjective;
alshabibbb424232016-01-15 12:20:25 -080053import org.onosproject.net.flowobjective.FilteringObjective;
alshabib0ccde6d2015-05-30 18:22:36 -070054import org.onosproject.net.flowobjective.FlowObjectiveService;
55import org.onosproject.net.flowobjective.ForwardingObjective;
alshabib49cadbd2016-01-12 18:06:53 -080056import org.onosproject.net.flowobjective.Objective;
57import org.onosproject.net.flowobjective.ObjectiveContext;
58import org.onosproject.net.flowobjective.ObjectiveError;
alshabib03adb492016-02-01 17:25:00 -080059import org.onosproject.olt.AccessDeviceConfig;
60import org.onosproject.olt.AccessDeviceData;
Srikanth Vavilapalli0d21dd12016-01-16 19:21:59 -080061import org.onosproject.olt.AccessDeviceEvent;
62import org.onosproject.olt.AccessDeviceListener;
63import org.onosproject.olt.AccessDeviceService;
alshabibf544c012016-02-21 14:49:51 -080064import org.osgi.service.component.ComponentContext;
alshabib0ccde6d2015-05-30 18:22:36 -070065import org.slf4j.Logger;
66
alshabibf544c012016-02-21 14:49:51 -080067import java.util.Dictionary;
alshabib8f8060d2016-02-10 15:08:23 -080068import java.util.List;
Jonathan Hart3e594642015-10-20 17:31:24 -070069import java.util.Map;
Jonathan Hart48327842015-11-10 16:09:22 -080070import java.util.Optional;
alshabibf544c012016-02-21 14:49:51 -080071import java.util.Properties;
alshabib02cbe6a2016-01-14 17:27:11 -080072import java.util.Set;
alshabib49cadbd2016-01-12 18:06:53 -080073import java.util.concurrent.CompletableFuture;
Jonathan Hart3e594642015-10-20 17:31:24 -070074import java.util.concurrent.ConcurrentHashMap;
alshabib49cadbd2016-01-12 18:06:53 -080075import java.util.concurrent.ExecutorService;
76import java.util.concurrent.Executors;
alshabib0ccde6d2015-05-30 18:22:36 -070077
alshabibf544c012016-02-21 14:49:51 -080078import static com.google.common.base.Strings.isNullOrEmpty;
79import static org.onlab.util.Tools.get;
alshabib49cadbd2016-01-12 18:06:53 -080080import static org.onlab.util.Tools.groupedThreads;
alshabib0ccde6d2015-05-30 18:22:36 -070081import static org.slf4j.LoggerFactory.getLogger;
82
83/**
Jonathan Hart3e594642015-10-20 17:31:24 -070084 * Provisions rules on access devices.
alshabib0ccde6d2015-05-30 18:22:36 -070085 */
Jonathan Hart3e594642015-10-20 17:31:24 -070086@Service
alshabib0ccde6d2015-05-30 18:22:36 -070087@Component(immediate = true)
alshabib6b139b42016-01-12 15:55:53 -080088public class Olt
89 extends AbstractListenerManager<AccessDeviceEvent, AccessDeviceListener>
90 implements AccessDeviceService {
alshabibf544c012016-02-21 14:49:51 -080091
92 private static final short DEFAULT_VLAN = 0;
93
alshabib0ccde6d2015-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 Hart3e594642015-10-20 17:31:24 -0700105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 protected NetworkConfigRegistry networkConfig;
107
alshabibf544c012016-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
alshabib0ccde6d2015-05-30 18:22:36 -0700116 private final DeviceListener deviceListener = new InternalDeviceListener();
117
118 private ApplicationId appId;
119
alshabib49cadbd2016-01-12 18:06:53 -0800120 private ExecutorService oltInstallers = Executors.newFixedThreadPool(4,
alshabib02cbe6a2016-01-14 17:27:11 -0800121 groupedThreads("onos/olt-service",
122 "olt-installer-%d"));
alshabib1af3b712015-06-05 14:55:24 -0700123
Jonathan Hart3e594642015-10-20 17:31:24 -0700124 private Map<DeviceId, AccessDeviceData> oltData = new ConcurrentHashMap<>();
125
alshabib02cbe6a2016-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 Hart3e594642015-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") {
alshabib02cbe6a2016-01-14 17:27:11 -0800139 @Override
140 public AccessDeviceConfig createConfig() {
141 return new AccessDeviceConfig();
142 }
143 };
144
alshabib0ccde6d2015-05-30 18:22:36 -0700145
146 @Activate
alshabibf544c012016-02-21 14:49:51 -0800147 public void activate(ComponentContext context) {
148 modified(context);
alshabib1af3b712015-06-05 14:55:24 -0700149 appId = coreService.registerApplication("org.onosproject.olt");
alshabibf544c012016-02-21 14:49:51 -0800150 componentConfigService.registerProperties(getClass());
alshabibbeb2dc92015-06-05 13:35:13 -0700151
alshabib6b139b42016-01-12 15:55:53 -0800152 eventDispatcher.addSink(AccessDeviceEvent.class, listenerRegistry);
153
Jonathan Hart3e594642015-10-20 17:31:24 -0700154 networkConfig.registerConfigFactory(configFactory);
155 networkConfig.addListener(configListener);
156
alshabibbb424232016-01-15 12:20:25 -0800157
Jonathan Hart3e594642015-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
alshabibbb424232016-01-15 12:20:25 -0800168 oltData.keySet().stream()
169 .flatMap(did -> deviceService.getPorts(did).stream())
alshabibfe69e9a2016-02-11 17:31:36 -0800170 .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number()))
alshabibbb424232016-01-15 12:20:25 -0800171 .filter(p -> p.isEnabled())
alshabibea9eed92016-02-12 15:47:20 -0800172 .forEach(p -> processFilteringObjectives((DeviceId) p.element().id(),
173 p.number(), true));
alshabibbb424232016-01-15 12:20:25 -0800174
alshabib87f90e42016-01-27 13:49:46 -0800175 deviceService.addListener(deviceListener);
176
alshabib0ccde6d2015-05-30 18:22:36 -0700177 log.info("Started with Application ID {}", appId.id());
178 }
179
180 @Deactivate
181 public void deactivate() {
alshabibf544c012016-02-21 14:49:51 -0800182 componentConfigService.unregisterProperties(getClass(), false);
alshabibfe69e9a2016-02-11 17:31:36 -0800183 deviceService.removeListener(deviceListener);
Jonathan Hart3e594642015-10-20 17:31:24 -0700184 networkConfig.removeListener(configListener);
185 networkConfig.unregisterConfigFactory(configFactory);
alshabib0ccde6d2015-05-30 18:22:36 -0700186 log.info("Stopped");
187 }
188
alshabibf544c012016-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
alshabib56efe432016-02-25 17:57:24 -0500201 @Override
Jonathan Hart3e594642015-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 Hart48327842015-11-10 16:09:22 -0800210 provisionVlans(olt.deviceId(), olt.uplink(), port.port(), vlan, olt.vlan(),
alshabibfa0dc662016-01-13 11:23:53 -0800211 olt.defaultVlan());
212 }
213
214 @Override
215 public void removeSubscriber(ConnectPoint port) {
alshabib02cbe6a2016-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
alshabibf544c012016-02-21 14:49:51 -0800227 @Override
228 public Map<DeviceId, AccessDeviceData> fetchOlts() {
229 return Maps.newHashMap(oltData);
230 }
231
alshabib02cbe6a2016-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,
alshabibbb424232016-01-15 12:20:25 -0800255 fwd.remove(new ObjectiveContext() {
256 @Override
257 public void onSuccess(Objective objective) {
258 upFuture.complete(null);
259 }
alshabib02cbe6a2016-01-14 17:27:11 -0800260
alshabibbb424232016-01-15 12:20:25 -0800261 @Override
262 public void onError(Objective objective, ObjectiveError error) {
263 upFuture.complete(error);
264 }
265 })));
alshabib02cbe6a2016-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);
alshabibfa0dc662016-01-13 11:23:53 -0800283
Jonathan Hart3e594642015-10-20 17:31:24 -0700284 }
285
286 private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort,
287 PortNumber subscriberPort,
Jonathan Hart48327842015-11-10 16:09:22 -0800288 VlanId subscriberVlan, VlanId deviceVlan,
289 Optional<VlanId> defaultVlan) {
Jonathan Hart3e594642015-10-20 17:31:24 -0700290
alshabib49cadbd2016-01-12 18:06:53 -0800291 CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
292 CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
293
Jonathan Hart3e594642015-10-20 17:31:24 -0700294 TrafficSelector upstream = DefaultTrafficSelector.builder()
alshabibf544c012016-02-21 14:49:51 -0800295 .matchVlanId(defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan)))
Jonathan Hart3e594642015-10-20 17:31:24 -0700296 .matchInPort(subscriberPort)
297 .build();
298
299 TrafficSelector downstream = DefaultTrafficSelector.builder()
300 .matchVlanId(deviceVlan)
301 .matchInPort(uplinkPort)
alshabibfa0dc662016-01-13 11:23:53 -0800302 .matchInnerVlanId(subscriberVlan)
Jonathan Hart3e594642015-10-20 17:31:24 -0700303 .build();
304
305 TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder()
alshabib49cadbd2016-01-12 18:06:53 -0800306 .pushVlan()
Jonathan Hart3e594642015-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()
alshabibf544c012016-02-21 14:49:51 -0800315 .setVlanId(defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan)))
Jonathan Hart3e594642015-10-20 17:31:24 -0700316 .setOutput(subscriberPort)
317 .build();
318
319
alshabib02cbe6a2016-01-14 17:27:11 -0800320 ForwardingObjective.Builder upFwd = DefaultForwardingObjective.builder()
Jonathan Hart3e594642015-10-20 17:31:24 -0700321 .withFlag(ForwardingObjective.Flag.VERSATILE)
322 .withPriority(1000)
323 .makePermanent()
324 .withSelector(upstream)
325 .fromApp(appId)
alshabib02cbe6a2016-01-14 17:27:11 -0800326 .withTreatment(upstreamTreatment);
alshabib49cadbd2016-01-12 18:06:53 -0800327
Jonathan Hart3e594642015-10-20 17:31:24 -0700328
alshabib02cbe6a2016-01-14 17:27:11 -0800329 ForwardingObjective.Builder downFwd = DefaultForwardingObjective.builder()
Jonathan Hart3e594642015-10-20 17:31:24 -0700330 .withFlag(ForwardingObjective.Flag.VERSATILE)
331 .withPriority(1000)
332 .makePermanent()
333 .withSelector(downstream)
334 .fromApp(appId)
alshabib02cbe6a2016-01-14 17:27:11 -0800335 .withTreatment(downstreamTreatment);
alshabib49cadbd2016-01-12 18:06:53 -0800336
alshabib02cbe6a2016-01-14 17:27:11 -0800337 ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
Jonathan Hart3e594642015-10-20 17:31:24 -0700338
alshabib02cbe6a2016-01-14 17:27:11 -0800339 subscribers.put(cp, subscriberVlan);
340 objectives.put(cp, Sets.newHashSet(upFwd, downFwd));
341
alshabib02cbe6a2016-01-14 17:27:11 -0800342 flowObjectiveService.forward(deviceId, upFwd.add(new ObjectiveContext() {
343 @Override
344 public void onSuccess(Objective objective) {
345 upFuture.complete(null);
346 }
347
348 @Override
349 public void onError(Objective objective, ObjectiveError error) {
350 upFuture.complete(error);
351 }
352 }));
353
alshabib02cbe6a2016-01-14 17:27:11 -0800354 flowObjectiveService.forward(deviceId, downFwd.add(new ObjectiveContext() {
355 @Override
356 public void onSuccess(Objective objective) {
357 downFuture.complete(null);
358 }
359
360 @Override
361 public void onError(Objective objective, ObjectiveError error) {
362 downFuture.complete(error);
363 }
364 }));
alshabib49cadbd2016-01-12 18:06:53 -0800365
366 upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
367 if (upStatus == null && downStatus == null) {
368 post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_REGISTERED,
369 deviceId,
370 deviceVlan,
371 subscriberVlan));
alshabibea9eed92016-02-12 15:47:20 -0800372
alshabib49cadbd2016-01-12 18:06:53 -0800373 } else if (downStatus != null) {
374 log.error("Subscriber with vlan {} on device {} " +
375 "on port {} failed downstream installation: {}",
376 subscriberVlan, deviceId, subscriberPort, downStatus);
377 } else if (upStatus != null) {
378 log.error("Subscriber with vlan {} on device {} " +
379 "on port {} failed upstream installation: {}",
380 subscriberVlan, deviceId, subscriberPort, upStatus);
381 }
382 }, oltInstallers);
383
Jonathan Hart3e594642015-10-20 17:31:24 -0700384 }
385
alshabibea9eed92016-02-12 15:47:20 -0800386 private void processFilteringObjectives(DeviceId devId, PortNumber port, boolean install) {
alshabib8f8060d2016-02-10 15:08:23 -0800387 DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
388
389 FilteringObjective eapol = (install ? builder.permit() : builder.deny())
alshabibea9eed92016-02-12 15:47:20 -0800390 .withKey(Criteria.matchInPort(port))
alshabibbb424232016-01-15 12:20:25 -0800391 .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
392 .withMeta(DefaultTrafficTreatment.builder()
393 .setOutput(PortNumber.CONTROLLER).build())
394 .fromApp(appId)
395 .withPriority(1000)
396 .add(new ObjectiveContext() {
397 @Override
398 public void onSuccess(Objective objective) {
399 log.info("Eapol filter for {} on {} installed.",
400 devId, port);
401 }
402
403 @Override
404 public void onError(Objective objective, ObjectiveError error) {
405 log.info("Eapol filter for {} on {} failed because {}",
406 devId, port, error);
407 }
408 });
409
alshabibbb424232016-01-15 12:20:25 -0800410 flowObjectiveService.filter(devId, eapol);
alshabib03adb492016-02-01 17:25:00 -0800411
alshabibbb424232016-01-15 12:20:25 -0800412 }
413
alshabib0ccde6d2015-05-30 18:22:36 -0700414 private class InternalDeviceListener implements DeviceListener {
415 @Override
416 public void event(DeviceEvent event) {
alshabib49cadbd2016-01-12 18:06:53 -0800417 DeviceId devId = event.subject().id();
418 if (!oltData.containsKey(devId)) {
419 log.debug("Device {} is not an OLT", devId);
alshabib6b139b42016-01-12 15:55:53 -0800420 return;
421 }
alshabib0ccde6d2015-05-30 18:22:36 -0700422 switch (event.type()) {
alshabibbb424232016-01-15 12:20:25 -0800423 //TODO: Port handling and bookkeeping should be inproved once
424 // olt firmware handles correct behaviour.
alshabib0ccde6d2015-05-30 18:22:36 -0700425 case PORT_ADDED:
alshabib8f8060d2016-02-10 15:08:23 -0800426 if (!oltData.get(devId).uplink().equals(event.port().number()) &&
427 event.port().isEnabled()) {
alshabibea9eed92016-02-12 15:47:20 -0800428 processFilteringObjectives(devId, event.port().number(), true);
alshabibbb424232016-01-15 12:20:25 -0800429 }
430 break;
431 case PORT_REMOVED:
432 AccessDeviceData olt = oltData.get(devId);
433 unprovisionSubscriber(devId, olt.uplink(),
434 event.port().number(),
435 olt.vlan());
alshabib8f8060d2016-02-10 15:08:23 -0800436 if (!oltData.get(devId).uplink().equals(event.port().number()) &&
437 event.port().isEnabled()) {
alshabibea9eed92016-02-12 15:47:20 -0800438 processFilteringObjectives(devId, event.port().number(), false);
alshabib8f8060d2016-02-10 15:08:23 -0800439 }
alshabibbb424232016-01-15 12:20:25 -0800440 break;
alshabib0ccde6d2015-05-30 18:22:36 -0700441 case PORT_UPDATED:
alshabib8f8060d2016-02-10 15:08:23 -0800442 if (oltData.get(devId).uplink().equals(event.port().number())) {
443 break;
444 }
445 if (event.port().isEnabled()) {
alshabibea9eed92016-02-12 15:47:20 -0800446 processFilteringObjectives(devId, event.port().number(), true);
alshabib8f8060d2016-02-10 15:08:23 -0800447 } else {
alshabibea9eed92016-02-12 15:47:20 -0800448 processFilteringObjectives(devId, event.port().number(), false);
alshabib8f8060d2016-02-10 15:08:23 -0800449 }
alshabib0ccde6d2015-05-30 18:22:36 -0700450 break;
451 case DEVICE_ADDED:
alshabib6b139b42016-01-12 15:55:53 -0800452 post(new AccessDeviceEvent(
453 AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
454 null, null));
alshabibf544c012016-02-21 14:49:51 -0800455 provisionDefaultFlows(devId);
alshabib6b139b42016-01-12 15:55:53 -0800456 break;
alshabib0ccde6d2015-05-30 18:22:36 -0700457 case DEVICE_REMOVED:
alshabib6b139b42016-01-12 15:55:53 -0800458 post(new AccessDeviceEvent(
459 AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
460 null, null));
461 break;
alshabibe5ec2402016-02-09 18:22:33 -0800462 case DEVICE_AVAILABILITY_CHANGED:
463 if (deviceService.isAvailable(devId)) {
464 post(new AccessDeviceEvent(
465 AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
466 null, null));
467 } else {
468 post(new AccessDeviceEvent(
469 AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
470 null, null));
471 }
472 break;
alshabib6b139b42016-01-12 15:55:53 -0800473 case DEVICE_UPDATED:
alshabib0ccde6d2015-05-30 18:22:36 -0700474 case DEVICE_SUSPENDED:
alshabib0ccde6d2015-05-30 18:22:36 -0700475 case PORT_STATS_UPDATED:
476 default:
477 return;
478 }
479 }
480 }
481
Jonathan Hart3e594642015-10-20 17:31:24 -0700482 private class InternalNetworkConfigListener implements NetworkConfigListener {
483 @Override
484 public void event(NetworkConfigEvent event) {
485 switch (event.type()) {
486
alshabib02cbe6a2016-01-14 17:27:11 -0800487 case CONFIG_ADDED:
488 case CONFIG_UPDATED:
alshabibf544c012016-02-21 14:49:51 -0800489
490 AccessDeviceConfig config =
491 networkConfig.getConfig((DeviceId) event.subject(), CONFIG_CLASS);
492 if (config != null) {
493 oltData.put(config.getOlt().deviceId(), config.getOlt());
494 provisionDefaultFlows((DeviceId) event.subject());
Jonathan Hart3e594642015-10-20 17:31:24 -0700495 }
alshabibf544c012016-02-21 14:49:51 -0800496
alshabib02cbe6a2016-01-14 17:27:11 -0800497 break;
alshabibf544c012016-02-21 14:49:51 -0800498 case CONFIG_REGISTERED:
alshabib02cbe6a2016-01-14 17:27:11 -0800499 case CONFIG_UNREGISTERED:
alshabibf544c012016-02-21 14:49:51 -0800500 break;
alshabib02cbe6a2016-01-14 17:27:11 -0800501 case CONFIG_REMOVED:
alshabibf544c012016-02-21 14:49:51 -0800502 oltData.remove(event.subject());
alshabib02cbe6a2016-01-14 17:27:11 -0800503 default:
504 break;
Jonathan Hart3e594642015-10-20 17:31:24 -0700505 }
506 }
alshabibf544c012016-02-21 14:49:51 -0800507
508 @Override
509 public boolean isRelevant(NetworkConfigEvent event) {
510 return event.configClass().equals(CONFIG_CLASS);
511 }
Jonathan Hart3e594642015-10-20 17:31:24 -0700512 }
alshabib0ccde6d2015-05-30 18:22:36 -0700513
alshabib8f8060d2016-02-10 15:08:23 -0800514 private void provisionDefaultFlows(DeviceId deviceId) {
515 List<Port> ports = deviceService.getPorts(deviceId);
516
517 ports.stream()
518 .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number()))
519 .filter(p -> p.isEnabled())
alshabibea9eed92016-02-12 15:47:20 -0800520 .forEach(p -> processFilteringObjectives((DeviceId) p.element().id(),
521 p.number(), true));
alshabib8f8060d2016-02-10 15:08:23 -0800522
523 }
524
alshabib0ccde6d2015-05-30 18:22:36 -0700525}