blob: 874faabfe9f879975632fbda941cd233f1a2a922 [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);
sanghobd812f82015-06-29 14:58:47 -0700202 tunnelHandler = new TunnelHandler(linkService, deviceConfiguration,
203 groupHandlerMap, tunnelStore);
204 policyHandler = new PolicyHandler(appId, deviceConfiguration,
205 flowObjectiveService, tunnelHandler, policyStore);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700206
Brian O'Connorfe78f252015-07-29 17:49:24 -0700207 packetService.addProcessor(processor, PacketProcessor.director(2));
sangho80f11cb2015-04-01 13:05:26 -0700208 linkService.addListener(new InternalLinkListener());
sangho80f11cb2015-04-01 13:05:26 -0700209 deviceService.addListener(new InternalDeviceListener());
210
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700211 for (Device device : deviceService.getDevices()) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700212 //Irrespective whether the local is a MASTER or not for this device,
213 //create group handler instance and push default TTP flow rules.
214 //Because in a multi-instance setup, instances can initiate
215 //groups for any devices. Also the default TTP rules are needed
216 //to be pushed before inserting any IP table entries for any device
217 DefaultGroupHandler groupHandler = DefaultGroupHandler
218 .createGroupHandler(device.id(), appId,
219 deviceConfiguration, linkService,
220 flowObjectiveService,
221 nsNextObjStore);
222 groupHandlerMap.put(device.id(), groupHandler);
223 defaultRoutingHandler.populateTtpRules(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700224 }
225
sanghofb7c7292015-04-13 15:15:58 -0700226 defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700227 log.info("Started");
sangho27462c62015-05-14 00:39:53 -0700228
sangho80f11cb2015-04-01 13:05:26 -0700229 }
230
231 @Deactivate
232 protected void deactivate() {
233 packetService.removeProcessor(processor);
234 processor = null;
235 log.info("Stopped");
236 }
237
sangho27462c62015-05-14 00:39:53 -0700238
239 @Override
240 public List<Tunnel> getTunnels() {
241 return tunnelHandler.getTunnels();
242 }
243
244 @Override
sanghobd812f82015-06-29 14:58:47 -0700245 public TunnelHandler.Result createTunnel(Tunnel tunnel) {
246 return tunnelHandler.createTunnel(tunnel);
sangho27462c62015-05-14 00:39:53 -0700247 }
248
249 @Override
sanghobd812f82015-06-29 14:58:47 -0700250 public TunnelHandler.Result removeTunnel(Tunnel tunnel) {
sangho27462c62015-05-14 00:39:53 -0700251 for (Policy policy: policyHandler.getPolicies()) {
252 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
253 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
254 if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
255 log.warn("Cannot remove the tunnel used by a policy");
sanghobd812f82015-06-29 14:58:47 -0700256 return TunnelHandler.Result.TUNNEL_IN_USE;
sangho27462c62015-05-14 00:39:53 -0700257 }
258 }
259 }
sanghobd812f82015-06-29 14:58:47 -0700260 return tunnelHandler.removeTunnel(tunnel);
sangho27462c62015-05-14 00:39:53 -0700261 }
262
263 @Override
sanghobd812f82015-06-29 14:58:47 -0700264 public PolicyHandler.Result removePolicy(Policy policy) {
265 return policyHandler.removePolicy(policy);
sangho27462c62015-05-14 00:39:53 -0700266 }
267
268 @Override
sanghobd812f82015-06-29 14:58:47 -0700269 public PolicyHandler.Result createPolicy(Policy policy) {
270 return policyHandler.createPolicy(policy);
sangho27462c62015-05-14 00:39:53 -0700271 }
272
273 @Override
274 public List<Policy> getPolicies() {
275 return policyHandler.getPolicies();
276 }
277
sangho80f1f892015-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 */
sangho27462c62015-05-14 00:39:53 -0700284 public Tunnel getTunnel(String tunnelId) {
285 return tunnelHandler.getTunnel(tunnelId);
286 }
287
sangho80f11cb2015-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 Vavilapalli64505482015-04-21 13:04:13 -0700296 for (DefaultGroupHandler groupHandler : groupHandlerMap.values()) {
sangho80f11cb2015-04-01 13:05:26 -0700297 return groupHandler.getGroupKey(ns);
298 }
299
300 return null;
301 }
302
sangho27462c62015-05-14 00:39:53 -0700303 /**
sangho80f1f892015-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.
sangho27462c62015-05-14 00:39:53 -0700306 *
sangho80f1f892015-05-19 11:57:42 -0700307 * @param deviceId Device ID
308 * @param ns NegighborSet
309 * @return next objective ID
sangho27462c62015-05-14 00:39:53 -0700310 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700311 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
312
Srikanth Vavilapalli7cd16712015-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 Vavilapalli64505482015-04-21 13:04:13 -0700321 }
322
sangho80f11cb2015-04-01 13:05:26 -0700323 private class InternalPacketProcessor implements PacketProcessor {
324
325 @Override
326 public void process(PacketContext context) {
327
328 if (context.isHandled()) {
329 return;
330 }
331
332 InboundPacket pkt = context.inPacket();
333 Ethernet ethernet = pkt.parsed();
334
335 if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
336 arpHandler.processPacketIn(pkt);
337 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
338 IPv4 ipPacket = (IPv4) ethernet.getPayload();
339 ipHandler.addToPacketBuffer(ipPacket);
340 if (ipPacket.getProtocol() == IPv4.PROTOCOL_ICMP) {
341 icmpHandler.processPacketIn(pkt);
342 } else {
343 ipHandler.processPacketIn(pkt);
344 }
345 }
346 }
347 }
348
349 private class InternalLinkListener implements LinkListener {
350 @Override
351 public void event(LinkEvent event) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700352 if (event.type() == LinkEvent.Type.LINK_ADDED
353 || event.type() == LinkEvent.Type.LINK_REMOVED) {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700354 log.debug("Event {} received from Link Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700355 scheduleEventHandlerIfNotScheduled(event);
356 }
357 }
358 }
359
360 private class InternalDeviceListener implements DeviceListener {
361
362 @Override
363 public void event(DeviceEvent event) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700364 /*if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
sangho80f11cb2015-04-01 13:05:26 -0700365 log.debug("Local role {} is not MASTER for device {}",
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700366 mastershipService.getLocalRole(event.subject().id()),
367 event.subject().id());
sangho80f11cb2015-04-01 13:05:26 -0700368 return;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700369 }*/
sangho80f11cb2015-04-01 13:05:26 -0700370
371 switch (event.type()) {
372 case DEVICE_ADDED:
373 case PORT_REMOVED:
sanghofb7c7292015-04-13 15:15:58 -0700374 case DEVICE_UPDATED:
375 case DEVICE_AVAILABILITY_CHANGED:
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700376 log.debug("Event {} received from Device Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700377 scheduleEventHandlerIfNotScheduled(event);
378 break;
379 default:
380 }
381 }
382 }
383
sangho80f11cb2015-04-01 13:05:26 -0700384 private void scheduleEventHandlerIfNotScheduled(Event event) {
385
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700386 synchronized (threadSchedulerLock) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700387 eventQueue.add(event);
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700388 numOfEventsQueued++;
389
390 if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
391 //No pending scheduled event handling threads. So start a new one.
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700392 eventHandlerFuture = executorService
393 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
394 numOfHandlerScheduled++;
395 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700396 log.trace("numOfEventsQueued {}, numOfEventHanlderScheduled {}",
397 numOfEventsQueued,
398 numOfHandlerScheduled);
sangho80f11cb2015-04-01 13:05:26 -0700399 }
sangho80f11cb2015-04-01 13:05:26 -0700400 }
401
402 private class InternalEventHandler implements Runnable {
403
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700404 @Override
sangho80f11cb2015-04-01 13:05:26 -0700405 public void run() {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700406 try {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700407 while (true) {
408 Event event = null;
409 synchronized (threadSchedulerLock) {
410 if (!eventQueue.isEmpty()) {
411 event = eventQueue.poll();
412 numOfEventsExecuted++;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700413 } else {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700414 numOfHandlerExecution++;
415 log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
416 numOfHandlerExecution, numOfEventsExecuted);
417 break;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700418 }
sanghofb7c7292015-04-13 15:15:58 -0700419 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700420 if (event.type() == LinkEvent.Type.LINK_ADDED) {
421 processLinkAdded((Link) event.subject());
422 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
423 processLinkRemoved((Link) event.subject());
424 //} else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
425 // processGroupAdded((Group) event.subject());
426 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
427 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
428 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
429 if (deviceService.isAvailable(((Device) event.subject()).id())) {
430 processDeviceAdded((Device) event.subject());
431 }
432 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
433 processPortRemoved((Device) event.subject(),
434 ((DeviceEvent) event).port());
435 } else {
436 log.warn("Unhandled event type: {}", event.type());
437 }
sangho80f11cb2015-04-01 13:05:26 -0700438 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700439 } catch (Exception e) {
440 log.error("SegmentRouting event handler "
441 + "thread thrown an exception: {}", e);
sangho80f11cb2015-04-01 13:05:26 -0700442 }
sangho80f11cb2015-04-01 13:05:26 -0700443 }
444 }
445
sangho80f11cb2015-04-01 13:05:26 -0700446 private void processLinkAdded(Link link) {
447 log.debug("A new link {} was added", link.toString());
448
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700449 //Irrespective whether the local is a MASTER or not for this device,
450 //create group handler instance and push default TTP flow rules.
451 //Because in a multi-instance setup, instances can initiate
452 //groups for any devices. Also the default TTP rules are needed
453 //to be pushed before inserting any IP table entries for any device
454 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
455 .deviceId());
456 if (groupHandler != null) {
457 groupHandler.linkUp(link);
458 } else {
459 Device device = deviceService.getDevice(link.src().deviceId());
460 if (device != null) {
461 log.warn("processLinkAdded: Link Added "
462 + "Notification without Device Added "
463 + "event, still handling it");
464 processDeviceAdded(device);
465 groupHandler = groupHandlerMap.get(link.src()
466 .deviceId());
sangho80f11cb2015-04-01 13:05:26 -0700467 groupHandler.linkUp(link);
468 }
469 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700470
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700471 log.trace("Starting optimized route population process");
472 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
473 //log.trace("processLinkAdded: re-starting route population process");
474 //defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700475 }
476
477 private void processLinkRemoved(Link link) {
478 log.debug("A link {} was removed", link.toString());
sangho2165d222015-05-01 09:38:25 -0700479 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId());
480 if (groupHandler != null) {
481 groupHandler.portDown(link.src().port());
482 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700483 log.trace("Starting optimized route population process");
484 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
485 //log.trace("processLinkRemoved: re-starting route population process");
486 //defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700487 }
488
489 private void processDeviceAdded(Device device) {
490 log.debug("A new device with ID {} was added", device.id());
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700491 //Irrespective whether the local is a MASTER or not for this device,
492 //create group handler instance and push default TTP flow rules.
493 //Because in a multi-instance setup, instances can initiate
494 //groups for any devices. Also the default TTP rules are needed
495 //to be pushed before inserting any IP table entries for any device
496 DefaultGroupHandler dgh = DefaultGroupHandler.
497 createGroupHandler(device.id(),
498 appId,
499 deviceConfiguration,
500 linkService,
501 flowObjectiveService,
502 nsNextObjStore);
sangho80f11cb2015-04-01 13:05:26 -0700503 groupHandlerMap.put(device.id(), dgh);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700504 defaultRoutingHandler.populateTtpRules(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700505 }
506
507 private void processPortRemoved(Device device, Port port) {
508 log.debug("Port {} was removed", port.toString());
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700509 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700510 if (groupHandler != null) {
511 groupHandler.portDown(port.number());
512 }
513 }
sangho27462c62015-05-14 00:39:53 -0700514
515
516
sangho80f11cb2015-04-01 13:05:26 -0700517}