blob: 9011160ca00b1795797a9ff3f7179527471eba6b [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
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700119 private DefaultRoutingHandler defaultRoutingHandler = null;
sangho27462c62015-05-14 00:39:53 -0700120 private TunnelHandler tunnelHandler = null;
121 private PolicyHandler policyHandler = null;
Charles Chan2b078ae2015-10-14 11:24:40 -0700122 private InternalPacketProcessor processor = null;
123 private InternalLinkListener linkListener = null;
124 private InternalDeviceListener deviceListener = null;
sangho80f11cb2015-04-01 13:05:26 -0700125 private InternalEventHandler eventHandler = new InternalEventHandler();
126
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700127 private ScheduledExecutorService executorService = Executors
128 .newScheduledThreadPool(1);
sangho80f11cb2015-04-01 13:05:26 -0700129
130 private static ScheduledFuture<?> eventHandlerFuture = null;
131 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700132 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700133 // Per device next objective ID store with (device id + neighbor set) as key
134 private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
135 Integer> nsNextObjStore = null;
sangho4a5c42a2015-05-20 22:16:38 -0700136 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
137 private EventuallyConsistentMap<String, Policy> policyStore = null;
138
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
140 protected StorageService storageService;
sangho80f11cb2015-04-01 13:05:26 -0700141
Charles Chan72f556a2015-10-05 17:50:33 -0700142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
143 protected NetworkConfigRegistry cfgService;
144
Charles Chane7c61022015-10-07 14:21:45 -0700145 private final InternalConfigListener cfgListener =
146 new InternalConfigListener(this);
147
Charles Chan72f556a2015-10-05 17:50:33 -0700148 private final ConfigFactory cfgFactory =
149 new ConfigFactory(SubjectFactories.DEVICE_SUBJECT_FACTORY,
150 SegmentRoutingConfig.class,
151 "segmentrouting") {
152 @Override
153 public SegmentRoutingConfig createConfig() {
154 return new SegmentRoutingConfig();
155 }
156 };
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700157
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700158 private Object threadSchedulerLock = new Object();
159 private static int numOfEventsQueued = 0;
160 private static int numOfEventsExecuted = 0;
sangho80f11cb2015-04-01 13:05:26 -0700161 private static int numOfHandlerExecution = 0;
162 private static int numOfHandlerScheduled = 0;
163
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700164 private KryoNamespace.Builder kryoBuilder = null;
165
sangho80f11cb2015-04-01 13:05:26 -0700166 @Activate
167 protected void activate() {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700168 appId = coreService
169 .registerApplication("org.onosproject.segmentrouting");
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700170
171 kryoBuilder = new KryoNamespace.Builder()
172 .register(NeighborSetNextObjectiveStoreKey.class,
sangho4a5c42a2015-05-20 22:16:38 -0700173 NeighborSet.class,
174 DeviceId.class,
175 URI.class,
176 WallClockTimestamp.class,
177 org.onosproject.cluster.NodeId.class,
178 HashSet.class,
179 Tunnel.class,
180 DefaultTunnel.class,
181 Policy.class,
182 TunnelPolicy.class,
183 Policy.Type.class
184 );
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700185
186 log.debug("Creating EC map nsnextobjectivestore");
187 EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
188 nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
189
190 nsNextObjStore = nsNextObjMapBuilder
191 .withName("nsnextobjectivestore")
192 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700193 .withTimestampProvider((k, v) -> new WallClockTimestamp())
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700194 .build();
195 log.trace("Current size {}", nsNextObjStore.size());
196
sangho4a5c42a2015-05-20 22:16:38 -0700197 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
198 storageService.eventuallyConsistentMapBuilder();
199
200 tunnelStore = tunnelMapBuilder
201 .withName("tunnelstore")
202 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700203 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho4a5c42a2015-05-20 22:16:38 -0700204 .build();
205
206 EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
207 storageService.eventuallyConsistentMapBuilder();
208
209 policyStore = policyMapBuilder
210 .withName("policystore")
211 .withSerializer(kryoBuilder)
Madan Jampani675ae202015-06-24 19:05:56 -0700212 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho4a5c42a2015-05-20 22:16:38 -0700213 .build();
214
Charles Chan72f556a2015-10-05 17:50:33 -0700215 cfgService.addListener(cfgListener);
216 cfgService.registerConfigFactory(cfgFactory);
Charles Chan72f556a2015-10-05 17:50:33 -0700217
Charles Chan2b078ae2015-10-14 11:24:40 -0700218 processor = new InternalPacketProcessor();
219 linkListener = new InternalLinkListener();
220 deviceListener = new InternalDeviceListener();
221
222 packetService.addProcessor(processor, PacketProcessor.director(2));
223 linkService.addListener(linkListener);
224 deviceService.addListener(deviceListener);
225
226 cfgListener.configureNetwork();
227
sangho80f11cb2015-04-01 13:05:26 -0700228 log.info("Started");
229 }
230
231 @Deactivate
232 protected void deactivate() {
Charles Chan72f556a2015-10-05 17:50:33 -0700233 cfgService.removeListener(cfgListener);
234 cfgService.unregisterConfigFactory(cfgFactory);
235
sangho80f11cb2015-04-01 13:05:26 -0700236 packetService.removeProcessor(processor);
Charles Chan2b078ae2015-10-14 11:24:40 -0700237 linkService.removeListener(linkListener);
238 deviceService.removeListener(deviceListener);
sangho80f11cb2015-04-01 13:05:26 -0700239 processor = null;
Charles Chan2b078ae2015-10-14 11:24:40 -0700240 linkListener = null;
241 deviceService = null;
242
243 groupHandlerMap.clear();
244
sangho80f11cb2015-04-01 13:05:26 -0700245 log.info("Stopped");
246 }
247
sangho27462c62015-05-14 00:39:53 -0700248
249 @Override
250 public List<Tunnel> getTunnels() {
251 return tunnelHandler.getTunnels();
252 }
253
254 @Override
sanghobd812f82015-06-29 14:58:47 -0700255 public TunnelHandler.Result createTunnel(Tunnel tunnel) {
256 return tunnelHandler.createTunnel(tunnel);
sangho27462c62015-05-14 00:39:53 -0700257 }
258
259 @Override
sanghobd812f82015-06-29 14:58:47 -0700260 public TunnelHandler.Result removeTunnel(Tunnel tunnel) {
sangho27462c62015-05-14 00:39:53 -0700261 for (Policy policy: policyHandler.getPolicies()) {
262 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
263 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
264 if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
265 log.warn("Cannot remove the tunnel used by a policy");
sanghobd812f82015-06-29 14:58:47 -0700266 return TunnelHandler.Result.TUNNEL_IN_USE;
sangho27462c62015-05-14 00:39:53 -0700267 }
268 }
269 }
sanghobd812f82015-06-29 14:58:47 -0700270 return tunnelHandler.removeTunnel(tunnel);
sangho27462c62015-05-14 00:39:53 -0700271 }
272
273 @Override
sanghobd812f82015-06-29 14:58:47 -0700274 public PolicyHandler.Result removePolicy(Policy policy) {
275 return policyHandler.removePolicy(policy);
sangho27462c62015-05-14 00:39:53 -0700276 }
277
278 @Override
sanghobd812f82015-06-29 14:58:47 -0700279 public PolicyHandler.Result createPolicy(Policy policy) {
280 return policyHandler.createPolicy(policy);
sangho27462c62015-05-14 00:39:53 -0700281 }
282
283 @Override
284 public List<Policy> getPolicies() {
285 return policyHandler.getPolicies();
286 }
287
sangho80f1f892015-05-19 11:57:42 -0700288 /**
289 * Returns the tunnel object with the tunnel ID.
290 *
291 * @param tunnelId Tunnel ID
292 * @return Tunnel reference
293 */
sangho27462c62015-05-14 00:39:53 -0700294 public Tunnel getTunnel(String tunnelId) {
295 return tunnelHandler.getTunnel(tunnelId);
296 }
297
sangho80f11cb2015-04-01 13:05:26 -0700298 /**
299 * Returns the GrouopKey object for the device and the NighborSet given.
300 *
301 * @param ns NeightborSet object for the GroupKey
302 * @return GroupKey object for the NeighborSet
303 */
304 public GroupKey getGroupKey(NeighborSet ns) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700305 for (DefaultGroupHandler groupHandler : groupHandlerMap.values()) {
sangho80f11cb2015-04-01 13:05:26 -0700306 return groupHandler.getGroupKey(ns);
307 }
308
309 return null;
310 }
311
sangho27462c62015-05-14 00:39:53 -0700312 /**
sangho80f1f892015-05-19 11:57:42 -0700313 * Returns the next objective ID for the NeighborSet given. If the nextObjectiveID does not exist,
314 * a new one is created and returned.
sangho27462c62015-05-14 00:39:53 -0700315 *
sangho80f1f892015-05-19 11:57:42 -0700316 * @param deviceId Device ID
317 * @param ns NegighborSet
318 * @return next objective ID
sangho27462c62015-05-14 00:39:53 -0700319 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700320 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700321 if (groupHandlerMap.get(deviceId) != null) {
322 log.trace("getNextObjectiveId query in device {}", deviceId);
323 return groupHandlerMap
324 .get(deviceId).getNextObjectiveId(ns);
325 } else {
326 log.warn("getNextObjectiveId query in device {} not found", deviceId);
327 return -1;
328 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700329 }
330
sangho80f11cb2015-04-01 13:05:26 -0700331 private class InternalPacketProcessor implements PacketProcessor {
sangho80f11cb2015-04-01 13:05:26 -0700332 @Override
333 public void process(PacketContext context) {
334
335 if (context.isHandled()) {
336 return;
337 }
338
339 InboundPacket pkt = context.inPacket();
340 Ethernet ethernet = pkt.parsed();
341
342 if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
343 arpHandler.processPacketIn(pkt);
344 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
345 IPv4 ipPacket = (IPv4) ethernet.getPayload();
346 ipHandler.addToPacketBuffer(ipPacket);
347 if (ipPacket.getProtocol() == IPv4.PROTOCOL_ICMP) {
348 icmpHandler.processPacketIn(pkt);
349 } else {
350 ipHandler.processPacketIn(pkt);
351 }
352 }
353 }
354 }
355
356 private class InternalLinkListener implements LinkListener {
357 @Override
358 public void event(LinkEvent event) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700359 if (event.type() == LinkEvent.Type.LINK_ADDED
360 || event.type() == LinkEvent.Type.LINK_REMOVED) {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700361 log.debug("Event {} received from Link Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700362 scheduleEventHandlerIfNotScheduled(event);
363 }
364 }
365 }
366
367 private class InternalDeviceListener implements DeviceListener {
sangho80f11cb2015-04-01 13:05:26 -0700368 @Override
369 public void event(DeviceEvent event) {
sangho80f11cb2015-04-01 13:05:26 -0700370 switch (event.type()) {
371 case DEVICE_ADDED:
372 case PORT_REMOVED:
sanghofb7c7292015-04-13 15:15:58 -0700373 case DEVICE_UPDATED:
374 case DEVICE_AVAILABILITY_CHANGED:
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700375 log.debug("Event {} received from Device Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700376 scheduleEventHandlerIfNotScheduled(event);
377 break;
378 default:
379 }
380 }
381 }
382
sangho80f11cb2015-04-01 13:05:26 -0700383 private void scheduleEventHandlerIfNotScheduled(Event event) {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700384 synchronized (threadSchedulerLock) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700385 eventQueue.add(event);
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700386 numOfEventsQueued++;
387
388 if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
389 //No pending scheduled event handling threads. So start a new one.
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700390 eventHandlerFuture = executorService
391 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
392 numOfHandlerScheduled++;
393 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700394 log.trace("numOfEventsQueued {}, numOfEventHanlderScheduled {}",
395 numOfEventsQueued,
396 numOfHandlerScheduled);
sangho80f11cb2015-04-01 13:05:26 -0700397 }
sangho80f11cb2015-04-01 13:05:26 -0700398 }
399
400 private class InternalEventHandler implements Runnable {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700401 @Override
sangho80f11cb2015-04-01 13:05:26 -0700402 public void run() {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700403 try {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700404 while (true) {
405 Event event = null;
406 synchronized (threadSchedulerLock) {
407 if (!eventQueue.isEmpty()) {
408 event = eventQueue.poll();
409 numOfEventsExecuted++;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700410 } else {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700411 numOfHandlerExecution++;
412 log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
413 numOfHandlerExecution, numOfEventsExecuted);
414 break;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700415 }
sanghofb7c7292015-04-13 15:15:58 -0700416 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700417 if (event.type() == LinkEvent.Type.LINK_ADDED) {
418 processLinkAdded((Link) event.subject());
419 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
420 processLinkRemoved((Link) event.subject());
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700421 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
422 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
423 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
424 if (deviceService.isAvailable(((Device) event.subject()).id())) {
425 processDeviceAdded((Device) event.subject());
426 }
427 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
428 processPortRemoved((Device) event.subject(),
429 ((DeviceEvent) event).port());
430 } else {
431 log.warn("Unhandled event type: {}", event.type());
432 }
sangho80f11cb2015-04-01 13:05:26 -0700433 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700434 } catch (Exception e) {
435 log.error("SegmentRouting event handler "
436 + "thread thrown an exception: {}", e);
sangho80f11cb2015-04-01 13:05:26 -0700437 }
sangho80f11cb2015-04-01 13:05:26 -0700438 }
439 }
440
sangho80f11cb2015-04-01 13:05:26 -0700441 private void processLinkAdded(Link link) {
442 log.debug("A new link {} was added", link.toString());
443
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700444 //Irrespective whether the local is a MASTER or not for this device,
445 //create group handler instance and push default TTP flow rules.
446 //Because in a multi-instance setup, instances can initiate
447 //groups for any devices. Also the default TTP rules are needed
448 //to be pushed before inserting any IP table entries for any device
449 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
450 .deviceId());
451 if (groupHandler != null) {
452 groupHandler.linkUp(link);
453 } else {
454 Device device = deviceService.getDevice(link.src().deviceId());
455 if (device != null) {
456 log.warn("processLinkAdded: Link Added "
457 + "Notification without Device Added "
458 + "event, still handling it");
459 processDeviceAdded(device);
460 groupHandler = groupHandlerMap.get(link.src()
461 .deviceId());
sangho80f11cb2015-04-01 13:05:26 -0700462 groupHandler.linkUp(link);
463 }
464 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700465
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700466 log.trace("Starting optimized route population process");
467 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
468 //log.trace("processLinkAdded: re-starting route population process");
469 //defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700470 }
471
472 private void processLinkRemoved(Link link) {
473 log.debug("A link {} was removed", link.toString());
sangho2165d222015-05-01 09:38:25 -0700474 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId());
475 if (groupHandler != null) {
476 groupHandler.portDown(link.src().port());
477 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700478 log.trace("Starting optimized route population process");
479 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
480 //log.trace("processLinkRemoved: re-starting route population process");
481 //defaultRoutingHandler.startPopulationProcess();
sangho80f11cb2015-04-01 13:05:26 -0700482 }
483
484 private void processDeviceAdded(Device device) {
485 log.debug("A new device with ID {} was added", device.id());
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700486 //Irrespective whether the local is a MASTER or not for this device,
487 //create group handler instance and push default TTP flow rules.
488 //Because in a multi-instance setup, instances can initiate
489 //groups for any devices. Also the default TTP rules are needed
490 //to be pushed before inserting any IP table entries for any device
491 DefaultGroupHandler dgh = DefaultGroupHandler.
492 createGroupHandler(device.id(),
493 appId,
494 deviceConfiguration,
495 linkService,
496 flowObjectiveService,
497 nsNextObjStore);
sangho80f11cb2015-04-01 13:05:26 -0700498 groupHandlerMap.put(device.id(), dgh);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700499 defaultRoutingHandler.populateTtpRules(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700500 }
501
502 private void processPortRemoved(Device device, Port port) {
503 log.debug("Port {} was removed", port.toString());
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700504 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700505 if (groupHandler != null) {
506 groupHandler.portDown(port.number());
507 }
508 }
sangho27462c62015-05-14 00:39:53 -0700509
Charles Chan72f556a2015-10-05 17:50:33 -0700510 private class InternalConfigListener implements NetworkConfigListener {
Charles Chane7c61022015-10-07 14:21:45 -0700511 SegmentRoutingManager segmentRoutingManager;
512
513 public InternalConfigListener(SegmentRoutingManager srMgr) {
514 this.segmentRoutingManager = srMgr;
515 }
516
517 public void configureNetwork() {
518 deviceConfiguration = new DeviceConfiguration(segmentRoutingManager.cfgService);
519
520 arpHandler = new ArpHandler(segmentRoutingManager);
521 icmpHandler = new IcmpHandler(segmentRoutingManager);
522 ipHandler = new IpHandler(segmentRoutingManager);
523 routingRulePopulator = new RoutingRulePopulator(segmentRoutingManager);
524 defaultRoutingHandler = new DefaultRoutingHandler(segmentRoutingManager);
525
526 tunnelHandler = new TunnelHandler(linkService, deviceConfiguration,
527 groupHandlerMap, tunnelStore);
528 policyHandler = new PolicyHandler(appId, deviceConfiguration,
529 flowObjectiveService,
530 tunnelHandler, policyStore);
531
Charles Chane7c61022015-10-07 14:21:45 -0700532 for (Device device : deviceService.getDevices()) {
533 //Irrespective whether the local is a MASTER or not for this device,
534 //create group handler instance and push default TTP flow rules.
535 //Because in a multi-instance setup, instances can initiate
536 //groups for any devices. Also the default TTP rules are needed
537 //to be pushed before inserting any IP table entries for any device
538 DefaultGroupHandler groupHandler = DefaultGroupHandler
539 .createGroupHandler(device.id(), appId,
540 deviceConfiguration, linkService,
541 flowObjectiveService,
542 nsNextObjStore);
543 groupHandlerMap.put(device.id(), groupHandler);
544 defaultRoutingHandler.populateTtpRules(device.id());
545 }
546
547 defaultRoutingHandler.startPopulationProcess();
548 }
549
Charles Chan72f556a2015-10-05 17:50:33 -0700550 @Override
551 public void event(NetworkConfigEvent event) {
Charles Chan2b078ae2015-10-14 11:24:40 -0700552 if (event.configClass().equals(SegmentRoutingConfig.class)) {
553 if (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED) {
554 log.info("Network configuration added.");
555 configureNetwork();
556 }
557 if (event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) {
558 log.info("Network configuration updated.");
559 // TODO support dynamic configuration
560 }
Charles Chan72f556a2015-10-05 17:50:33 -0700561 }
562 }
563 }
sangho80f11cb2015-04-01 13:05:26 -0700564}