blob: a78e9b4464b47b8510b703c7e04c06c75a65a120 [file] [log] [blame]
Jonathan Hartdf207092015-12-10 11:19:25 -08001/*
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 */
16
Jonathan Hartc22e8472015-11-17 18:25:45 -080017package org.onosproject.routing.impl;
Jonathan Hartdf207092015-12-10 11:19:25 -080018
19import com.google.common.collect.ConcurrentHashMultiset;
20import com.google.common.collect.HashMultimap;
21import com.google.common.collect.Maps;
22import com.google.common.collect.Multimap;
23import com.google.common.collect.Multiset;
24import org.apache.felix.scr.annotations.Activate;
25import org.apache.felix.scr.annotations.Component;
26import org.apache.felix.scr.annotations.Deactivate;
Jonathan Hartb9401902016-02-02 18:46:01 -080027import org.apache.felix.scr.annotations.Modified;
28import org.apache.felix.scr.annotations.Property;
Jonathan Hartdf207092015-12-10 11:19:25 -080029import org.apache.felix.scr.annotations.Reference;
30import org.apache.felix.scr.annotations.ReferenceCardinality;
31import org.onlab.packet.Ethernet;
32import org.onlab.packet.IpAddress;
33import org.onlab.packet.IpPrefix;
Jonathan Hartca47cd72015-12-13 12:31:09 -080034import org.onlab.packet.VlanId;
Jonathan Hartb9401902016-02-02 18:46:01 -080035import org.onlab.util.Tools;
36import org.onosproject.cfg.ComponentConfigService;
Jonathan Hartdf207092015-12-10 11:19:25 -080037import org.onosproject.core.ApplicationId;
38import org.onosproject.core.CoreService;
39import org.onosproject.incubator.net.intf.Interface;
gaurav164cf6d2016-03-25 21:43:04 +053040import org.onosproject.incubator.net.intf.InterfaceEvent;
41import org.onosproject.incubator.net.intf.InterfaceListener;
Jonathan Hartdf207092015-12-10 11:19:25 -080042import org.onosproject.incubator.net.intf.InterfaceService;
Saurav Das49cb5a12016-01-16 22:54:07 -080043import org.onosproject.net.ConnectPoint;
Jonathan Hartdf207092015-12-10 11:19:25 -080044import org.onosproject.net.DeviceId;
Jonathan Hartb3fa42c2016-01-13 09:50:43 -080045import org.onosproject.net.config.NetworkConfigEvent;
46import org.onosproject.net.config.NetworkConfigListener;
Jonathan Hartdf207092015-12-10 11:19:25 -080047import org.onosproject.net.config.NetworkConfigService;
48import org.onosproject.net.device.DeviceEvent;
49import org.onosproject.net.device.DeviceListener;
50import org.onosproject.net.device.DeviceService;
51import org.onosproject.net.flow.DefaultTrafficSelector;
52import org.onosproject.net.flow.DefaultTrafficTreatment;
53import org.onosproject.net.flow.TrafficSelector;
54import org.onosproject.net.flow.TrafficTreatment;
55import org.onosproject.net.flow.criteria.Criteria;
56import org.onosproject.net.flowobjective.DefaultFilteringObjective;
57import org.onosproject.net.flowobjective.DefaultForwardingObjective;
58import org.onosproject.net.flowobjective.DefaultNextObjective;
59import org.onosproject.net.flowobjective.FilteringObjective;
60import org.onosproject.net.flowobjective.FlowObjectiveService;
61import org.onosproject.net.flowobjective.ForwardingObjective;
62import org.onosproject.net.flowobjective.NextObjective;
Jonathan Hartdf207092015-12-10 11:19:25 -080063import org.onosproject.net.flowobjective.ObjectiveContext;
Jonathan Hartf04b7d92016-03-29 09:39:11 -070064import org.onosproject.net.flowobjective.DefaultObjectiveContext;
Jonathan Hartdf207092015-12-10 11:19:25 -080065import org.onosproject.routing.FibEntry;
66import org.onosproject.routing.FibListener;
67import org.onosproject.routing.FibUpdate;
68import org.onosproject.routing.RoutingService;
Jonathan Hartb3fa42c2016-01-13 09:50:43 -080069import org.onosproject.routing.config.RouterConfig;
Jonathan Hartb9401902016-02-02 18:46:01 -080070import org.osgi.service.component.ComponentContext;
Jonathan Hartdf207092015-12-10 11:19:25 -080071import org.slf4j.Logger;
72import org.slf4j.LoggerFactory;
73
74import java.util.Collection;
Jonathan Hartb9401902016-02-02 18:46:01 -080075import java.util.Dictionary;
Jonathan Hartdf207092015-12-10 11:19:25 -080076import java.util.HashMap;
Jonathan Hart883fd372016-02-10 14:36:15 -080077import java.util.List;
Jonathan Hartdf207092015-12-10 11:19:25 -080078import java.util.Map;
Jonathan Hartdf207092015-12-10 11:19:25 -080079import java.util.Set;
Jonathan Hart883fd372016-02-10 14:36:15 -080080import java.util.stream.Collectors;
Jonathan Hartdf207092015-12-10 11:19:25 -080081
82/**
83 * Programs routes to a single OpenFlow switch.
84 */
Jonathan Hartc22e8472015-11-17 18:25:45 -080085@Component(immediate = true, enabled = false)
86public class SingleSwitchFibInstaller {
Jonathan Hartdf207092015-12-10 11:19:25 -080087
88 private final Logger log = LoggerFactory.getLogger(getClass());
89
90 private static final int PRIORITY_OFFSET = 100;
91 private static final int PRIORITY_MULTIPLIER = 5;
92
Saurav Das49cb5a12016-01-16 22:54:07 -080093 public static final short ASSIGNED_VLAN = 4094;
94
Jonathan Hartdf207092015-12-10 11:19:25 -080095 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 protected CoreService coreService;
97
98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 protected RoutingService routingService;
100
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected InterfaceService interfaceService;
103
104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
105 protected NetworkConfigService networkConfigService;
106
107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hartb9401902016-02-02 18:46:01 -0800108 protected ComponentConfigService componentConfigService;
109
110 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hartdf207092015-12-10 11:19:25 -0800111 protected FlowObjectiveService flowObjectiveService;
112
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
114 protected DeviceService deviceService;
115
Jonathan Hartb9401902016-02-02 18:46:01 -0800116 @Property(name = "routeToNextHop", boolValue = false,
117 label = "Install a /32 route to each next hop")
118 private boolean routeToNextHop = false;
119
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800120 private InternalDeviceListener deviceListener;
Jonathan Hartdf207092015-12-10 11:19:25 -0800121
122 // Device id of data-plane switch - should be learned from config
123 private DeviceId deviceId;
124
Saurav Das49cb5a12016-01-16 22:54:07 -0800125 private ConnectPoint controlPlaneConnectPoint;
126
Jonathan Hart883fd372016-02-10 14:36:15 -0800127 private List<String> interfaces;
128
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800129 private ApplicationId routerAppId;
Jonathan Hartdf207092015-12-10 11:19:25 -0800130
131 // Reference count for how many times a next hop is used by a route
132 private final Multiset<IpAddress> nextHopsCount = ConcurrentHashMultiset.create();
133
134 // Mapping from prefix to its current next hop
135 private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap();
136
137 // Mapping from next hop IP to next hop object containing group info
138 private final Map<IpAddress, Integer> nextHops = Maps.newHashMap();
139
140 // Stores FIB updates that are waiting for groups to be set up
141 private final Multimap<NextHopGroupKey, FibEntry> pendingUpdates = HashMultimap.create();
142
gaurav164cf6d2016-03-25 21:43:04 +0530143 //interface object for event
144 private InternalInterfaceListener internalInterfaceList = new InternalInterfaceListener();
Jonathan Hartdf207092015-12-10 11:19:25 -0800145
146 @Activate
Jonathan Hartb9401902016-02-02 18:46:01 -0800147 protected void activate(ComponentContext context) {
Jonathan Hartb9401902016-02-02 18:46:01 -0800148 componentConfigService.registerProperties(getClass());
Jonathan Hart9ad777f2016-02-19 12:44:36 -0800149 modified(context);
150
151 routerAppId = coreService.registerApplication(RoutingService.ROUTER_APP_ID);
Jonathan Hartb9401902016-02-02 18:46:01 -0800152
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800153 deviceListener = new InternalDeviceListener();
Jonathan Hartdf207092015-12-10 11:19:25 -0800154 deviceService.addListener(deviceListener);
155
gaurav164cf6d2016-03-25 21:43:04 +0530156 interfaceService.addListener(internalInterfaceList);
157
Jonathan Hartdf207092015-12-10 11:19:25 -0800158 routingService.addFibListener(new InternalFibListener());
159 routingService.start();
160
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800161 updateConfig();
Jonathan Hartdf207092015-12-10 11:19:25 -0800162
163 log.info("Started");
164 }
165
166 @Deactivate
167 protected void deactivate() {
168 routingService.stop();
169
170 deviceService.removeListener(deviceListener);
171
gaurav164cf6d2016-03-25 21:43:04 +0530172 interfaceService.removeListener(internalInterfaceList);
173
Jonathan Hartdf207092015-12-10 11:19:25 -0800174 //processIntfFilters(false, configService.getInterfaces()); //TODO necessary?
175
Jonathan Hartb9401902016-02-02 18:46:01 -0800176 componentConfigService.unregisterProperties(getClass(), false);
177
Jonathan Hartdf207092015-12-10 11:19:25 -0800178 log.info("Stopped");
179 }
180
Jonathan Hartb9401902016-02-02 18:46:01 -0800181 @Modified
182 protected void modified(ComponentContext context) {
183 Dictionary<?, ?> properties = context.getProperties();
184 if (properties == null) {
185 return;
186 }
187
188 String strRouteToNextHop = Tools.get(properties, "routeToNextHop");
189 routeToNextHop = Boolean.parseBoolean(strRouteToNextHop);
190
191 log.info("routeToNextHop set to {}", routeToNextHop);
192 }
193
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800194 private void updateConfig() {
195 RouterConfig routerConfig =
196 networkConfigService.getConfig(routerAppId, RoutingService.ROUTER_CONFIG_CLASS);
Jonathan Hartdf207092015-12-10 11:19:25 -0800197
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800198 if (routerConfig == null) {
199 log.info("Router config not available");
Jonathan Hartdf207092015-12-10 11:19:25 -0800200 return;
201 }
Saurav Das49cb5a12016-01-16 22:54:07 -0800202 controlPlaneConnectPoint = routerConfig.getControlPlaneConnectPoint();
203 log.info("Control Plane Connect Point: {}", controlPlaneConnectPoint);
Jonathan Hartdf207092015-12-10 11:19:25 -0800204
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800205 deviceId = routerConfig.getControlPlaneConnectPoint().deviceId();
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800206 log.info("Router device ID is {}", deviceId);
207
Jonathan Hart883fd372016-02-10 14:36:15 -0800208 interfaces = routerConfig.getInterfaces();
209 log.info("Using interfaces: {}", interfaces.isEmpty() ? "all" : interfaces);
210
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800211 updateDevice();
212 }
213
214 private void updateDevice() {
215 if (deviceId != null && deviceService.isAvailable(deviceId)) {
Jonathan Hart883fd372016-02-10 14:36:15 -0800216
217 Set<Interface> intfs;
218 if (interfaces.isEmpty()) {
219 intfs = interfaceService.getInterfaces();
220 } else {
221 // TODO need to fix by making interface names globally unique
222 intfs = interfaceService.getInterfaces().stream()
223 .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
224 .filter(intf -> interfaces.contains(intf.name()))
225 .collect(Collectors.toSet());
226 }
227
228 processIntfFilters(true, intfs);
Jonathan Hartdf207092015-12-10 11:19:25 -0800229 }
Jonathan Hartdf207092015-12-10 11:19:25 -0800230 }
231
232 private void updateFibEntry(Collection<FibUpdate> updates) {
233 Map<FibEntry, Integer> toInstall = new HashMap<>(updates.size());
234
235 for (FibUpdate update : updates) {
236 FibEntry entry = update.entry();
237
238 addNextHop(entry);
239
240 Integer nextId;
241 synchronized (pendingUpdates) {
242 nextId = nextHops.get(entry.nextHopIp());
243 }
244
245 toInstall.put(update.entry(), nextId);
246 }
247
248 installFlows(toInstall);
249 }
250
251 private void installFlows(Map<FibEntry, Integer> entriesToInstall) {
252
253 for (Map.Entry<FibEntry, Integer> entry : entriesToInstall.entrySet()) {
254 FibEntry fibEntry = entry.getKey();
255 Integer nextId = entry.getValue();
256
257 flowObjectiveService.forward(deviceId,
258 generateRibForwardingObj(fibEntry.prefix(), nextId).add());
259 log.trace("Sending forwarding objective {} -> nextId:{}", fibEntry, nextId);
260 }
261
262 }
263
264 private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
265
266 for (FibUpdate update : withdraws) {
267 FibEntry entry = update.entry();
268 //Integer nextId = nextHops.get(entry.nextHopIp());
269
270 /* Group group = deleteNextHop(entry.prefix());
271 if (group == null) {
272 log.warn("Group not found when deleting {}", entry);
273 return;
274 }*/
275
276 flowObjectiveService.forward(deviceId,
277 generateRibForwardingObj(entry.prefix(), null).remove());
278
279 }
280
281 }
282
283 private ForwardingObjective.Builder generateRibForwardingObj(IpPrefix prefix,
284 Integer nextId) {
285 TrafficSelector selector = DefaultTrafficSelector.builder()
286 .matchEthType(Ethernet.TYPE_IPV4)
287 .matchIPDst(prefix)
288 .build();
289
290 int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
291
292 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
Saurav Das49cb5a12016-01-16 22:54:07 -0800293 .fromApp(routerAppId)
Jonathan Hartdf207092015-12-10 11:19:25 -0800294 .makePermanent()
295 .withSelector(selector)
296 .withPriority(priority)
297 .withFlag(ForwardingObjective.Flag.SPECIFIC);
298
299 if (nextId == null) {
300 // Route withdraws are not specified with next hops. Generating
301 // dummy treatment as there is no equivalent nextId info.
302 fwdBuilder.withTreatment(DefaultTrafficTreatment.builder().build());
303 } else {
304 fwdBuilder.nextStep(nextId);
305 }
306 return fwdBuilder;
307 }
308
309 private synchronized void addNextHop(FibEntry entry) {
310 prefixToNextHop.put(entry.prefix(), entry.nextHopIp());
311 if (nextHopsCount.count(entry.nextHopIp()) == 0) {
312 // There was no next hop in the multiset
313
314 Interface egressIntf = interfaceService.getMatchingInterface(entry.nextHopIp());
315 if (egressIntf == null) {
316 log.warn("no egress interface found for {}", entry);
317 return;
318 }
319
320 NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp());
321
322 NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey);
323
Jonathan Hartca47cd72015-12-13 12:31:09 -0800324 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
Jonathan Hartdf207092015-12-10 11:19:25 -0800325 .setEthSrc(egressIntf.mac())
Jonathan Hartca47cd72015-12-13 12:31:09 -0800326 .setEthDst(nextHop.mac());
327
Saurav Das49cb5a12016-01-16 22:54:07 -0800328 TrafficSelector.Builder metabuilder = null;
Jonathan Hartca47cd72015-12-13 12:31:09 -0800329 if (!egressIntf.vlan().equals(VlanId.NONE)) {
330 treatment.pushVlan()
331 .setVlanId(egressIntf.vlan())
332 .setVlanPcp((byte) 0);
Saurav Das49cb5a12016-01-16 22:54:07 -0800333 } else {
334 // untagged outgoing port may require internal vlan in some pipelines
335 metabuilder = DefaultTrafficSelector.builder();
336 metabuilder.matchVlanId(VlanId.vlanId(ASSIGNED_VLAN));
Jonathan Hartca47cd72015-12-13 12:31:09 -0800337 }
338
339 treatment.setOutput(egressIntf.connectPoint().port());
Jonathan Hartdf207092015-12-10 11:19:25 -0800340
341 int nextId = flowObjectiveService.allocateNextId();
Saurav Das49cb5a12016-01-16 22:54:07 -0800342 NextObjective.Builder nextBuilder = DefaultNextObjective.builder()
Jonathan Hartdf207092015-12-10 11:19:25 -0800343 .withId(nextId)
Jonathan Hartca47cd72015-12-13 12:31:09 -0800344 .addTreatment(treatment.build())
Jonathan Hartdf207092015-12-10 11:19:25 -0800345 .withType(NextObjective.Type.SIMPLE)
Saurav Das49cb5a12016-01-16 22:54:07 -0800346 .fromApp(routerAppId);
347 if (metabuilder != null) {
348 nextBuilder.withMeta(metabuilder.build());
349 }
Jonathan Hartdf207092015-12-10 11:19:25 -0800350
Saurav Das49cb5a12016-01-16 22:54:07 -0800351 NextObjective nextObjective = nextBuilder.add(); // TODO add callbacks
Jonathan Hartdf207092015-12-10 11:19:25 -0800352 flowObjectiveService.next(deviceId, nextObjective);
353
354 nextHops.put(nextHop.ip(), nextId);
355
Jonathan Hartb9401902016-02-02 18:46:01 -0800356 if (routeToNextHop) {
357 // Install route to next hop
358 ForwardingObjective fob =
359 generateRibForwardingObj(IpPrefix.valueOf(entry.nextHopIp(), 32), nextId).add();
360 flowObjectiveService.forward(deviceId, fob);
361 }
Jonathan Hartdf207092015-12-10 11:19:25 -0800362 }
363
364 nextHopsCount.add(entry.nextHopIp());
365 }
366
367 /*private synchronized Group deleteNextHop(IpPrefix prefix) {
368 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
369 NextHop nextHop = nextHops.get(nextHopIp);
370 if (nextHop == null) {
371 log.warn("No next hop found when removing prefix {}", prefix);
372 return null;
373 }
374
375 Group group = groupService.getGroup(deviceId,
376 new DefaultGroupKey(appKryo.
377 serialize(nextHop.group())));
378
379 // FIXME disabling group deletes for now until we verify the logic is OK
380 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
381 // There was one or less next hops, so there are now none
382
383 log.debug("removing group for next hop {}", nextHop);
384
385 nextHops.remove(nextHopIp);
386
387 groupService.removeGroup(deviceId,
388 new DefaultGroupKey(appKryo.build().serialize(nextHop.group())),
389 appId);
390 }
391
392 return group;
393 }*/
394
395 private void processIntfFilters(boolean install, Set<Interface> intfs) {
396 log.info("Processing {} router interfaces", intfs.size());
397 for (Interface intf : intfs) {
398 if (!intf.connectPoint().deviceId().equals(deviceId)) {
399 // Ignore interfaces if they are not on the router switch
400 continue;
401 }
402
gaurav164cf6d2016-03-25 21:43:04 +0530403 createFilteringObjective(install, intf);
404 }
405 }
Jonathan Hart6344f572015-12-15 08:26:25 -0800406
gaurav164cf6d2016-03-25 21:43:04 +0530407 //process filtering objective for interface add/remove.
408 private void processIntfFilter(boolean install, Interface intf) {
409
410 if (!intf.connectPoint().deviceId().equals(deviceId)) {
411 // Ignore interfaces if they are not on the router switch
412 return;
413 }
414
415 createFilteringObjective(install, intf);
416 }
417
418 //create filtering objective for interface
419 private void createFilteringObjective(boolean install, Interface intf) {
420
421 FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
422 // first add filter for the interface
423 fob.withKey(Criteria.matchInPort(intf.connectPoint().port()))
424 .addCondition(Criteria.matchEthDst(intf.mac()))
425 .addCondition(Criteria.matchVlanId(intf.vlan()));
426 fob.withPriority(PRIORITY_OFFSET);
427 if (intf.vlan() == VlanId.NONE) {
428 TrafficTreatment tt = DefaultTrafficTreatment.builder()
429 .pushVlan().setVlanId(VlanId.vlanId(ASSIGNED_VLAN)).build();
430 fob.withMeta(tt);
431 }
432
433 fob.permit().fromApp(routerAppId);
434 sendFilteringObjective(install, fob, intf);
435 if (controlPlaneConnectPoint != null) {
436 // then add the same mac/vlan filters for control-plane connect point
437 fob.withKey(Criteria.matchInPort(controlPlaneConnectPoint.port()));
Saurav Das49cb5a12016-01-16 22:54:07 -0800438 sendFilteringObjective(install, fob, intf);
Jonathan Hartdf207092015-12-10 11:19:25 -0800439 }
440 }
441
Saurav Das49cb5a12016-01-16 22:54:07 -0800442 private void sendFilteringObjective(boolean install, FilteringObjective.Builder fob,
443 Interface intf) {
Saurav Das49cb5a12016-01-16 22:54:07 -0800444
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700445 ObjectiveContext context = new DefaultObjectiveContext(
446 (objective) -> log.info("Installed filter for interface {}", intf),
447 (objective, error) ->
448 log.error("Failed to install filter for interface {}: {}", intf, error));
gaurav164cf6d2016-03-25 21:43:04 +0530449
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700450 FilteringObjective filter = install ? fob.add(context) : fob.remove(context);
451
452 flowObjectiveService.filter(deviceId, filter);
Saurav Das49cb5a12016-01-16 22:54:07 -0800453 }
454
Jonathan Hartdf207092015-12-10 11:19:25 -0800455 private class InternalFibListener implements FibListener {
456
457 @Override
458 public void update(Collection<FibUpdate> updates,
459 Collection<FibUpdate> withdraws) {
Jonathan Hartc22e8472015-11-17 18:25:45 -0800460 SingleSwitchFibInstaller.this.deleteFibEntry(withdraws);
461 SingleSwitchFibInstaller.this.updateFibEntry(updates);
Jonathan Hartdf207092015-12-10 11:19:25 -0800462 }
463 }
464
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800465 /**
466 * Listener for device events used to trigger driver setup when a device is
467 * (re)detected.
468 */
469 private class InternalDeviceListener implements DeviceListener {
Jonathan Hartdf207092015-12-10 11:19:25 -0800470 @Override
471 public void event(DeviceEvent event) {
472 switch (event.type()) {
473 case DEVICE_ADDED:
474 case DEVICE_AVAILABILITY_CHANGED:
475 if (deviceService.isAvailable(event.subject().id())) {
476 log.info("Device connected {}", event.subject().id());
477 if (event.subject().id().equals(deviceId)) {
Charles Chanf555a732016-02-15 15:37:15 -0800478 updateDevice();
Jonathan Hartdf207092015-12-10 11:19:25 -0800479 }
480 }
481 break;
482 // TODO other cases
483 case DEVICE_UPDATED:
484 case DEVICE_REMOVED:
485 case DEVICE_SUSPENDED:
486 case PORT_ADDED:
487 case PORT_UPDATED:
488 case PORT_REMOVED:
489 default:
490 break;
491 }
492 }
493 }
Jonathan Hartb3fa42c2016-01-13 09:50:43 -0800494
495 /**
496 * Listener for network config events.
497 */
498 private class InternalNetworkConfigListener implements NetworkConfigListener {
499 @Override
500 public void event(NetworkConfigEvent event) {
501 if (event.subject().equals(RoutingService.ROUTER_CONFIG_CLASS)) {
502 switch (event.type()) {
503 case CONFIG_ADDED:
504 case CONFIG_UPDATED:
505 updateConfig();
506 break;
507 case CONFIG_REGISTERED:
508 case CONFIG_UNREGISTERED:
509 case CONFIG_REMOVED:
510 default:
511 break;
512 }
513 }
514 }
515 }
gaurav164cf6d2016-03-25 21:43:04 +0530516
517 private class InternalInterfaceListener implements InterfaceListener {
518
519 @Override
520 public void event(InterfaceEvent event) {
521 Interface intf = event.subject();
522 switch (event.type()) {
523 case INTERFACE_ADDED:
524 if (intf != null) {
525 processIntfFilter(true, intf);
526 }
527 break;
528 case INTERFACE_UPDATED:
529 break;
530 case INTERFACE_REMOVED:
531 if (intf != null) {
532 processIntfFilter(false, intf);
533 }
534 break;
535 default:
536 break;
537 }
538 }
539 }
Jonathan Hartdf207092015-12-10 11:19:25 -0800540}