blob: f473ccebd8f1c8948af7740791de935e07bdabe8 [file] [log] [blame]
sangho80f11cb2015-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;
sangho27462c62015-05-14 00:39:53 -070023import org.apache.felix.scr.annotations.Service;
sangho80f11cb2015-04-01 13:05:26 -070024import org.onlab.packet.Ethernet;
25import org.onlab.packet.IPv4;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070026import org.onlab.util.KryoNamespace;
sangho80f11cb2015-04-01 13:05:26 -070027import org.onosproject.core.ApplicationId;
28import org.onosproject.core.CoreService;
29import org.onosproject.event.Event;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070030import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
31import org.onosproject.segmentrouting.grouphandler.NeighborSet;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070032import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey;
sangho80f11cb2015-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;
sangho80f11cb2015-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 Vavilapalli64505482015-04-21 13:04:13 -070041import org.onosproject.net.flowobjective.FlowObjectiveService;
sangho80f11cb2015-04-01 13:05:26 -070042import org.onosproject.net.group.GroupKey;
sangho80f11cb2015-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 Vavilapalli37a461b2015-04-07 15:12:32 -070053import org.onosproject.segmentrouting.config.NetworkConfigManager;
Srikanth Vavilapalli7cd16712015-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;
sangho80f11cb2015-04-01 13:05:26 -070058import org.slf4j.Logger;
59import org.slf4j.LoggerFactory;
60
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070061import java.net.URI;
62import java.util.HashSet;
sangho27462c62015-05-14 00:39:53 -070063import java.util.List;
sangho80f11cb2015-04-01 13:05:26 -070064import java.util.Map;
65import java.util.concurrent.ConcurrentHashMap;
66import java.util.concurrent.ConcurrentLinkedQueue;
67import java.util.concurrent.Executors;
68import java.util.concurrent.ScheduledExecutorService;
69import java.util.concurrent.ScheduledFuture;
70import java.util.concurrent.TimeUnit;
71
72@SuppressWarnings("ALL")
sangho27462c62015-05-14 00:39:53 -070073@Service
sangho80f11cb2015-04-01 13:05:26 -070074@Component(immediate = true)
sangho27462c62015-05-14 00:39:53 -070075public class SegmentRoutingManager implements SegmentRoutingService {
sangho80f11cb2015-04-01 13:05:26 -070076
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070077 private static Logger log = LoggerFactory
78 .getLogger(SegmentRoutingManager.class);
sangho80f11cb2015-04-01 13:05:26 -070079
80 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81 protected CoreService coreService;
82
83 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 protected TopologyService topologyService;
85
86 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected PacketService packetService;
88
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 protected IntentService intentService;
91
92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
93 protected HostService hostService;
94
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 protected DeviceService deviceService;
97
98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070099 protected FlowObjectiveService flowObjectiveService;
sangho80f11cb2015-04-01 13:05:26 -0700100
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected LinkService linkService;
103
104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
sangho80f11cb2015-04-01 13:05:26 -0700105 protected MastershipService mastershipService;
sangho27462c62015-05-14 00:39:53 -0700106
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700107 protected ArpHandler arpHandler = null;
108 protected IcmpHandler icmpHandler = null;
109 protected IpHandler ipHandler = null;
110 protected RoutingRulePopulator routingRulePopulator = null;
sangho80f11cb2015-04-01 13:05:26 -0700111 protected ApplicationId appId;
sangho9b169e32015-04-14 16:27:13 -0700112 protected DeviceConfiguration deviceConfiguration = null;
sangho80f11cb2015-04-01 13:05:26 -0700113
sangho27462c62015-05-14 00:39:53 -0700114
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700115 private DefaultRoutingHandler defaultRoutingHandler = null;
sangho27462c62015-05-14 00:39:53 -0700116 private TunnelHandler tunnelHandler = null;
117 private PolicyHandler policyHandler = null;
sangho80f11cb2015-04-01 13:05:26 -0700118 private InternalPacketProcessor processor = new InternalPacketProcessor();
119 private InternalEventHandler eventHandler = new InternalEventHandler();
120
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700121 private ScheduledExecutorService executorService = Executors
122 .newScheduledThreadPool(1);
sangho80f11cb2015-04-01 13:05:26 -0700123
124 private static ScheduledFuture<?> eventHandlerFuture = null;
125 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700126 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700127 // Per device next objective ID store with (device id + neighbor set) as key
128 private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
129 Integer> nsNextObjStore = null;
sangho4a5c42a2015-05-20 22:16:38 -0700130 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
131 private EventuallyConsistentMap<String, Policy> policyStore = null;
132
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
134 protected StorageService storageService;
sangho80f11cb2015-04-01 13:05:26 -0700135
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700136 private NetworkConfigManager networkConfigService = new NetworkConfigManager();;
137
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700138 private Object threadSchedulerLock = new Object();
139 private static int numOfEventsQueued = 0;
140 private static int numOfEventsExecuted = 0;
sangho80f11cb2015-04-01 13:05:26 -0700141 private static int numOfHandlerExecution = 0;
142 private static int numOfHandlerScheduled = 0;
143
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700144 private KryoNamespace.Builder kryoBuilder = null;
145
sangho80f11cb2015-04-01 13:05:26 -0700146 @Activate
147 protected void activate() {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700148 appId = coreService
149 .registerApplication("org.onosproject.segmentrouting");
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700150
151 kryoBuilder = new KryoNamespace.Builder()
152 .register(NeighborSetNextObjectiveStoreKey.class,
sangho4a5c42a2015-05-20 22:16:38 -0700153 NeighborSet.class,
154 DeviceId.class,
155 URI.class,
156 WallClockTimestamp.class,
157 org.onosproject.cluster.NodeId.class,
158 HashSet.class,
159 Tunnel.class,
160 DefaultTunnel.class,
161 Policy.class,
162 TunnelPolicy.class,
163 Policy.Type.class
164 );
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700165
166 log.debug("Creating EC map nsnextobjectivestore");
167 EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
168 nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
169
170 nsNextObjStore = nsNextObjMapBuilder
171 .withName("nsnextobjectivestore")
172 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700173 .withTimestampProvider((k, v) -> new WallClockTimestamp())
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700174 .build();
175 log.trace("Current size {}", nsNextObjStore.size());
176
sangho4a5c42a2015-05-20 22:16:38 -0700177 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
178 storageService.eventuallyConsistentMapBuilder();
179
180 tunnelStore = tunnelMapBuilder
181 .withName("tunnelstore")
182 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700183 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho4a5c42a2015-05-20 22:16:38 -0700184 .build();
185
186 EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
187 storageService.eventuallyConsistentMapBuilder();
188
189 policyStore = policyMapBuilder
190 .withName("policystore")
191 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700192 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho4a5c42a2015-05-20 22:16:38 -0700193 .build();
194
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700195 networkConfigService.init();
196 deviceConfiguration = new DeviceConfiguration(networkConfigService);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700197 arpHandler = new ArpHandler(this);
198 icmpHandler = new IcmpHandler(this);
199 ipHandler = new IpHandler(this);
200 routingRulePopulator = new RoutingRulePopulator(this);
201 defaultRoutingHandler = new DefaultRoutingHandler(this);
sangho4a5c42a2015-05-20 22:16:38 -0700202 tunnelHandler = new TunnelHandler(this, tunnelStore);
203 policyHandler = new PolicyHandler(this, policyStore);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700204
sangho80f11cb2015-04-01 13:05:26 -0700205 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
206 linkService.addListener(new InternalLinkListener());
sangho80f11cb2015-04-01 13:05:26 -0700207 deviceService.addListener(new InternalDeviceListener());
208
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700209 for (Device device : deviceService.getDevices()) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700210 //Irrespective whether the local is a MASTER or not for this device,
211 //create group handler instance and push default TTP flow rules.
212 //Because in a multi-instance setup, instances can initiate
213 //groups for any devices. Also the default TTP rules are needed
214 //to be pushed before inserting any IP table entries for any device
215 DefaultGroupHandler groupHandler = DefaultGroupHandler
216 .createGroupHandler(device.id(), appId,
217 deviceConfiguration, linkService,
218 flowObjectiveService,
219 nsNextObjStore);
220 groupHandlerMap.put(device.id(), groupHandler);
221 defaultRoutingHandler.populateTtpRules(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700222 }
223
sanghofb7c7292015-04-13 15:15:58 -0700224 defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700225 log.info("Started");
sangho27462c62015-05-14 00:39:53 -0700226
sangho80f11cb2015-04-01 13:05:26 -0700227 }
228
229 @Deactivate
230 protected void deactivate() {
231 packetService.removeProcessor(processor);
232 processor = null;
233 log.info("Stopped");
234 }
235
sangho27462c62015-05-14 00:39:53 -0700236
237 @Override
238 public List<Tunnel> getTunnels() {
239 return tunnelHandler.getTunnels();
240 }
241
242 @Override
243 public void createTunnel(Tunnel tunnel) {
244 tunnelHandler.createTunnel(tunnel);
245 }
246
247 @Override
248 public void removeTunnel(Tunnel tunnel) {
249 for (Policy policy: policyHandler.getPolicies()) {
250 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
251 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
252 if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
253 log.warn("Cannot remove the tunnel used by a policy");
254 return;
255 }
256 }
257 }
258 tunnelHandler.removeTunnel(tunnel);
259 }
260
261 @Override
262 public void removePolicy(Policy policy) {
263 policyHandler.removePolicy(policy);
264
265 }
266
267 @Override
268 public void createPolicy(Policy policy) {
269 policyHandler.createPolicy(policy);
270 }
271
272 @Override
273 public List<Policy> getPolicies() {
274 return policyHandler.getPolicies();
275 }
276
sangho80f1f892015-05-19 11:57:42 -0700277 /**
278 * Returns the tunnel object with the tunnel ID.
279 *
280 * @param tunnelId Tunnel ID
281 * @return Tunnel reference
282 */
sangho27462c62015-05-14 00:39:53 -0700283 public Tunnel getTunnel(String tunnelId) {
284 return tunnelHandler.getTunnel(tunnelId);
285 }
286
sangho80f11cb2015-04-01 13:05:26 -0700287 /**
288 * Returns the GrouopKey object for the device and the NighborSet given.
289 *
290 * @param ns NeightborSet object for the GroupKey
291 * @return GroupKey object for the NeighborSet
292 */
293 public GroupKey getGroupKey(NeighborSet ns) {
294
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700295 for (DefaultGroupHandler groupHandler : groupHandlerMap.values()) {
sangho80f11cb2015-04-01 13:05:26 -0700296 return groupHandler.getGroupKey(ns);
297 }
298
299 return null;
300 }
301
sangho27462c62015-05-14 00:39:53 -0700302 /**
sangho80f1f892015-05-19 11:57:42 -0700303 * Returns the next objective ID for the NeighborSet given. If the nextObjectiveID does not exist,
304 * a new one is created and returned.
sangho27462c62015-05-14 00:39:53 -0700305 *
sangho80f1f892015-05-19 11:57:42 -0700306 * @param deviceId Device ID
307 * @param ns NegighborSet
308 * @return next objective ID
sangho27462c62015-05-14 00:39:53 -0700309 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700310 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
311
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700312 if (groupHandlerMap.get(deviceId) != null) {
313 log.trace("getNextObjectiveId query in device {}", deviceId);
314 return groupHandlerMap
315 .get(deviceId).getNextObjectiveId(ns);
316 } else {
317 log.warn("getNextObjectiveId query in device {} not found", deviceId);
318 return -1;
319 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700320 }
321
sangho27462c62015-05-14 00:39:53 -0700322 /**
sangho4a5c42a2015-05-20 22:16:38 -0700323 * Checks if the next objective ID (group) for the neighbor set exists or not in the device.
324 *
325 * @param deviceId Device ID to check
326 * @param ns neighbor set to check
327 * @return true if it exists, false otherwise
328 */
329 public boolean hasNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
330 if (groupHandlerMap.get(deviceId) != null) {
331 log.trace("getNextObjectiveId query in device {}", deviceId);
332 return groupHandlerMap
333 .get(deviceId).hasNextObjectiveId(ns);
334 } else {
335 log.warn("getNextObjectiveId query in device {} not found", deviceId);
336 return false;
337 }
338 }
339
340 /**
sangho80f1f892015-05-19 11:57:42 -0700341 * Removes the next objective ID.
sangho27462c62015-05-14 00:39:53 -0700342 *
sangho80f1f892015-05-19 11:57:42 -0700343 * @param deviceId Device ID
344 * @param objectiveId next objective ID to remove
345 * @return true, if succeeds, false otherwise
sangho27462c62015-05-14 00:39:53 -0700346 */
347 public boolean removeNextObjective(DeviceId deviceId, int objectiveId) {
348 return groupHandlerMap.get(deviceId).removeGroup(objectiveId);
349 }
350
sangho80f11cb2015-04-01 13:05:26 -0700351 private class InternalPacketProcessor implements PacketProcessor {
352
353 @Override
354 public void process(PacketContext context) {
355
356 if (context.isHandled()) {
357 return;
358 }
359
360 InboundPacket pkt = context.inPacket();
361 Ethernet ethernet = pkt.parsed();
362
363 if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
364 arpHandler.processPacketIn(pkt);
365 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
366 IPv4 ipPacket = (IPv4) ethernet.getPayload();
367 ipHandler.addToPacketBuffer(ipPacket);
368 if (ipPacket.getProtocol() == IPv4.PROTOCOL_ICMP) {
369 icmpHandler.processPacketIn(pkt);
370 } else {
371 ipHandler.processPacketIn(pkt);
372 }
373 }
374 }
375 }
376
377 private class InternalLinkListener implements LinkListener {
378 @Override
379 public void event(LinkEvent event) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700380 if (event.type() == LinkEvent.Type.LINK_ADDED
381 || event.type() == LinkEvent.Type.LINK_REMOVED) {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700382 log.debug("Event {} received from Link Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700383 scheduleEventHandlerIfNotScheduled(event);
384 }
385 }
386 }
387
388 private class InternalDeviceListener implements DeviceListener {
389
390 @Override
391 public void event(DeviceEvent event) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700392 /*if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
sangho80f11cb2015-04-01 13:05:26 -0700393 log.debug("Local role {} is not MASTER for device {}",
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700394 mastershipService.getLocalRole(event.subject().id()),
395 event.subject().id());
sangho80f11cb2015-04-01 13:05:26 -0700396 return;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700397 }*/
sangho80f11cb2015-04-01 13:05:26 -0700398
399 switch (event.type()) {
400 case DEVICE_ADDED:
401 case PORT_REMOVED:
sanghofb7c7292015-04-13 15:15:58 -0700402 case DEVICE_UPDATED:
403 case DEVICE_AVAILABILITY_CHANGED:
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700404 log.debug("Event {} received from Device Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700405 scheduleEventHandlerIfNotScheduled(event);
406 break;
407 default:
408 }
409 }
410 }
411
sangho80f11cb2015-04-01 13:05:26 -0700412 private void scheduleEventHandlerIfNotScheduled(Event event) {
413
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700414 synchronized (threadSchedulerLock) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700415 eventQueue.add(event);
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700416 numOfEventsQueued++;
417
418 if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
419 //No pending scheduled event handling threads. So start a new one.
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700420 eventHandlerFuture = executorService
421 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
422 numOfHandlerScheduled++;
423 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700424 log.trace("numOfEventsQueued {}, numOfEventHanlderScheduled {}",
425 numOfEventsQueued,
426 numOfHandlerScheduled);
sangho80f11cb2015-04-01 13:05:26 -0700427 }
sangho80f11cb2015-04-01 13:05:26 -0700428 }
429
430 private class InternalEventHandler implements Runnable {
431
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700432 @Override
sangho80f11cb2015-04-01 13:05:26 -0700433 public void run() {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700434 try {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700435 while (true) {
436 Event event = null;
437 synchronized (threadSchedulerLock) {
438 if (!eventQueue.isEmpty()) {
439 event = eventQueue.poll();
440 numOfEventsExecuted++;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700441 } else {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700442 numOfHandlerExecution++;
443 log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
444 numOfHandlerExecution, numOfEventsExecuted);
445 break;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700446 }
sanghofb7c7292015-04-13 15:15:58 -0700447 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700448 if (event.type() == LinkEvent.Type.LINK_ADDED) {
449 processLinkAdded((Link) event.subject());
450 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
451 processLinkRemoved((Link) event.subject());
452 //} else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
453 // processGroupAdded((Group) event.subject());
454 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
455 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
456 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
457 if (deviceService.isAvailable(((Device) event.subject()).id())) {
458 processDeviceAdded((Device) event.subject());
459 }
460 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
461 processPortRemoved((Device) event.subject(),
462 ((DeviceEvent) event).port());
463 } else {
464 log.warn("Unhandled event type: {}", event.type());
465 }
sangho80f11cb2015-04-01 13:05:26 -0700466 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700467 } catch (Exception e) {
468 log.error("SegmentRouting event handler "
469 + "thread thrown an exception: {}", e);
sangho80f11cb2015-04-01 13:05:26 -0700470 }
sangho80f11cb2015-04-01 13:05:26 -0700471 }
472 }
473
sangho80f11cb2015-04-01 13:05:26 -0700474 private void processLinkAdded(Link link) {
475 log.debug("A new link {} was added", link.toString());
476
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700477 //Irrespective whether the local is a MASTER or not for this device,
478 //create group handler instance and push default TTP flow rules.
479 //Because in a multi-instance setup, instances can initiate
480 //groups for any devices. Also the default TTP rules are needed
481 //to be pushed before inserting any IP table entries for any device
482 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
483 .deviceId());
484 if (groupHandler != null) {
485 groupHandler.linkUp(link);
486 } else {
487 Device device = deviceService.getDevice(link.src().deviceId());
488 if (device != null) {
489 log.warn("processLinkAdded: Link Added "
490 + "Notification without Device Added "
491 + "event, still handling it");
492 processDeviceAdded(device);
493 groupHandler = groupHandlerMap.get(link.src()
494 .deviceId());
sangho80f11cb2015-04-01 13:05:26 -0700495 groupHandler.linkUp(link);
496 }
497 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700498
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700499 log.trace("Starting optimized route population process");
500 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
501 //log.trace("processLinkAdded: re-starting route population process");
502 //defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700503 }
504
505 private void processLinkRemoved(Link link) {
506 log.debug("A link {} was removed", link.toString());
sangho2165d222015-05-01 09:38:25 -0700507 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId());
508 if (groupHandler != null) {
509 groupHandler.portDown(link.src().port());
510 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700511 log.trace("Starting optimized route population process");
512 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
513 //log.trace("processLinkRemoved: re-starting route population process");
514 //defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700515 }
516
517 private void processDeviceAdded(Device device) {
518 log.debug("A new device with ID {} was added", device.id());
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700519 //Irrespective whether the local is a MASTER or not for this device,
520 //create group handler instance and push default TTP flow rules.
521 //Because in a multi-instance setup, instances can initiate
522 //groups for any devices. Also the default TTP rules are needed
523 //to be pushed before inserting any IP table entries for any device
524 DefaultGroupHandler dgh = DefaultGroupHandler.
525 createGroupHandler(device.id(),
526 appId,
527 deviceConfiguration,
528 linkService,
529 flowObjectiveService,
530 nsNextObjStore);
sangho80f11cb2015-04-01 13:05:26 -0700531 groupHandlerMap.put(device.id(), dgh);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700532 defaultRoutingHandler.populateTtpRules(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700533 }
534
535 private void processPortRemoved(Device device, Port port) {
536 log.debug("Port {} was removed", port.toString());
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700537 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700538 if (groupHandler != null) {
539 groupHandler.portDown(port.number());
540 }
541 }
sangho27462c62015-05-14 00:39:53 -0700542
543
544
sangho80f11cb2015-04-01 13:05:26 -0700545}