blob: 764bed3868b84017f795aab2c1d0b1b82ec7cccd [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;
Charles Chan72f556a2015-10-05 17:50:33 -070030import org.onosproject.net.config.ConfigFactory;
31import org.onosproject.net.config.NetworkConfigEvent;
32import org.onosproject.net.config.NetworkConfigRegistry;
33import org.onosproject.net.config.NetworkConfigListener;
34import org.onosproject.net.config.basics.SubjectFactories;
35import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070036import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
37import org.onosproject.segmentrouting.grouphandler.NeighborSet;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070038import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey;
sangho80f11cb2015-04-01 13:05:26 -070039import org.onosproject.mastership.MastershipService;
40import org.onosproject.net.Device;
41import org.onosproject.net.DeviceId;
42import org.onosproject.net.Link;
sangho80f11cb2015-04-01 13:05:26 -070043import org.onosproject.net.Port;
44import org.onosproject.net.device.DeviceEvent;
45import org.onosproject.net.device.DeviceListener;
46import org.onosproject.net.device.DeviceService;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070047import org.onosproject.net.flowobjective.FlowObjectiveService;
sangho80f11cb2015-04-01 13:05:26 -070048import org.onosproject.net.group.GroupKey;
sangho80f11cb2015-04-01 13:05:26 -070049import org.onosproject.net.host.HostService;
50import org.onosproject.net.intent.IntentService;
51import org.onosproject.net.link.LinkEvent;
52import org.onosproject.net.link.LinkListener;
53import org.onosproject.net.link.LinkService;
54import org.onosproject.net.packet.InboundPacket;
55import org.onosproject.net.packet.PacketContext;
56import org.onosproject.net.packet.PacketProcessor;
57import org.onosproject.net.packet.PacketService;
58import org.onosproject.net.topology.TopologyService;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070059import org.onosproject.store.service.EventuallyConsistentMap;
60import org.onosproject.store.service.EventuallyConsistentMapBuilder;
61import org.onosproject.store.service.StorageService;
62import org.onosproject.store.service.WallClockTimestamp;
sangho80f11cb2015-04-01 13:05:26 -070063import org.slf4j.Logger;
64import org.slf4j.LoggerFactory;
65
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070066import java.net.URI;
67import java.util.HashSet;
sangho27462c62015-05-14 00:39:53 -070068import java.util.List;
sangho80f11cb2015-04-01 13:05:26 -070069import java.util.Map;
70import java.util.concurrent.ConcurrentHashMap;
71import java.util.concurrent.ConcurrentLinkedQueue;
72import java.util.concurrent.Executors;
73import java.util.concurrent.ScheduledExecutorService;
74import java.util.concurrent.ScheduledFuture;
75import java.util.concurrent.TimeUnit;
76
77@SuppressWarnings("ALL")
sangho27462c62015-05-14 00:39:53 -070078@Service
sangho80f11cb2015-04-01 13:05:26 -070079@Component(immediate = true)
sangho27462c62015-05-14 00:39:53 -070080public class SegmentRoutingManager implements SegmentRoutingService {
sangho80f11cb2015-04-01 13:05:26 -070081
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070082 private static Logger log = LoggerFactory
83 .getLogger(SegmentRoutingManager.class);
sangho80f11cb2015-04-01 13:05:26 -070084
85 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 protected CoreService coreService;
87
88 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 protected TopologyService topologyService;
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected PacketService packetService;
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected IntentService intentService;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected HostService hostService;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected DeviceService deviceService;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700104 protected FlowObjectiveService flowObjectiveService;
sangho80f11cb2015-04-01 13:05:26 -0700105
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected LinkService linkService;
108
109 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
sangho80f11cb2015-04-01 13:05:26 -0700110 protected MastershipService mastershipService;
sangho27462c62015-05-14 00:39:53 -0700111
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700112 protected ArpHandler arpHandler = null;
113 protected IcmpHandler icmpHandler = null;
114 protected IpHandler ipHandler = null;
115 protected RoutingRulePopulator routingRulePopulator = null;
sangho80f11cb2015-04-01 13:05:26 -0700116 protected ApplicationId appId;
sangho9b169e32015-04-14 16:27:13 -0700117 protected DeviceConfiguration deviceConfiguration = null;
sangho80f11cb2015-04-01 13:05:26 -0700118
sangho27462c62015-05-14 00:39:53 -0700119
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700120 private DefaultRoutingHandler defaultRoutingHandler = null;
sangho27462c62015-05-14 00:39:53 -0700121 private TunnelHandler tunnelHandler = null;
122 private PolicyHandler policyHandler = null;
sangho80f11cb2015-04-01 13:05:26 -0700123 private InternalPacketProcessor processor = new InternalPacketProcessor();
124 private InternalEventHandler eventHandler = new InternalEventHandler();
125
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700126 private ScheduledExecutorService executorService = Executors
127 .newScheduledThreadPool(1);
sangho80f11cb2015-04-01 13:05:26 -0700128
129 private static ScheduledFuture<?> eventHandlerFuture = null;
130 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700131 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700132 // Per device next objective ID store with (device id + neighbor set) as key
133 private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
134 Integer> nsNextObjStore = null;
sangho4a5c42a2015-05-20 22:16:38 -0700135 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
136 private EventuallyConsistentMap<String, Policy> policyStore = null;
137
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700138 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
139 protected StorageService storageService;
sangho80f11cb2015-04-01 13:05:26 -0700140
Charles Chan72f556a2015-10-05 17:50:33 -0700141 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
142 protected NetworkConfigRegistry cfgService;
143
144 private final InternalConfigListener cfgListener = new InternalConfigListener();
145 private final ConfigFactory cfgFactory =
146 new ConfigFactory(SubjectFactories.DEVICE_SUBJECT_FACTORY,
147 SegmentRoutingConfig.class,
148 "segmentrouting") {
149 @Override
150 public SegmentRoutingConfig createConfig() {
151 return new SegmentRoutingConfig();
152 }
153 };
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700154
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700155 private Object threadSchedulerLock = new Object();
156 private static int numOfEventsQueued = 0;
157 private static int numOfEventsExecuted = 0;
sangho80f11cb2015-04-01 13:05:26 -0700158 private static int numOfHandlerExecution = 0;
159 private static int numOfHandlerScheduled = 0;
160
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700161 private KryoNamespace.Builder kryoBuilder = null;
162
sangho80f11cb2015-04-01 13:05:26 -0700163 @Activate
164 protected void activate() {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700165 appId = coreService
166 .registerApplication("org.onosproject.segmentrouting");
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700167
168 kryoBuilder = new KryoNamespace.Builder()
169 .register(NeighborSetNextObjectiveStoreKey.class,
sangho4a5c42a2015-05-20 22:16:38 -0700170 NeighborSet.class,
171 DeviceId.class,
172 URI.class,
173 WallClockTimestamp.class,
174 org.onosproject.cluster.NodeId.class,
175 HashSet.class,
176 Tunnel.class,
177 DefaultTunnel.class,
178 Policy.class,
179 TunnelPolicy.class,
180 Policy.Type.class
181 );
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700182
183 log.debug("Creating EC map nsnextobjectivestore");
184 EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
185 nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
186
187 nsNextObjStore = nsNextObjMapBuilder
188 .withName("nsnextobjectivestore")
189 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700190 .withTimestampProvider((k, v) -> new WallClockTimestamp())
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700191 .build();
192 log.trace("Current size {}", nsNextObjStore.size());
193
sangho4a5c42a2015-05-20 22:16:38 -0700194 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
195 storageService.eventuallyConsistentMapBuilder();
196
197 tunnelStore = tunnelMapBuilder
198 .withName("tunnelstore")
199 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700200 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho4a5c42a2015-05-20 22:16:38 -0700201 .build();
202
203 EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
204 storageService.eventuallyConsistentMapBuilder();
205
206 policyStore = policyMapBuilder
207 .withName("policystore")
208 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700209 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho4a5c42a2015-05-20 22:16:38 -0700210 .build();
211
Charles Chan72f556a2015-10-05 17:50:33 -0700212 cfgService.addListener(cfgListener);
213 cfgService.registerConfigFactory(cfgFactory);
214 deviceConfiguration = new DeviceConfiguration(cfgService);
215
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700216 arpHandler = new ArpHandler(this);
217 icmpHandler = new IcmpHandler(this);
218 ipHandler = new IpHandler(this);
219 routingRulePopulator = new RoutingRulePopulator(this);
220 defaultRoutingHandler = new DefaultRoutingHandler(this);
sanghobd812f82015-06-29 14:58:47 -0700221 tunnelHandler = new TunnelHandler(linkService, deviceConfiguration,
222 groupHandlerMap, tunnelStore);
223 policyHandler = new PolicyHandler(appId, deviceConfiguration,
224 flowObjectiveService, tunnelHandler, policyStore);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700225
Brian O'Connorfe78f252015-07-29 17:49:24 -0700226 packetService.addProcessor(processor, PacketProcessor.director(2));
sangho80f11cb2015-04-01 13:05:26 -0700227 linkService.addListener(new InternalLinkListener());
sangho80f11cb2015-04-01 13:05:26 -0700228 deviceService.addListener(new InternalDeviceListener());
229
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700230 for (Device device : deviceService.getDevices()) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700231 //Irrespective whether the local is a MASTER or not for this device,
232 //create group handler instance and push default TTP flow rules.
233 //Because in a multi-instance setup, instances can initiate
234 //groups for any devices. Also the default TTP rules are needed
235 //to be pushed before inserting any IP table entries for any device
236 DefaultGroupHandler groupHandler = DefaultGroupHandler
237 .createGroupHandler(device.id(), appId,
238 deviceConfiguration, linkService,
239 flowObjectiveService,
240 nsNextObjStore);
241 groupHandlerMap.put(device.id(), groupHandler);
242 defaultRoutingHandler.populateTtpRules(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700243 }
244
sanghofb7c7292015-04-13 15:15:58 -0700245 defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700246 log.info("Started");
sangho27462c62015-05-14 00:39:53 -0700247
sangho80f11cb2015-04-01 13:05:26 -0700248 }
249
250 @Deactivate
251 protected void deactivate() {
Charles Chan72f556a2015-10-05 17:50:33 -0700252 cfgService.removeListener(cfgListener);
253 cfgService.unregisterConfigFactory(cfgFactory);
254
sangho80f11cb2015-04-01 13:05:26 -0700255 packetService.removeProcessor(processor);
256 processor = null;
257 log.info("Stopped");
258 }
259
sangho27462c62015-05-14 00:39:53 -0700260
261 @Override
262 public List<Tunnel> getTunnels() {
263 return tunnelHandler.getTunnels();
264 }
265
266 @Override
sanghobd812f82015-06-29 14:58:47 -0700267 public TunnelHandler.Result createTunnel(Tunnel tunnel) {
268 return tunnelHandler.createTunnel(tunnel);
sangho27462c62015-05-14 00:39:53 -0700269 }
270
271 @Override
sanghobd812f82015-06-29 14:58:47 -0700272 public TunnelHandler.Result removeTunnel(Tunnel tunnel) {
sangho27462c62015-05-14 00:39:53 -0700273 for (Policy policy: policyHandler.getPolicies()) {
274 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
275 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
276 if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
277 log.warn("Cannot remove the tunnel used by a policy");
sanghobd812f82015-06-29 14:58:47 -0700278 return TunnelHandler.Result.TUNNEL_IN_USE;
sangho27462c62015-05-14 00:39:53 -0700279 }
280 }
281 }
sanghobd812f82015-06-29 14:58:47 -0700282 return tunnelHandler.removeTunnel(tunnel);
sangho27462c62015-05-14 00:39:53 -0700283 }
284
285 @Override
sanghobd812f82015-06-29 14:58:47 -0700286 public PolicyHandler.Result removePolicy(Policy policy) {
287 return policyHandler.removePolicy(policy);
sangho27462c62015-05-14 00:39:53 -0700288 }
289
290 @Override
sanghobd812f82015-06-29 14:58:47 -0700291 public PolicyHandler.Result createPolicy(Policy policy) {
292 return policyHandler.createPolicy(policy);
sangho27462c62015-05-14 00:39:53 -0700293 }
294
295 @Override
296 public List<Policy> getPolicies() {
297 return policyHandler.getPolicies();
298 }
299
sangho80f1f892015-05-19 11:57:42 -0700300 /**
301 * Returns the tunnel object with the tunnel ID.
302 *
303 * @param tunnelId Tunnel ID
304 * @return Tunnel reference
305 */
sangho27462c62015-05-14 00:39:53 -0700306 public Tunnel getTunnel(String tunnelId) {
307 return tunnelHandler.getTunnel(tunnelId);
308 }
309
sangho80f11cb2015-04-01 13:05:26 -0700310 /**
311 * Returns the GrouopKey object for the device and the NighborSet given.
312 *
313 * @param ns NeightborSet object for the GroupKey
314 * @return GroupKey object for the NeighborSet
315 */
316 public GroupKey getGroupKey(NeighborSet ns) {
317
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700318 for (DefaultGroupHandler groupHandler : groupHandlerMap.values()) {
sangho80f11cb2015-04-01 13:05:26 -0700319 return groupHandler.getGroupKey(ns);
320 }
321
322 return null;
323 }
324
sangho27462c62015-05-14 00:39:53 -0700325 /**
sangho80f1f892015-05-19 11:57:42 -0700326 * Returns the next objective ID for the NeighborSet given. If the nextObjectiveID does not exist,
327 * a new one is created and returned.
sangho27462c62015-05-14 00:39:53 -0700328 *
sangho80f1f892015-05-19 11:57:42 -0700329 * @param deviceId Device ID
330 * @param ns NegighborSet
331 * @return next objective ID
sangho27462c62015-05-14 00:39:53 -0700332 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700333 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
334
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700335 if (groupHandlerMap.get(deviceId) != null) {
336 log.trace("getNextObjectiveId query in device {}", deviceId);
337 return groupHandlerMap
338 .get(deviceId).getNextObjectiveId(ns);
339 } else {
340 log.warn("getNextObjectiveId query in device {} not found", deviceId);
341 return -1;
342 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700343 }
344
sangho80f11cb2015-04-01 13:05:26 -0700345 private class InternalPacketProcessor implements PacketProcessor {
346
347 @Override
348 public void process(PacketContext context) {
349
350 if (context.isHandled()) {
351 return;
352 }
353
354 InboundPacket pkt = context.inPacket();
355 Ethernet ethernet = pkt.parsed();
356
357 if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
358 arpHandler.processPacketIn(pkt);
359 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
360 IPv4 ipPacket = (IPv4) ethernet.getPayload();
361 ipHandler.addToPacketBuffer(ipPacket);
362 if (ipPacket.getProtocol() == IPv4.PROTOCOL_ICMP) {
363 icmpHandler.processPacketIn(pkt);
364 } else {
365 ipHandler.processPacketIn(pkt);
366 }
367 }
368 }
369 }
370
371 private class InternalLinkListener implements LinkListener {
372 @Override
373 public void event(LinkEvent event) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700374 if (event.type() == LinkEvent.Type.LINK_ADDED
375 || event.type() == LinkEvent.Type.LINK_REMOVED) {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700376 log.debug("Event {} received from Link Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700377 scheduleEventHandlerIfNotScheduled(event);
378 }
379 }
380 }
381
382 private class InternalDeviceListener implements DeviceListener {
383
384 @Override
385 public void event(DeviceEvent event) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700386 /*if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
sangho80f11cb2015-04-01 13:05:26 -0700387 log.debug("Local role {} is not MASTER for device {}",
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700388 mastershipService.getLocalRole(event.subject().id()),
389 event.subject().id());
sangho80f11cb2015-04-01 13:05:26 -0700390 return;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700391 }*/
sangho80f11cb2015-04-01 13:05:26 -0700392
393 switch (event.type()) {
394 case DEVICE_ADDED:
395 case PORT_REMOVED:
sanghofb7c7292015-04-13 15:15:58 -0700396 case DEVICE_UPDATED:
397 case DEVICE_AVAILABILITY_CHANGED:
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700398 log.debug("Event {} received from Device Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700399 scheduleEventHandlerIfNotScheduled(event);
400 break;
401 default:
402 }
403 }
404 }
405
sangho80f11cb2015-04-01 13:05:26 -0700406 private void scheduleEventHandlerIfNotScheduled(Event event) {
407
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700408 synchronized (threadSchedulerLock) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700409 eventQueue.add(event);
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700410 numOfEventsQueued++;
411
412 if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
413 //No pending scheduled event handling threads. So start a new one.
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700414 eventHandlerFuture = executorService
415 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
416 numOfHandlerScheduled++;
417 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700418 log.trace("numOfEventsQueued {}, numOfEventHanlderScheduled {}",
419 numOfEventsQueued,
420 numOfHandlerScheduled);
sangho80f11cb2015-04-01 13:05:26 -0700421 }
sangho80f11cb2015-04-01 13:05:26 -0700422 }
423
424 private class InternalEventHandler implements Runnable {
425
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700426 @Override
sangho80f11cb2015-04-01 13:05:26 -0700427 public void run() {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700428 try {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700429 while (true) {
430 Event event = null;
431 synchronized (threadSchedulerLock) {
432 if (!eventQueue.isEmpty()) {
433 event = eventQueue.poll();
434 numOfEventsExecuted++;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700435 } else {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700436 numOfHandlerExecution++;
437 log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
438 numOfHandlerExecution, numOfEventsExecuted);
439 break;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700440 }
sanghofb7c7292015-04-13 15:15:58 -0700441 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700442 if (event.type() == LinkEvent.Type.LINK_ADDED) {
443 processLinkAdded((Link) event.subject());
444 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
445 processLinkRemoved((Link) event.subject());
446 //} else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
447 // processGroupAdded((Group) event.subject());
448 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
449 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
450 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
451 if (deviceService.isAvailable(((Device) event.subject()).id())) {
452 processDeviceAdded((Device) event.subject());
453 }
454 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
455 processPortRemoved((Device) event.subject(),
456 ((DeviceEvent) event).port());
457 } else {
458 log.warn("Unhandled event type: {}", event.type());
459 }
sangho80f11cb2015-04-01 13:05:26 -0700460 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700461 } catch (Exception e) {
462 log.error("SegmentRouting event handler "
463 + "thread thrown an exception: {}", e);
sangho80f11cb2015-04-01 13:05:26 -0700464 }
sangho80f11cb2015-04-01 13:05:26 -0700465 }
466 }
467
sangho80f11cb2015-04-01 13:05:26 -0700468 private void processLinkAdded(Link link) {
469 log.debug("A new link {} was added", link.toString());
470
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700471 //Irrespective whether the local is a MASTER or not for this device,
472 //create group handler instance and push default TTP flow rules.
473 //Because in a multi-instance setup, instances can initiate
474 //groups for any devices. Also the default TTP rules are needed
475 //to be pushed before inserting any IP table entries for any device
476 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
477 .deviceId());
478 if (groupHandler != null) {
479 groupHandler.linkUp(link);
480 } else {
481 Device device = deviceService.getDevice(link.src().deviceId());
482 if (device != null) {
483 log.warn("processLinkAdded: Link Added "
484 + "Notification without Device Added "
485 + "event, still handling it");
486 processDeviceAdded(device);
487 groupHandler = groupHandlerMap.get(link.src()
488 .deviceId());
sangho80f11cb2015-04-01 13:05:26 -0700489 groupHandler.linkUp(link);
490 }
491 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700492
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700493 log.trace("Starting optimized route population process");
494 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
495 //log.trace("processLinkAdded: re-starting route population process");
496 //defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700497 }
498
499 private void processLinkRemoved(Link link) {
500 log.debug("A link {} was removed", link.toString());
sangho2165d222015-05-01 09:38:25 -0700501 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId());
502 if (groupHandler != null) {
503 groupHandler.portDown(link.src().port());
504 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700505 log.trace("Starting optimized route population process");
506 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
507 //log.trace("processLinkRemoved: re-starting route population process");
508 //defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700509 }
510
511 private void processDeviceAdded(Device device) {
512 log.debug("A new device with ID {} was added", device.id());
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700513 //Irrespective whether the local is a MASTER or not for this device,
514 //create group handler instance and push default TTP flow rules.
515 //Because in a multi-instance setup, instances can initiate
516 //groups for any devices. Also the default TTP rules are needed
517 //to be pushed before inserting any IP table entries for any device
518 DefaultGroupHandler dgh = DefaultGroupHandler.
519 createGroupHandler(device.id(),
520 appId,
521 deviceConfiguration,
522 linkService,
523 flowObjectiveService,
524 nsNextObjStore);
sangho80f11cb2015-04-01 13:05:26 -0700525 groupHandlerMap.put(device.id(), dgh);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700526 defaultRoutingHandler.populateTtpRules(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700527 }
528
529 private void processPortRemoved(Device device, Port port) {
530 log.debug("Port {} was removed", port.toString());
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700531 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700532 if (groupHandler != null) {
533 groupHandler.portDown(port.number());
534 }
535 }
sangho27462c62015-05-14 00:39:53 -0700536
Charles Chan72f556a2015-10-05 17:50:33 -0700537 private class InternalConfigListener implements NetworkConfigListener {
538 @Override
539 public void event(NetworkConfigEvent event) {
540 if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
541 event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
542 event.configClass().equals(SegmentRoutingConfig.class)) {
543 // TODO Support dynamic configuration in the future
544 return;
545 }
546 }
547 }
sangho80f11cb2015-04-01 13:05:26 -0700548}