blob: 8a7aae9ecae6fe0484a25fa6ccf1e7f9df749684 [file] [log] [blame]
sanghob35a6192015-04-01 13:05:26 -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.segmentrouting;
17
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
sangho1e575652015-05-14 00:39:53 -070023import org.apache.felix.scr.annotations.Service;
sanghob35a6192015-04-01 13:05:26 -070024import org.onlab.packet.Ethernet;
25import org.onlab.packet.IPv4;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070026import org.onlab.util.KryoNamespace;
sanghob35a6192015-04-01 13:05:26 -070027import org.onosproject.core.ApplicationId;
28import org.onosproject.core.CoreService;
29import org.onosproject.event.Event;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070030import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
31import org.onosproject.segmentrouting.grouphandler.NeighborSet;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070032import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey;
sanghob35a6192015-04-01 13:05:26 -070033import org.onosproject.mastership.MastershipService;
34import org.onosproject.net.Device;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.Link;
sanghob35a6192015-04-01 13:05:26 -070037import org.onosproject.net.Port;
38import org.onosproject.net.device.DeviceEvent;
39import org.onosproject.net.device.DeviceListener;
40import org.onosproject.net.device.DeviceService;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070041import org.onosproject.net.flowobjective.FlowObjectiveService;
sanghob35a6192015-04-01 13:05:26 -070042import org.onosproject.net.group.GroupKey;
sanghob35a6192015-04-01 13:05:26 -070043import org.onosproject.net.host.HostService;
44import org.onosproject.net.intent.IntentService;
45import org.onosproject.net.link.LinkEvent;
46import org.onosproject.net.link.LinkListener;
47import org.onosproject.net.link.LinkService;
48import org.onosproject.net.packet.InboundPacket;
49import org.onosproject.net.packet.PacketContext;
50import org.onosproject.net.packet.PacketProcessor;
51import org.onosproject.net.packet.PacketService;
52import org.onosproject.net.topology.TopologyService;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070053import org.onosproject.segmentrouting.config.NetworkConfigManager;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070054import org.onosproject.store.service.EventuallyConsistentMap;
55import org.onosproject.store.service.EventuallyConsistentMapBuilder;
56import org.onosproject.store.service.StorageService;
57import org.onosproject.store.service.WallClockTimestamp;
58import org.onosproject.store.service.WallclockClockManager;
sanghob35a6192015-04-01 13:05:26 -070059import org.slf4j.Logger;
60import org.slf4j.LoggerFactory;
61
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070062import java.net.URI;
63import java.util.HashSet;
sangho1e575652015-05-14 00:39:53 -070064import java.util.List;
sanghob35a6192015-04-01 13:05:26 -070065import java.util.Map;
66import java.util.concurrent.ConcurrentHashMap;
67import java.util.concurrent.ConcurrentLinkedQueue;
68import java.util.concurrent.Executors;
69import java.util.concurrent.ScheduledExecutorService;
70import java.util.concurrent.ScheduledFuture;
71import java.util.concurrent.TimeUnit;
72
73@SuppressWarnings("ALL")
sangho1e575652015-05-14 00:39:53 -070074@Service
sanghob35a6192015-04-01 13:05:26 -070075@Component(immediate = true)
sangho1e575652015-05-14 00:39:53 -070076public class SegmentRoutingManager implements SegmentRoutingService {
sanghob35a6192015-04-01 13:05:26 -070077
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070078 private static Logger log = LoggerFactory
79 .getLogger(SegmentRoutingManager.class);
sanghob35a6192015-04-01 13:05:26 -070080
81 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 protected CoreService coreService;
83
84 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
85 protected TopologyService topologyService;
86
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 protected PacketService packetService;
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 protected IntentService intentService;
92
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected HostService hostService;
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected DeviceService deviceService;
98
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700100 protected FlowObjectiveService flowObjectiveService;
sanghob35a6192015-04-01 13:05:26 -0700101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected LinkService linkService;
104
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
sanghob35a6192015-04-01 13:05:26 -0700106 protected MastershipService mastershipService;
sangho1e575652015-05-14 00:39:53 -0700107
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700108 protected ArpHandler arpHandler = null;
109 protected IcmpHandler icmpHandler = null;
110 protected IpHandler ipHandler = null;
111 protected RoutingRulePopulator routingRulePopulator = null;
sanghob35a6192015-04-01 13:05:26 -0700112 protected ApplicationId appId;
sangho666cd6d2015-04-14 16:27:13 -0700113 protected DeviceConfiguration deviceConfiguration = null;
sanghob35a6192015-04-01 13:05:26 -0700114
sangho1e575652015-05-14 00:39:53 -0700115
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700116 private DefaultRoutingHandler defaultRoutingHandler = null;
sangho1e575652015-05-14 00:39:53 -0700117 private TunnelHandler tunnelHandler = null;
118 private PolicyHandler policyHandler = null;
sanghob35a6192015-04-01 13:05:26 -0700119 private InternalPacketProcessor processor = new InternalPacketProcessor();
120 private InternalEventHandler eventHandler = new InternalEventHandler();
121
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700122 private ScheduledExecutorService executorService = Executors
123 .newScheduledThreadPool(1);
sanghob35a6192015-04-01 13:05:26 -0700124
125 private static ScheduledFuture<?> eventHandlerFuture = null;
126 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700127 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700128 // Per device next objective ID store with (device id + neighbor set) as key
129 private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
130 Integer> nsNextObjStore = null;
sangho0b2b6d12015-05-20 22:16:38 -0700131 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
132 private EventuallyConsistentMap<String, Policy> policyStore = null;
133
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700134 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
135 protected StorageService storageService;
sanghob35a6192015-04-01 13:05:26 -0700136
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700137 private NetworkConfigManager networkConfigService = new NetworkConfigManager();;
138
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700139 private Object threadSchedulerLock = new Object();
140 private static int numOfEventsQueued = 0;
141 private static int numOfEventsExecuted = 0;
sanghob35a6192015-04-01 13:05:26 -0700142 private static int numOfHandlerExecution = 0;
143 private static int numOfHandlerScheduled = 0;
144
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700145 private KryoNamespace.Builder kryoBuilder = null;
146
sanghob35a6192015-04-01 13:05:26 -0700147 @Activate
148 protected void activate() {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700149 appId = coreService
150 .registerApplication("org.onosproject.segmentrouting");
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700151
152 kryoBuilder = new KryoNamespace.Builder()
153 .register(NeighborSetNextObjectiveStoreKey.class,
sangho0b2b6d12015-05-20 22:16:38 -0700154 NeighborSet.class,
155 DeviceId.class,
156 URI.class,
157 WallClockTimestamp.class,
158 org.onosproject.cluster.NodeId.class,
159 HashSet.class,
160 Tunnel.class,
161 DefaultTunnel.class,
162 Policy.class,
163 TunnelPolicy.class,
164 Policy.Type.class
165 );
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700166
167 log.debug("Creating EC map nsnextobjectivestore");
168 EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
169 nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
170
171 nsNextObjStore = nsNextObjMapBuilder
172 .withName("nsnextobjectivestore")
173 .withSerializer(kryoBuilder)
174 .withClockService(new WallclockClockManager<>())
175 .build();
176 log.trace("Current size {}", nsNextObjStore.size());
177
sangho0b2b6d12015-05-20 22:16:38 -0700178 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
179 storageService.eventuallyConsistentMapBuilder();
180
181 tunnelStore = tunnelMapBuilder
182 .withName("tunnelstore")
183 .withSerializer(kryoBuilder)
184 .withClockService(new WallclockClockManager<>())
185 .build();
186
187 EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
188 storageService.eventuallyConsistentMapBuilder();
189
190 policyStore = policyMapBuilder
191 .withName("policystore")
192 .withSerializer(kryoBuilder)
193 .withClockService(new WallclockClockManager<>())
194 .build();
195
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700196 networkConfigService.init();
197 deviceConfiguration = new DeviceConfiguration(networkConfigService);
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700198 arpHandler = new ArpHandler(this);
199 icmpHandler = new IcmpHandler(this);
200 ipHandler = new IpHandler(this);
201 routingRulePopulator = new RoutingRulePopulator(this);
202 defaultRoutingHandler = new DefaultRoutingHandler(this);
sangho0b2b6d12015-05-20 22:16:38 -0700203 tunnelHandler = new TunnelHandler(this, tunnelStore);
204 policyHandler = new PolicyHandler(this, policyStore);
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700205
sanghob35a6192015-04-01 13:05:26 -0700206 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
207 linkService.addListener(new InternalLinkListener());
sanghob35a6192015-04-01 13:05:26 -0700208 deviceService.addListener(new InternalDeviceListener());
209
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700210 for (Device device : deviceService.getDevices()) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700211 //Irrespective whether the local is a MASTER or not for this device,
212 //create group handler instance and push default TTP flow rules.
213 //Because in a multi-instance setup, instances can initiate
214 //groups for any devices. Also the default TTP rules are needed
215 //to be pushed before inserting any IP table entries for any device
216 DefaultGroupHandler groupHandler = DefaultGroupHandler
217 .createGroupHandler(device.id(), appId,
218 deviceConfiguration, linkService,
219 flowObjectiveService,
220 nsNextObjStore);
221 groupHandlerMap.put(device.id(), groupHandler);
222 defaultRoutingHandler.populateTtpRules(device.id());
sanghob35a6192015-04-01 13:05:26 -0700223 }
224
sangho20eff1d2015-04-13 15:15:58 -0700225 defaultRoutingHandler.startPopulationProcess();
sanghob35a6192015-04-01 13:05:26 -0700226 log.info("Started");
sangho1e575652015-05-14 00:39:53 -0700227
sanghob35a6192015-04-01 13:05:26 -0700228 }
229
230 @Deactivate
231 protected void deactivate() {
232 packetService.removeProcessor(processor);
233 processor = null;
234 log.info("Stopped");
235 }
236
sangho1e575652015-05-14 00:39:53 -0700237
238 @Override
239 public List<Tunnel> getTunnels() {
240 return tunnelHandler.getTunnels();
241 }
242
243 @Override
244 public void createTunnel(Tunnel tunnel) {
245 tunnelHandler.createTunnel(tunnel);
246 }
247
248 @Override
249 public void removeTunnel(Tunnel tunnel) {
250 for (Policy policy: policyHandler.getPolicies()) {
251 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
252 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
253 if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
254 log.warn("Cannot remove the tunnel used by a policy");
255 return;
256 }
257 }
258 }
259 tunnelHandler.removeTunnel(tunnel);
260 }
261
262 @Override
263 public void removePolicy(Policy policy) {
264 policyHandler.removePolicy(policy);
265
266 }
267
268 @Override
269 public void createPolicy(Policy policy) {
270 policyHandler.createPolicy(policy);
271 }
272
273 @Override
274 public List<Policy> getPolicies() {
275 return policyHandler.getPolicies();
276 }
277
sanghof9d0bf12015-05-19 11:57:42 -0700278 /**
279 * Returns the tunnel object with the tunnel ID.
280 *
281 * @param tunnelId Tunnel ID
282 * @return Tunnel reference
283 */
sangho1e575652015-05-14 00:39:53 -0700284 public Tunnel getTunnel(String tunnelId) {
285 return tunnelHandler.getTunnel(tunnelId);
286 }
287
sanghob35a6192015-04-01 13:05:26 -0700288 /**
289 * Returns the GrouopKey object for the device and the NighborSet given.
290 *
291 * @param ns NeightborSet object for the GroupKey
292 * @return GroupKey object for the NeighborSet
293 */
294 public GroupKey getGroupKey(NeighborSet ns) {
295
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700296 for (DefaultGroupHandler groupHandler : groupHandlerMap.values()) {
sanghob35a6192015-04-01 13:05:26 -0700297 return groupHandler.getGroupKey(ns);
298 }
299
300 return null;
301 }
302
sangho1e575652015-05-14 00:39:53 -0700303 /**
sanghof9d0bf12015-05-19 11:57:42 -0700304 * Returns the next objective ID for the NeighborSet given. If the nextObjectiveID does not exist,
305 * a new one is created and returned.
sangho1e575652015-05-14 00:39:53 -0700306 *
sanghof9d0bf12015-05-19 11:57:42 -0700307 * @param deviceId Device ID
308 * @param ns NegighborSet
309 * @return next objective ID
sangho1e575652015-05-14 00:39:53 -0700310 */
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700311 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
312
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700313 if (groupHandlerMap.get(deviceId) != null) {
314 log.trace("getNextObjectiveId query in device {}", deviceId);
315 return groupHandlerMap
316 .get(deviceId).getNextObjectiveId(ns);
317 } else {
318 log.warn("getNextObjectiveId query in device {} not found", deviceId);
319 return -1;
320 }
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700321 }
322
sangho1e575652015-05-14 00:39:53 -0700323 /**
sangho0b2b6d12015-05-20 22:16:38 -0700324 * Checks if the next objective ID (group) for the neighbor set exists or not in the device.
325 *
326 * @param deviceId Device ID to check
327 * @param ns neighbor set to check
328 * @return true if it exists, false otherwise
329 */
330 public boolean hasNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
331 if (groupHandlerMap.get(deviceId) != null) {
332 log.trace("getNextObjectiveId query in device {}", deviceId);
333 return groupHandlerMap
334 .get(deviceId).hasNextObjectiveId(ns);
335 } else {
336 log.warn("getNextObjectiveId query in device {} not found", deviceId);
337 return false;
338 }
339 }
340
341 /**
sanghof9d0bf12015-05-19 11:57:42 -0700342 * Removes the next objective ID.
sangho1e575652015-05-14 00:39:53 -0700343 *
sanghof9d0bf12015-05-19 11:57:42 -0700344 * @param deviceId Device ID
345 * @param objectiveId next objective ID to remove
346 * @return true, if succeeds, false otherwise
sangho1e575652015-05-14 00:39:53 -0700347 */
348 public boolean removeNextObjective(DeviceId deviceId, int objectiveId) {
349 return groupHandlerMap.get(deviceId).removeGroup(objectiveId);
350 }
351
sanghob35a6192015-04-01 13:05:26 -0700352 private class InternalPacketProcessor implements PacketProcessor {
353
354 @Override
355 public void process(PacketContext context) {
356
357 if (context.isHandled()) {
358 return;
359 }
360
361 InboundPacket pkt = context.inPacket();
362 Ethernet ethernet = pkt.parsed();
363
364 if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
365 arpHandler.processPacketIn(pkt);
366 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
367 IPv4 ipPacket = (IPv4) ethernet.getPayload();
368 ipHandler.addToPacketBuffer(ipPacket);
369 if (ipPacket.getProtocol() == IPv4.PROTOCOL_ICMP) {
370 icmpHandler.processPacketIn(pkt);
371 } else {
372 ipHandler.processPacketIn(pkt);
373 }
374 }
375 }
376 }
377
378 private class InternalLinkListener implements LinkListener {
379 @Override
380 public void event(LinkEvent event) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700381 if (event.type() == LinkEvent.Type.LINK_ADDED
382 || event.type() == LinkEvent.Type.LINK_REMOVED) {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700383 log.debug("Event {} received from Link Service", event.type());
sanghob35a6192015-04-01 13:05:26 -0700384 scheduleEventHandlerIfNotScheduled(event);
385 }
386 }
387 }
388
389 private class InternalDeviceListener implements DeviceListener {
390
391 @Override
392 public void event(DeviceEvent event) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700393 /*if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
sanghob35a6192015-04-01 13:05:26 -0700394 log.debug("Local role {} is not MASTER for device {}",
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700395 mastershipService.getLocalRole(event.subject().id()),
396 event.subject().id());
sanghob35a6192015-04-01 13:05:26 -0700397 return;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700398 }*/
sanghob35a6192015-04-01 13:05:26 -0700399
400 switch (event.type()) {
401 case DEVICE_ADDED:
402 case PORT_REMOVED:
sangho20eff1d2015-04-13 15:15:58 -0700403 case DEVICE_UPDATED:
404 case DEVICE_AVAILABILITY_CHANGED:
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700405 log.debug("Event {} received from Device Service", event.type());
sanghob35a6192015-04-01 13:05:26 -0700406 scheduleEventHandlerIfNotScheduled(event);
407 break;
408 default:
409 }
410 }
411 }
412
sanghob35a6192015-04-01 13:05:26 -0700413 private void scheduleEventHandlerIfNotScheduled(Event event) {
414
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700415 synchronized (threadSchedulerLock) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700416 eventQueue.add(event);
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700417 numOfEventsQueued++;
418
419 if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
420 //No pending scheduled event handling threads. So start a new one.
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700421 eventHandlerFuture = executorService
422 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
423 numOfHandlerScheduled++;
424 }
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700425 log.trace("numOfEventsQueued {}, numOfEventHanlderScheduled {}",
426 numOfEventsQueued,
427 numOfHandlerScheduled);
sanghob35a6192015-04-01 13:05:26 -0700428 }
sanghob35a6192015-04-01 13:05:26 -0700429 }
430
431 private class InternalEventHandler implements Runnable {
432
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700433 @Override
sanghob35a6192015-04-01 13:05:26 -0700434 public void run() {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700435 try {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700436 while (true) {
437 Event event = null;
438 synchronized (threadSchedulerLock) {
439 if (!eventQueue.isEmpty()) {
440 event = eventQueue.poll();
441 numOfEventsExecuted++;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700442 } else {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700443 numOfHandlerExecution++;
444 log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
445 numOfHandlerExecution, numOfEventsExecuted);
446 break;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700447 }
sangho20eff1d2015-04-13 15:15:58 -0700448 }
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700449 if (event.type() == LinkEvent.Type.LINK_ADDED) {
450 processLinkAdded((Link) event.subject());
451 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
452 processLinkRemoved((Link) event.subject());
453 //} else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
454 // processGroupAdded((Group) event.subject());
455 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
456 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
457 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
458 if (deviceService.isAvailable(((Device) event.subject()).id())) {
459 processDeviceAdded((Device) event.subject());
460 }
461 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
462 processPortRemoved((Device) event.subject(),
463 ((DeviceEvent) event).port());
464 } else {
465 log.warn("Unhandled event type: {}", event.type());
466 }
sanghob35a6192015-04-01 13:05:26 -0700467 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700468 } catch (Exception e) {
469 log.error("SegmentRouting event handler "
470 + "thread thrown an exception: {}", e);
sanghob35a6192015-04-01 13:05:26 -0700471 }
sanghob35a6192015-04-01 13:05:26 -0700472 }
473 }
474
sanghob35a6192015-04-01 13:05:26 -0700475 private void processLinkAdded(Link link) {
476 log.debug("A new link {} was added", link.toString());
477
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700478 //Irrespective whether the local is a MASTER or not for this device,
479 //create group handler instance and push default TTP flow rules.
480 //Because in a multi-instance setup, instances can initiate
481 //groups for any devices. Also the default TTP rules are needed
482 //to be pushed before inserting any IP table entries for any device
483 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
484 .deviceId());
485 if (groupHandler != null) {
486 groupHandler.linkUp(link);
487 } else {
488 Device device = deviceService.getDevice(link.src().deviceId());
489 if (device != null) {
490 log.warn("processLinkAdded: Link Added "
491 + "Notification without Device Added "
492 + "event, still handling it");
493 processDeviceAdded(device);
494 groupHandler = groupHandlerMap.get(link.src()
495 .deviceId());
sanghob35a6192015-04-01 13:05:26 -0700496 groupHandler.linkUp(link);
497 }
498 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700499
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700500 log.trace("Starting optimized route population process");
501 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
502 //log.trace("processLinkAdded: re-starting route population process");
503 //defaultRoutingHandler.startPopulationProcess();
sanghob35a6192015-04-01 13:05:26 -0700504 }
505
506 private void processLinkRemoved(Link link) {
507 log.debug("A link {} was removed", link.toString());
sangho834e4b02015-05-01 09:38:25 -0700508 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId());
509 if (groupHandler != null) {
510 groupHandler.portDown(link.src().port());
511 }
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700512 log.trace("Starting optimized route population process");
513 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
514 //log.trace("processLinkRemoved: re-starting route population process");
515 //defaultRoutingHandler.startPopulationProcess();
sanghob35a6192015-04-01 13:05:26 -0700516 }
517
518 private void processDeviceAdded(Device device) {
519 log.debug("A new device with ID {} was added", device.id());
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700520 //Irrespective whether the local is a MASTER or not for this device,
521 //create group handler instance and push default TTP flow rules.
522 //Because in a multi-instance setup, instances can initiate
523 //groups for any devices. Also the default TTP rules are needed
524 //to be pushed before inserting any IP table entries for any device
525 DefaultGroupHandler dgh = DefaultGroupHandler.
526 createGroupHandler(device.id(),
527 appId,
528 deviceConfiguration,
529 linkService,
530 flowObjectiveService,
531 nsNextObjStore);
sanghob35a6192015-04-01 13:05:26 -0700532 groupHandlerMap.put(device.id(), dgh);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700533 defaultRoutingHandler.populateTtpRules(device.id());
sanghob35a6192015-04-01 13:05:26 -0700534 }
535
536 private void processPortRemoved(Device device, Port port) {
537 log.debug("Port {} was removed", port.toString());
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700538 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
sanghob35a6192015-04-01 13:05:26 -0700539 if (groupHandler != null) {
540 groupHandler.portDown(port.number());
541 }
542 }
sangho1e575652015-05-14 00:39:53 -0700543
544
545
sanghob35a6192015-04-01 13:05:26 -0700546}