blob: 0c30cef01b14c6e39697c6767959523e2242d010 [file] [log] [blame]
sangho80f11cb2015-04-01 13:05:26 -07001/*
Brian O'Connor43b53542016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
sangho80f11cb2015-04-01 13:05:26 -07003 *
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
Charles Chand7844e52016-10-20 17:02:44 -070018import com.google.common.collect.Maps;
sangho80f11cb2015-04-01 13:05:26 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
sangho27462c62015-05-14 00:39:53 -070024import org.apache.felix.scr.annotations.Service;
sangho80f11cb2015-04-01 13:05:26 -070025import org.onlab.packet.Ethernet;
Pier Ventreb6b81d52016-12-02 08:16:05 -080026import org.onlab.packet.ICMP6;
Charles Chan77277672015-10-20 16:24:19 -070027import org.onlab.packet.IPv4;
Pier Ventreb6a7f342016-11-26 21:05:22 -080028import org.onlab.packet.IPv6;
Charles Chan77277672015-10-20 16:24:19 -070029import org.onlab.packet.IpPrefix;
Jonathan Hart54541d12016-04-12 15:39:44 -070030import org.onlab.packet.VlanId;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070031import org.onlab.util.KryoNamespace;
Saurav Dasc3604f12016-03-23 11:22:49 -070032import org.onosproject.cfg.ComponentConfigService;
sangho80f11cb2015-04-01 13:05:26 -070033import org.onosproject.core.ApplicationId;
34import org.onosproject.core.CoreService;
35import org.onosproject.event.Event;
Pier Luigiad0a67f2017-02-03 13:34:21 -080036import org.onosproject.incubator.net.config.basics.ConfigException;
Pier Luigi37a35432017-02-01 13:50:04 -080037import org.onosproject.incubator.net.config.basics.InterfaceConfig;
Charles Chanc91c8782016-03-30 17:54:24 -070038import org.onosproject.incubator.net.config.basics.McastConfig;
Pier Luigiad0a67f2017-02-03 13:34:21 -080039import org.onosproject.incubator.net.intf.Interface;
Charles Chan46fdfaf2016-11-09 20:51:44 -080040import org.onosproject.incubator.net.intf.InterfaceService;
Charles Chandebfea32016-10-24 14:52:01 -070041import org.onosproject.incubator.net.routing.RouteEvent;
42import org.onosproject.incubator.net.routing.RouteListener;
43import org.onosproject.incubator.net.routing.RouteService;
Pier Ventreb6b81d52016-12-02 08:16:05 -080044import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
Jonathan Hart54541d12016-04-12 15:39:44 -070045import org.onosproject.mastership.MastershipService;
Pier Ventreb6a7f342016-11-26 21:05:22 -080046import org.onosproject.net.ConnectPoint;
Jonathan Hart54541d12016-04-12 15:39:44 -070047import org.onosproject.net.Device;
48import org.onosproject.net.DeviceId;
49import org.onosproject.net.Link;
50import org.onosproject.net.Port;
Charles Chanf4586112015-11-09 16:37:23 -080051import org.onosproject.net.PortNumber;
Charles Chan72f556a2015-10-05 17:50:33 -070052import org.onosproject.net.config.ConfigFactory;
53import org.onosproject.net.config.NetworkConfigEvent;
Charles Chan72f556a2015-10-05 17:50:33 -070054import org.onosproject.net.config.NetworkConfigListener;
Jonathan Hart54541d12016-04-12 15:39:44 -070055import org.onosproject.net.config.NetworkConfigRegistry;
Charles Chan72f556a2015-10-05 17:50:33 -070056import org.onosproject.net.config.basics.SubjectFactories;
Jonathan Hart54541d12016-04-12 15:39:44 -070057import org.onosproject.net.device.DeviceEvent;
58import org.onosproject.net.device.DeviceListener;
59import org.onosproject.net.device.DeviceService;
Charles Chanf4586112015-11-09 16:37:23 -080060import org.onosproject.net.flow.TrafficSelector;
61import org.onosproject.net.flow.TrafficTreatment;
Jonathan Hart54541d12016-04-12 15:39:44 -070062import org.onosproject.net.flowobjective.FlowObjectiveService;
Charles Chanf4586112015-11-09 16:37:23 -080063import org.onosproject.net.host.HostEvent;
64import org.onosproject.net.host.HostListener;
Pier Ventreb6a7f342016-11-26 21:05:22 -080065import org.onosproject.net.host.HostService;
66import org.onosproject.net.link.LinkEvent;
67import org.onosproject.net.link.LinkListener;
68import org.onosproject.net.link.LinkService;
Charles Chanc91c8782016-03-30 17:54:24 -070069import org.onosproject.net.mcast.McastEvent;
70import org.onosproject.net.mcast.McastListener;
71import org.onosproject.net.mcast.MulticastRouteService;
Pier Ventreb6a7f342016-11-26 21:05:22 -080072import org.onosproject.net.packet.InboundPacket;
73import org.onosproject.net.packet.PacketContext;
74import org.onosproject.net.packet.PacketProcessor;
75import org.onosproject.net.packet.PacketService;
Pier Ventref3cf5b92016-11-09 14:17:26 -080076import org.onosproject.net.topology.PathService;
Charles Chanc91c8782016-03-30 17:54:24 -070077import org.onosproject.net.topology.TopologyService;
Pier Luigi37a35432017-02-01 13:50:04 -080078import org.onosproject.routing.config.RouterConfig;
Charles Chanc91c8782016-03-30 17:54:24 -070079import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
80import org.onosproject.segmentrouting.config.DeviceConfiguration;
Pier Ventre6b19e482016-11-07 16:21:04 -080081import org.onosproject.segmentrouting.config.PwaasConfig;
Pier Ventreb6a7f342016-11-26 21:05:22 -080082import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
Pier Ventre6b19e482016-11-07 16:21:04 -080083import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
Charles Chan82f19972016-05-17 13:13:55 -070084import org.onosproject.segmentrouting.config.XConnectConfig;
Charles Chanc91c8782016-03-30 17:54:24 -070085import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
86import org.onosproject.segmentrouting.grouphandler.NeighborSet;
Charles Chan1eaf4802016-04-18 13:44:03 -070087import org.onosproject.segmentrouting.storekey.NeighborSetNextObjectiveStoreKey;
88import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
Charles Chan1eaf4802016-04-18 13:44:03 -070089import org.onosproject.segmentrouting.storekey.SubnetAssignedVidStoreKey;
Charles Chan10b0fb72017-02-02 16:20:42 -080090import org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey;
Charles Chan82f19972016-05-17 13:13:55 -070091import org.onosproject.segmentrouting.storekey.XConnectStoreKey;
Pier Ventre6b19e482016-11-07 16:21:04 -080092import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
Jonathan Hart54541d12016-04-12 15:39:44 -070093import org.onosproject.store.serializers.KryoNamespaces;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070094import org.onosproject.store.service.EventuallyConsistentMap;
95import org.onosproject.store.service.EventuallyConsistentMapBuilder;
96import org.onosproject.store.service.StorageService;
97import org.onosproject.store.service.WallClockTimestamp;
Charles Chan41f5ec02016-06-13 18:54:31 -070098import org.opencord.cordconfig.CordConfigEvent;
99import org.opencord.cordconfig.CordConfigListener;
100import org.opencord.cordconfig.CordConfigService;
sangho80f11cb2015-04-01 13:05:26 -0700101import org.slf4j.Logger;
102import org.slf4j.LoggerFactory;
103
sangho27462c62015-05-14 00:39:53 -0700104import java.util.List;
sangho80f11cb2015-04-01 13:05:26 -0700105import java.util.Map;
Saurav Das7c305372015-10-28 12:39:42 -0700106import java.util.Set;
sangho80f11cb2015-04-01 13:05:26 -0700107import java.util.concurrent.ConcurrentHashMap;
108import java.util.concurrent.ConcurrentLinkedQueue;
109import java.util.concurrent.Executors;
110import java.util.concurrent.ScheduledExecutorService;
111import java.util.concurrent.ScheduledFuture;
112import java.util.concurrent.TimeUnit;
113
Charles Chand6d25332016-02-26 22:19:52 -0800114import static com.google.common.base.Preconditions.checkState;
Pier Ventreadb4ae62016-11-23 09:57:42 -0800115import static org.onlab.packet.Ethernet.TYPE_ARP;
Yuta HIGUCHIebee2f12016-07-21 16:54:33 -0700116import static org.onlab.util.Tools.groupedThreads;
Charles Chand6d25332016-02-26 22:19:52 -0800117
Charles Chanb7f75ac2016-01-11 18:28:54 -0800118/**
119 * Segment routing manager.
120 */
Jonathan Hart54541d12016-04-12 15:39:44 -0700121@Service
122@Component(immediate = true)
sangho27462c62015-05-14 00:39:53 -0700123public class SegmentRoutingManager implements SegmentRoutingService {
sangho80f11cb2015-04-01 13:05:26 -0700124
Charles Chan46fdfaf2016-11-09 20:51:44 -0800125 private static Logger log = LoggerFactory.getLogger(SegmentRoutingManager.class);
sangho80f11cb2015-04-01 13:05:26 -0700126
127 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chandebfea32016-10-24 14:52:01 -0700128 private ComponentConfigService compCfgService;
sangho80f11cb2015-04-01 13:05:26 -0700129
130 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventreb6a7f342016-11-26 21:05:22 -0800131 private NeighbourResolutionService neighbourResolutionService;
132
133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventref3cf5b92016-11-09 14:17:26 -0800134 public PathService pathService;
135
136 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chandebfea32016-10-24 14:52:01 -0700137 CoreService coreService;
sangho80f11cb2015-04-01 13:05:26 -0700138
139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chandebfea32016-10-24 14:52:01 -0700140 PacketService packetService;
sangho80f11cb2015-04-01 13:05:26 -0700141
142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chandebfea32016-10-24 14:52:01 -0700143 HostService hostService;
sangho80f11cb2015-04-01 13:05:26 -0700144
145 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chandebfea32016-10-24 14:52:01 -0700146 DeviceService deviceService;
sangho80f11cb2015-04-01 13:05:26 -0700147
148 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventref3cf5b92016-11-09 14:17:26 -0800149 public FlowObjectiveService flowObjectiveService;
sangho80f11cb2015-04-01 13:05:26 -0700150
151 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chandebfea32016-10-24 14:52:01 -0700152 LinkService linkService;
sangho27462c62015-05-14 00:39:53 -0700153
Charles Chan82ab1932016-01-30 23:22:37 -0800154 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventref3cf5b92016-11-09 14:17:26 -0800155 public MastershipService mastershipService;
Charles Chandebfea32016-10-24 14:52:01 -0700156
157 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventref3cf5b92016-11-09 14:17:26 -0800158 public StorageService storageService;
Charles Chandebfea32016-10-24 14:52:01 -0700159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
161 MulticastRouteService multicastRouteService;
162
163 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
164 TopologyService topologyService;
165
166 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
167 CordConfigService cordConfigService;
168
169 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
170 RouteService routeService;
Charles Chan82ab1932016-01-30 23:22:37 -0800171
172 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan46fdfaf2016-11-09 20:51:44 -0800173 public NetworkConfigRegistry cfgService;
Charles Chan82ab1932016-01-30 23:22:37 -0800174
Saurav Dasc3604f12016-03-23 11:22:49 -0700175 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan46fdfaf2016-11-09 20:51:44 -0800176 public InterfaceService interfaceService;
177
Charles Chandebfea32016-10-24 14:52:01 -0700178 ArpHandler arpHandler = null;
179 IcmpHandler icmpHandler = null;
180 IpHandler ipHandler = null;
181 RoutingRulePopulator routingRulePopulator = null;
Charles Chan46fdfaf2016-11-09 20:51:44 -0800182 public ApplicationId appId;
Pier Ventref3cf5b92016-11-09 14:17:26 -0800183 public DeviceConfiguration deviceConfiguration = null;
sangho80f11cb2015-04-01 13:05:26 -0700184
Charles Chandebfea32016-10-24 14:52:01 -0700185 DefaultRoutingHandler defaultRoutingHandler = null;
sangho27462c62015-05-14 00:39:53 -0700186 private TunnelHandler tunnelHandler = null;
187 private PolicyHandler policyHandler = null;
Charles Chan2b078ae2015-10-14 11:24:40 -0700188 private InternalPacketProcessor processor = null;
189 private InternalLinkListener linkListener = null;
190 private InternalDeviceListener deviceListener = null;
Charles Chan82f19972016-05-17 13:13:55 -0700191 private AppConfigHandler appCfgHandler = null;
Charles Chandebfea32016-10-24 14:52:01 -0700192 XConnectHandler xConnectHandler = null;
Charles Chan1eaf4802016-04-18 13:44:03 -0700193 private McastHandler mcastHandler = null;
Charles Chandebfea32016-10-24 14:52:01 -0700194 HostHandler hostHandler = null;
Charles Chan41f5ec02016-06-13 18:54:31 -0700195 private CordConfigHandler cordConfigHandler = null;
Pier Ventreb6a7f342016-11-26 21:05:22 -0800196 private RouteHandler routeHandler = null;
Pier Ventreb6b81d52016-12-02 08:16:05 -0800197 private SegmentRoutingNeighbourDispatcher neighbourHandler = null;
Pier Ventre6b19e482016-11-07 16:21:04 -0800198 private L2TunnelHandler l2TunnelHandler = null;
sangho80f11cb2015-04-01 13:05:26 -0700199 private InternalEventHandler eventHandler = new InternalEventHandler();
Charles Chan82ab1932016-01-30 23:22:37 -0800200 private final InternalHostListener hostListener = new InternalHostListener();
Charles Chanc91c8782016-03-30 17:54:24 -0700201 private final InternalConfigListener cfgListener = new InternalConfigListener(this);
202 private final InternalMcastListener mcastListener = new InternalMcastListener();
Charles Chan41f5ec02016-06-13 18:54:31 -0700203 private final InternalCordConfigListener cordConfigListener = new InternalCordConfigListener();
Charles Chandebfea32016-10-24 14:52:01 -0700204 private final InternalRouteEventListener routeListener = new InternalRouteEventListener();
sangho80f11cb2015-04-01 13:05:26 -0700205
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700206 private ScheduledExecutorService executorService = Executors
Yuta HIGUCHIebee2f12016-07-21 16:54:33 -0700207 .newScheduledThreadPool(1, groupedThreads("SegmentRoutingManager", "event-%d", log));
sangho80f11cb2015-04-01 13:05:26 -0700208
Saurav Das2d94d312015-11-24 23:21:05 -0800209 @SuppressWarnings("unused")
sangho80f11cb2015-04-01 13:05:26 -0700210 private static ScheduledFuture<?> eventHandlerFuture = null;
Saurav Das2d94d312015-11-24 23:21:05 -0800211 @SuppressWarnings("rawtypes")
Yuta HIGUCHIebee2f12016-07-21 16:54:33 -0700212 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<>();
Charles Chanf4586112015-11-09 16:37:23 -0800213 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap =
Charles Chanb7f75ac2016-01-11 18:28:54 -0800214 new ConcurrentHashMap<>();
215 /**
216 * Per device next objective ID store with (device id + neighbor set) as key.
217 */
218 public EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer>
Charles Chanf4586112015-11-09 16:37:23 -0800219 nsNextObjStore = null;
Charles Chanb7f75ac2016-01-11 18:28:54 -0800220 /**
221 * Per device next objective ID store with (device id + subnet) as key.
222 */
Charles Chan10b0fb72017-02-02 16:20:42 -0800223 public EventuallyConsistentMap<VlanNextObjectiveStoreKey, Integer>
224 vlanNextObjStore = null;
Charles Chanb7f75ac2016-01-11 18:28:54 -0800225 /**
226 * Per device next objective ID store with (device id + port) as key.
227 */
228 public EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer>
Saurav Das2d94d312015-11-24 23:21:05 -0800229 portNextObjStore = null;
Charles Chan10b0fb72017-02-02 16:20:42 -0800230
Saurav Das2d94d312015-11-24 23:21:05 -0800231 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
232 private EventuallyConsistentMap<String, Policy> policyStore = null;
sangho4a5c42a2015-05-20 22:16:38 -0700233
Charles Chanc91c8782016-03-30 17:54:24 -0700234 private final ConfigFactory<DeviceId, SegmentRoutingDeviceConfig> deviceConfigFactory =
Charles Chan82f19972016-05-17 13:13:55 -0700235 new ConfigFactory<DeviceId, SegmentRoutingDeviceConfig>(
236 SubjectFactories.DEVICE_SUBJECT_FACTORY,
Charles Chanc91c8782016-03-30 17:54:24 -0700237 SegmentRoutingDeviceConfig.class, "segmentrouting") {
Charles Chan72f556a2015-10-05 17:50:33 -0700238 @Override
Charles Chan82ab1932016-01-30 23:22:37 -0800239 public SegmentRoutingDeviceConfig createConfig() {
240 return new SegmentRoutingDeviceConfig();
Charles Chan72f556a2015-10-05 17:50:33 -0700241 }
242 };
Pier Ventre6b19e482016-11-07 16:21:04 -0800243
Charles Chanc91c8782016-03-30 17:54:24 -0700244 private final ConfigFactory<ApplicationId, SegmentRoutingAppConfig> appConfigFactory =
Charles Chan82f19972016-05-17 13:13:55 -0700245 new ConfigFactory<ApplicationId, SegmentRoutingAppConfig>(
246 SubjectFactories.APP_SUBJECT_FACTORY,
Charles Chanc91c8782016-03-30 17:54:24 -0700247 SegmentRoutingAppConfig.class, "segmentrouting") {
Charles Chan82ab1932016-01-30 23:22:37 -0800248 @Override
249 public SegmentRoutingAppConfig createConfig() {
250 return new SegmentRoutingAppConfig();
251 }
252 };
Pier Ventre6b19e482016-11-07 16:21:04 -0800253
Charles Chan82f19972016-05-17 13:13:55 -0700254 private final ConfigFactory<ApplicationId, XConnectConfig> xConnectConfigFactory =
255 new ConfigFactory<ApplicationId, XConnectConfig>(
256 SubjectFactories.APP_SUBJECT_FACTORY,
257 XConnectConfig.class, "xconnect") {
258 @Override
259 public XConnectConfig createConfig() {
260 return new XConnectConfig();
261 }
262 };
Pier Ventre6b19e482016-11-07 16:21:04 -0800263
Charles Chanc91c8782016-03-30 17:54:24 -0700264 private ConfigFactory<ApplicationId, McastConfig> mcastConfigFactory =
Charles Chan82f19972016-05-17 13:13:55 -0700265 new ConfigFactory<ApplicationId, McastConfig>(
266 SubjectFactories.APP_SUBJECT_FACTORY,
Charles Chanc91c8782016-03-30 17:54:24 -0700267 McastConfig.class, "multicast") {
268 @Override
269 public McastConfig createConfig() {
270 return new McastConfig();
271 }
272 };
273
Pier Ventre6b19e482016-11-07 16:21:04 -0800274 private final ConfigFactory<ApplicationId, PwaasConfig> pwaasConfigFactory =
275 new ConfigFactory<ApplicationId, PwaasConfig>(
276 SubjectFactories.APP_SUBJECT_FACTORY,
277 PwaasConfig.class, "pwaas") {
278 @Override
279 public PwaasConfig createConfig() {
280 return new PwaasConfig();
281 }
282 };
283
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700284 private Object threadSchedulerLock = new Object();
285 private static int numOfEventsQueued = 0;
286 private static int numOfEventsExecuted = 0;
sangho80f11cb2015-04-01 13:05:26 -0700287 private static int numOfHandlerExecution = 0;
288 private static int numOfHandlerScheduled = 0;
289
Charles Chan1963f4f2016-02-18 14:22:42 -0800290 /**
291 * Segment Routing App ID.
292 */
Charles Chan46fdfaf2016-11-09 20:51:44 -0800293 public static final String APP_NAME = "org.onosproject.segmentrouting";
Charles Chan10b0fb72017-02-02 16:20:42 -0800294
Charles Chanb7f75ac2016-01-11 18:28:54 -0800295 /**
296 * The default VLAN ID assigned to the interfaces without subnet config.
297 */
Charles Chan10b0fb72017-02-02 16:20:42 -0800298 public static final VlanId INTERNAL_VLAN = VlanId.vlanId((short) 4094);
Saurav Das7c305372015-10-28 12:39:42 -0700299
sangho80f11cb2015-04-01 13:05:26 -0700300 @Activate
301 protected void activate() {
Charles Chan46fdfaf2016-11-09 20:51:44 -0800302 appId = coreService.registerApplication(APP_NAME);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700303
304 log.debug("Creating EC map nsnextobjectivestore");
305 EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
306 nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700307 nsNextObjStore = nsNextObjMapBuilder
308 .withName("nsnextobjectivestore")
Jonathan Hart54541d12016-04-12 15:39:44 -0700309 .withSerializer(createSerializer())
Madan Jampani675ae202015-06-24 19:05:56 -0700310 .withTimestampProvider((k, v) -> new WallClockTimestamp())
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700311 .build();
312 log.trace("Current size {}", nsNextObjStore.size());
313
Charles Chan10b0fb72017-02-02 16:20:42 -0800314 log.debug("Creating EC map vlannextobjectivestore");
315 EventuallyConsistentMapBuilder<VlanNextObjectiveStoreKey, Integer>
316 vlanNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
317 vlanNextObjStore = vlanNextObjMapBuilder
318 .withName("vlannextobjectivestore")
Jonathan Hart54541d12016-04-12 15:39:44 -0700319 .withSerializer(createSerializer())
Charles Chan77277672015-10-20 16:24:19 -0700320 .withTimestampProvider((k, v) -> new WallClockTimestamp())
321 .build();
322
Saurav Das2d94d312015-11-24 23:21:05 -0800323 log.debug("Creating EC map subnetnextobjectivestore");
324 EventuallyConsistentMapBuilder<PortNextObjectiveStoreKey, Integer>
325 portNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
326 portNextObjStore = portNextObjMapBuilder
327 .withName("portnextobjectivestore")
Jonathan Hart54541d12016-04-12 15:39:44 -0700328 .withSerializer(createSerializer())
Saurav Das2d94d312015-11-24 23:21:05 -0800329 .withTimestampProvider((k, v) -> new WallClockTimestamp())
330 .build();
331
sangho4a5c42a2015-05-20 22:16:38 -0700332 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
333 storageService.eventuallyConsistentMapBuilder();
sangho4a5c42a2015-05-20 22:16:38 -0700334 tunnelStore = tunnelMapBuilder
335 .withName("tunnelstore")
Jonathan Hart54541d12016-04-12 15:39:44 -0700336 .withSerializer(createSerializer())
Madan Jampani675ae202015-06-24 19:05:56 -0700337 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho4a5c42a2015-05-20 22:16:38 -0700338 .build();
339
340 EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
341 storageService.eventuallyConsistentMapBuilder();
sangho4a5c42a2015-05-20 22:16:38 -0700342 policyStore = policyMapBuilder
343 .withName("policystore")
Jonathan Hart54541d12016-04-12 15:39:44 -0700344 .withSerializer(createSerializer())
Madan Jampani675ae202015-06-24 19:05:56 -0700345 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho4a5c42a2015-05-20 22:16:38 -0700346 .build();
347
Saurav Dasc3604f12016-03-23 11:22:49 -0700348 compCfgService.preSetProperty("org.onosproject.net.group.impl.GroupManager",
Pier Luigib9632ba2017-01-12 18:14:58 -0800349 "purgeOnDisconnection", "true");
Saurav Dasc3604f12016-03-23 11:22:49 -0700350 compCfgService.preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
Pier Luigib9632ba2017-01-12 18:14:58 -0800351 "purgeOnDisconnection", "true");
Pier Luigib9632ba2017-01-12 18:14:58 -0800352 compCfgService.preSetProperty("org.onosproject.provider.host.impl.HostLocationProvider",
353 "requestInterceptsEnabled", "false");
Pier Luigibc976df2017-01-12 22:46:39 -0800354 compCfgService.preSetProperty("org.onosproject.incubator.net.neighbour.impl.NeighbourResolutionManager",
355 "requestInterceptsEnabled", "false");
356 compCfgService.preSetProperty("org.onosproject.dhcprelay.DhcpRelay",
357 "arpEnabled", "false");
Pier Luigi0ebeb312017-02-02 22:31:34 -0800358 compCfgService.preSetProperty("org.onosproject.net.host.impl.HostManager",
359 "greedyLearningIpv6", "true");
360
Saurav Dasc3604f12016-03-23 11:22:49 -0700361
Charles Chan2b078ae2015-10-14 11:24:40 -0700362 processor = new InternalPacketProcessor();
363 linkListener = new InternalLinkListener();
364 deviceListener = new InternalDeviceListener();
Charles Chan82f19972016-05-17 13:13:55 -0700365 appCfgHandler = new AppConfigHandler(this);
366 xConnectHandler = new XConnectHandler(this);
Charles Chan1eaf4802016-04-18 13:44:03 -0700367 mcastHandler = new McastHandler(this);
368 hostHandler = new HostHandler(this);
Charles Chan41f5ec02016-06-13 18:54:31 -0700369 cordConfigHandler = new CordConfigHandler(this);
Charles Chandebfea32016-10-24 14:52:01 -0700370 routeHandler = new RouteHandler(this);
Pier Ventreb6b81d52016-12-02 08:16:05 -0800371 neighbourHandler = new SegmentRoutingNeighbourDispatcher(this);
Pier Ventre6b19e482016-11-07 16:21:04 -0800372 l2TunnelHandler = new L2TunnelHandler(this);
Charles Chan2b078ae2015-10-14 11:24:40 -0700373
Charles Chand6d25332016-02-26 22:19:52 -0800374 cfgService.addListener(cfgListener);
Charles Chanc91c8782016-03-30 17:54:24 -0700375 cfgService.registerConfigFactory(deviceConfigFactory);
376 cfgService.registerConfigFactory(appConfigFactory);
Charles Chan82f19972016-05-17 13:13:55 -0700377 cfgService.registerConfigFactory(xConnectConfigFactory);
Charles Chanc91c8782016-03-30 17:54:24 -0700378 cfgService.registerConfigFactory(mcastConfigFactory);
Pier Ventre6b19e482016-11-07 16:21:04 -0800379 cfgService.registerConfigFactory(pwaasConfigFactory);
Charles Chan82ab1932016-01-30 23:22:37 -0800380 hostService.addListener(hostListener);
Charles Chan2b078ae2015-10-14 11:24:40 -0700381 packetService.addProcessor(processor, PacketProcessor.director(2));
382 linkService.addListener(linkListener);
383 deviceService.addListener(deviceListener);
Charles Chanc91c8782016-03-30 17:54:24 -0700384 multicastRouteService.addListener(mcastListener);
Charles Chan41f5ec02016-06-13 18:54:31 -0700385 cordConfigService.addListener(cordConfigListener);
Charles Chan2b078ae2015-10-14 11:24:40 -0700386
387 cfgListener.configureNetwork();
388
Charles Chandebfea32016-10-24 14:52:01 -0700389 routeService.addListener(routeListener);
390
sangho80f11cb2015-04-01 13:05:26 -0700391 log.info("Started");
392 }
393
Jonathan Hart54541d12016-04-12 15:39:44 -0700394 private KryoNamespace.Builder createSerializer() {
395 return new KryoNamespace.Builder()
396 .register(KryoNamespaces.API)
397 .register(NeighborSetNextObjectiveStoreKey.class,
Charles Chan10b0fb72017-02-02 16:20:42 -0800398 VlanNextObjectiveStoreKey.class,
Jonathan Hart54541d12016-04-12 15:39:44 -0700399 SubnetAssignedVidStoreKey.class,
400 NeighborSet.class,
401 Tunnel.class,
402 DefaultTunnel.class,
403 Policy.class,
404 TunnelPolicy.class,
405 Policy.Type.class,
406 PortNextObjectiveStoreKey.class,
Charles Chan82f19972016-05-17 13:13:55 -0700407 XConnectStoreKey.class
Jonathan Hart54541d12016-04-12 15:39:44 -0700408 );
409 }
410
sangho80f11cb2015-04-01 13:05:26 -0700411 @Deactivate
412 protected void deactivate() {
Charles Chan72f556a2015-10-05 17:50:33 -0700413 cfgService.removeListener(cfgListener);
Charles Chanc91c8782016-03-30 17:54:24 -0700414 cfgService.unregisterConfigFactory(deviceConfigFactory);
415 cfgService.unregisterConfigFactory(appConfigFactory);
Charles Chandebfea32016-10-24 14:52:01 -0700416 cfgService.unregisterConfigFactory(xConnectConfigFactory);
Charles Chanc91c8782016-03-30 17:54:24 -0700417 cfgService.unregisterConfigFactory(mcastConfigFactory);
Pier Ventre6b19e482016-11-07 16:21:04 -0800418 cfgService.unregisterConfigFactory(pwaasConfigFactory);
Charles Chan72f556a2015-10-05 17:50:33 -0700419
sangho80f11cb2015-04-01 13:05:26 -0700420 packetService.removeProcessor(processor);
Charles Chan2b078ae2015-10-14 11:24:40 -0700421 linkService.removeListener(linkListener);
422 deviceService.removeListener(deviceListener);
Charles Chanc91c8782016-03-30 17:54:24 -0700423 multicastRouteService.removeListener(mcastListener);
Charles Chan41f5ec02016-06-13 18:54:31 -0700424 cordConfigService.removeListener(cordConfigListener);
Charles Chandebfea32016-10-24 14:52:01 -0700425 routeService.removeListener(routeListener);
Charles Chanc91c8782016-03-30 17:54:24 -0700426
Charles Chan2e71ef32017-02-23 15:44:08 -0800427 neighbourResolutionService.unregisterNeighbourHandlers(appId);
428
sangho80f11cb2015-04-01 13:05:26 -0700429 processor = null;
Charles Chan2b078ae2015-10-14 11:24:40 -0700430 linkListener = null;
Charles Chanc91c8782016-03-30 17:54:24 -0700431 deviceListener = null;
Charles Chan2b078ae2015-10-14 11:24:40 -0700432 groupHandlerMap.clear();
433
Charles Chanc91c8782016-03-30 17:54:24 -0700434 nsNextObjStore.destroy();
Charles Chan10b0fb72017-02-02 16:20:42 -0800435 vlanNextObjStore.destroy();
Charles Chanc91c8782016-03-30 17:54:24 -0700436 portNextObjStore.destroy();
Charles Chanc91c8782016-03-30 17:54:24 -0700437 tunnelStore.destroy();
438 policyStore.destroy();
sangho80f11cb2015-04-01 13:05:26 -0700439 log.info("Stopped");
440 }
441
sangho27462c62015-05-14 00:39:53 -0700442 @Override
443 public List<Tunnel> getTunnels() {
444 return tunnelHandler.getTunnels();
445 }
446
447 @Override
sanghobd812f82015-06-29 14:58:47 -0700448 public TunnelHandler.Result createTunnel(Tunnel tunnel) {
449 return tunnelHandler.createTunnel(tunnel);
sangho27462c62015-05-14 00:39:53 -0700450 }
451
452 @Override
sanghobd812f82015-06-29 14:58:47 -0700453 public TunnelHandler.Result removeTunnel(Tunnel tunnel) {
sangho27462c62015-05-14 00:39:53 -0700454 for (Policy policy: policyHandler.getPolicies()) {
455 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
456 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
457 if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
458 log.warn("Cannot remove the tunnel used by a policy");
sanghobd812f82015-06-29 14:58:47 -0700459 return TunnelHandler.Result.TUNNEL_IN_USE;
sangho27462c62015-05-14 00:39:53 -0700460 }
461 }
462 }
sanghobd812f82015-06-29 14:58:47 -0700463 return tunnelHandler.removeTunnel(tunnel);
sangho27462c62015-05-14 00:39:53 -0700464 }
465
466 @Override
sanghobd812f82015-06-29 14:58:47 -0700467 public PolicyHandler.Result removePolicy(Policy policy) {
468 return policyHandler.removePolicy(policy);
sangho27462c62015-05-14 00:39:53 -0700469 }
470
471 @Override
sanghobd812f82015-06-29 14:58:47 -0700472 public PolicyHandler.Result createPolicy(Policy policy) {
473 return policyHandler.createPolicy(policy);
sangho27462c62015-05-14 00:39:53 -0700474 }
475
476 @Override
477 public List<Policy> getPolicies() {
478 return policyHandler.getPolicies();
479 }
480
Saurav Das07c74602016-04-27 18:35:50 -0700481 @Override
482 public void rerouteNetwork() {
483 cfgListener.configureNetwork();
484 for (Device device : deviceService.getDevices()) {
Saurav Dasf9332192017-02-18 14:05:44 -0800485 if (mastershipService.isLocalMaster(device.id())) {
486 defaultRoutingHandler.populatePortAddressingRules(device.id());
487 }
Saurav Das07c74602016-04-27 18:35:50 -0700488 }
489 defaultRoutingHandler.startPopulationProcess();
490 }
491
Charles Chand7844e52016-10-20 17:02:44 -0700492 @Override
Pier Ventreb6a7f342016-11-26 21:05:22 -0800493 public Map<DeviceId, Set<IpPrefix>> getDeviceSubnetMap() {
494 Map<DeviceId, Set<IpPrefix>> deviceSubnetMap = Maps.newHashMap();
Charles Chand7844e52016-10-20 17:02:44 -0700495 deviceService.getAvailableDevices().forEach(device -> {
496 deviceSubnetMap.put(device.id(), deviceConfiguration.getSubnets(device.id()));
497 });
498 return deviceSubnetMap;
499 }
500
sangho80f1f892015-05-19 11:57:42 -0700501 /**
Pier Ventre7a78de22016-10-31 15:00:01 -0700502 * Returns the MPLS-ECMP configuration.
503 *
504 * @return MPLS-ECMP value
505 */
506 public boolean getMplsEcmp() {
507 SegmentRoutingAppConfig segmentRoutingAppConfig = cfgService
508 .getConfig(this.appId, SegmentRoutingAppConfig.class);
509 return segmentRoutingAppConfig != null && segmentRoutingAppConfig.mplsEcmp();
510 }
511
512 /**
sangho80f1f892015-05-19 11:57:42 -0700513 * Returns the tunnel object with the tunnel ID.
514 *
515 * @param tunnelId Tunnel ID
516 * @return Tunnel reference
517 */
sangho27462c62015-05-14 00:39:53 -0700518 public Tunnel getTunnel(String tunnelId) {
519 return tunnelHandler.getTunnel(tunnelId);
520 }
521
sangho80f11cb2015-04-01 13:05:26 -0700522 /**
Charles Chan10b0fb72017-02-02 16:20:42 -0800523 * Returns untagged VLAN configured on given connect point.
sangho80f11cb2015-04-01 13:05:26 -0700524 *
Charles Chan10b0fb72017-02-02 16:20:42 -0800525 * @param connectPoint connect point
526 * @return untagged VLAN or null if not configured
sangho80f11cb2015-04-01 13:05:26 -0700527 */
Charles Chan10b0fb72017-02-02 16:20:42 -0800528 public VlanId getUntaggedVlanId(ConnectPoint connectPoint) {
529 return interfaceService.getInterfacesByPort(connectPoint).stream()
530 .filter(intf -> !intf.vlanUntagged().equals(VlanId.NONE))
531 .map(Interface::vlanUntagged)
532 .findFirst().orElse(null);
sangho80f11cb2015-04-01 13:05:26 -0700533 }
534
sangho27462c62015-05-14 00:39:53 -0700535 /**
Saurav Das7c305372015-10-28 12:39:42 -0700536 * Returns the next objective ID for the given NeighborSet.
Saurav Das4c35fc42015-11-20 15:27:53 -0800537 * If the nextObjective does not exist, a new one is created and
Saurav Das2d94d312015-11-24 23:21:05 -0800538 * its id is returned.
sangho27462c62015-05-14 00:39:53 -0700539 *
sangho80f1f892015-05-19 11:57:42 -0700540 * @param deviceId Device ID
541 * @param ns NegighborSet
Saurav Das4c35fc42015-11-20 15:27:53 -0800542 * @param meta metadata passed into the creation of a Next Objective
Pier Ventre229fd0b2016-10-31 16:49:19 -0700543 * @param isBos indicates if it is BoS or not
Saurav Das4c35fc42015-11-20 15:27:53 -0800544 * @return next objective ID or -1 if an error was encountered during the
545 * creation of the nextObjective
sangho27462c62015-05-14 00:39:53 -0700546 */
Saurav Das4c35fc42015-11-20 15:27:53 -0800547 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns,
Pier Ventre229fd0b2016-10-31 16:49:19 -0700548 TrafficSelector meta, boolean isBos) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700549 if (groupHandlerMap.get(deviceId) != null) {
550 log.trace("getNextObjectiveId query in device {}", deviceId);
551 return groupHandlerMap
Pier Ventre229fd0b2016-10-31 16:49:19 -0700552 .get(deviceId).getNextObjectiveId(ns, meta, isBos);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700553 } else {
Saurav Das2d94d312015-11-24 23:21:05 -0800554 log.warn("getNextObjectiveId query - groupHandler for device {} "
555 + "not found", deviceId);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700556 return -1;
557 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700558 }
559
Charles Chan77277672015-10-20 16:24:19 -0700560 /**
Pier Ventre229fd0b2016-10-31 16:49:19 -0700561 * Returns the next objective ID for the given NeighborSet.
562 * If the nextObjective does not exist, a new one is created and
563 * its id is returned.
564 *
565 * @param deviceId Device ID
566 * @param ns NegighborSet
567 * @param meta metadata passed into the creation of a Next Objective
568 * @return next objective ID or -1 if an error was encountered during the
569 * creation of the nextObjective
570 */
571 public int getNextObjectiveId(DeviceId deviceId,
572 NeighborSet ns,
573 TrafficSelector meta) {
574 return this.getNextObjectiveId(deviceId, ns, meta, true);
575 }
576
577 /**
Saurav Das2d94d312015-11-24 23:21:05 -0800578 * Returns the next objective ID for the given subnet prefix. It is expected
Charles Chan10b0fb72017-02-02 16:20:42 -0800579 * Returns the next objective ID for the given vlan id. It is expected
Saurav Das2d94d312015-11-24 23:21:05 -0800580 * that the next-objective has been pre-created from configuration.
Charles Chan77277672015-10-20 16:24:19 -0700581 *
582 * @param deviceId Device ID
Charles Chan10b0fb72017-02-02 16:20:42 -0800583 * @param vlanId VLAN ID
Saurav Das2d94d312015-11-24 23:21:05 -0800584 * @return next objective ID or -1 if it was not found
Charles Chan77277672015-10-20 16:24:19 -0700585 */
Charles Chan10b0fb72017-02-02 16:20:42 -0800586 public int getVlanNextObjectiveId(DeviceId deviceId, VlanId vlanId) {
Charles Chan77277672015-10-20 16:24:19 -0700587 if (groupHandlerMap.get(deviceId) != null) {
Charles Chan10b0fb72017-02-02 16:20:42 -0800588 log.trace("getVlanNextObjectiveId query in device {}", deviceId);
589 return groupHandlerMap.get(deviceId).getVlanNextObjectiveId(vlanId);
Charles Chan77277672015-10-20 16:24:19 -0700590 } else {
Charles Chan10b0fb72017-02-02 16:20:42 -0800591 log.warn("getVlanNextObjectiveId query - groupHandler for "
Saurav Das2d94d312015-11-24 23:21:05 -0800592 + "device {} not found", deviceId);
593 return -1;
594 }
595 }
596
597 /**
598 * Returns the next objective ID for the given portNumber, given the treatment.
599 * There could be multiple different treatments to the same outport, which
600 * would result in different objectives. If the next object
601 * does not exist, a new one is created and its id is returned.
602 *
603 * @param deviceId Device ID
604 * @param portNum port number on device for which NextObjective is queried
605 * @param treatment the actions to apply on the packets (should include outport)
606 * @param meta metadata passed into the creation of a Next Objective if necessary
Saurav Das07c74602016-04-27 18:35:50 -0700607 * @return next objective ID or -1 if an error occurred during retrieval or creation
Saurav Das2d94d312015-11-24 23:21:05 -0800608 */
609 public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum,
610 TrafficTreatment treatment,
611 TrafficSelector meta) {
612 DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId);
613 if (ghdlr != null) {
614 return ghdlr.getPortNextObjectiveId(portNum, treatment, meta);
615 } else {
Charles Chanb7f75ac2016-01-11 18:28:54 -0800616 log.warn("getPortNextObjectiveId query - groupHandler for device {}"
617 + " not found", deviceId);
618 return -1;
619 }
620 }
621
sangho80f11cb2015-04-01 13:05:26 -0700622 private class InternalPacketProcessor implements PacketProcessor {
sangho80f11cb2015-04-01 13:05:26 -0700623 @Override
624 public void process(PacketContext context) {
625
626 if (context.isHandled()) {
627 return;
628 }
629
630 InboundPacket pkt = context.inPacket();
631 Ethernet ethernet = pkt.parsed();
Pier Luigi37a35432017-02-01 13:50:04 -0800632
633 if (ethernet == null) {
634 return;
635 }
636
Saurav Das2d94d312015-11-24 23:21:05 -0800637 log.trace("Rcvd pktin: {}", ethernet);
Pier Ventreadb4ae62016-11-23 09:57:42 -0800638 if (ethernet.getEtherType() == TYPE_ARP) {
Charles Chanef1cfef2017-02-16 11:45:52 -0800639 log.warn("Receive unexpected ARP packet on {}", context.inPacket().receivedFrom());
Pier Ventreb6a7f342016-11-26 21:05:22 -0800640 log.debug("{}", ethernet);
Pier Ventre6b2c1b32016-12-09 17:26:04 -0800641 return;
sangho80f11cb2015-04-01 13:05:26 -0700642 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
Pier Ventreb6b81d52016-12-02 08:16:05 -0800643 IPv4 ipv4Packet = (IPv4) ethernet.getPayload();
644 //ipHandler.addToPacketBuffer(ipv4Packet);
645 if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_ICMP) {
646 icmpHandler.processIcmp(ethernet, pkt.receivedFrom());
sangho80f11cb2015-04-01 13:05:26 -0700647 } else {
Charles Chand041ad82017-01-13 17:20:44 -0800648 // NOTE: We don't support IP learning at this moment so this
649 // is not necessary. Also it causes duplication of DHCP packets.
Pier Ventre6b2c1b32016-12-09 17:26:04 -0800650 // ipHandler.processPacketIn(ipv4Packet, pkt.receivedFrom());
sangho80f11cb2015-04-01 13:05:26 -0700651 }
Pier Ventreb6a7f342016-11-26 21:05:22 -0800652 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV6) {
653 IPv6 ipv6Packet = (IPv6) ethernet.getPayload();
Pier Ventreb6b81d52016-12-02 08:16:05 -0800654 //ipHandler.addToPacketBuffer(ipv6Packet);
Pier Luigi37a35432017-02-01 13:50:04 -0800655 // We deal with the packet only if the packet is a ICMP6 ECHO/REPLY
Pier Ventreb6b81d52016-12-02 08:16:05 -0800656 if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
657 ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload();
658 if (icmp6Packet.getIcmpType() == ICMP6.ECHO_REQUEST ||
659 icmp6Packet.getIcmpType() == ICMP6.ECHO_REPLY) {
660 icmpHandler.processIcmpv6(ethernet, pkt.receivedFrom());
661 } else {
Pier Luigi37a35432017-02-01 13:50:04 -0800662 // XXX Neigbour hacking, to handle the ICMPv6 packet
663 // not under our control
664 if (icmpHandler.handleUPstreamPackets(context)) {
665 log.debug("Rcvd pktin from UpStream: {}", ipv6Packet);
666 } else {
667 log.debug("Received ICMPv6 0x{} - not handled",
668 Integer.toHexString(icmp6Packet.getIcmpType() & 0xff));
669 }
Pier Ventreb6b81d52016-12-02 08:16:05 -0800670 }
671 } else {
672 // NOTE: We don't support IP learning at this moment so this
673 // is not necessary. Also it causes duplication of DHCPv6 packets.
674 // ipHandler.processPacketIn(ipv6Packet, pkt.receivedFrom());
675 }
sangho80f11cb2015-04-01 13:05:26 -0700676 }
677 }
678 }
679
680 private class InternalLinkListener implements LinkListener {
681 @Override
682 public void event(LinkEvent event) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700683 if (event.type() == LinkEvent.Type.LINK_ADDED
684 || event.type() == LinkEvent.Type.LINK_REMOVED) {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700685 log.debug("Event {} received from Link Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700686 scheduleEventHandlerIfNotScheduled(event);
687 }
688 }
689 }
690
691 private class InternalDeviceListener implements DeviceListener {
sangho80f11cb2015-04-01 13:05:26 -0700692 @Override
693 public void event(DeviceEvent event) {
sangho80f11cb2015-04-01 13:05:26 -0700694 switch (event.type()) {
695 case DEVICE_ADDED:
Saurav Dasf0f592d2016-11-18 15:21:57 -0800696 case PORT_UPDATED:
697 case PORT_ADDED:
sanghofb7c7292015-04-13 15:15:58 -0700698 case DEVICE_UPDATED:
699 case DEVICE_AVAILABILITY_CHANGED:
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700700 log.debug("Event {} received from Device Service", event.type());
sangho80f11cb2015-04-01 13:05:26 -0700701 scheduleEventHandlerIfNotScheduled(event);
702 break;
703 default:
704 }
705 }
706 }
707
Saurav Das2d94d312015-11-24 23:21:05 -0800708 @SuppressWarnings("rawtypes")
sangho80f11cb2015-04-01 13:05:26 -0700709 private void scheduleEventHandlerIfNotScheduled(Event event) {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700710 synchronized (threadSchedulerLock) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700711 eventQueue.add(event);
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700712 numOfEventsQueued++;
713
714 if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
715 //No pending scheduled event handling threads. So start a new one.
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700716 eventHandlerFuture = executorService
717 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
718 numOfHandlerScheduled++;
719 }
Jonathan Hart54541d12016-04-12 15:39:44 -0700720 log.trace("numOfEventsQueued {}, numOfEventHandlerScheduled {}",
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700721 numOfEventsQueued,
722 numOfHandlerScheduled);
sangho80f11cb2015-04-01 13:05:26 -0700723 }
sangho80f11cb2015-04-01 13:05:26 -0700724 }
725
726 private class InternalEventHandler implements Runnable {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700727 @Override
sangho80f11cb2015-04-01 13:05:26 -0700728 public void run() {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700729 try {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700730 while (true) {
Saurav Das2d94d312015-11-24 23:21:05 -0800731 @SuppressWarnings("rawtypes")
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700732 Event event = null;
733 synchronized (threadSchedulerLock) {
734 if (!eventQueue.isEmpty()) {
735 event = eventQueue.poll();
736 numOfEventsExecuted++;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700737 } else {
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700738 numOfHandlerExecution++;
739 log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
740 numOfHandlerExecution, numOfEventsExecuted);
741 break;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700742 }
sanghofb7c7292015-04-13 15:15:58 -0700743 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700744 if (event.type() == LinkEvent.Type.LINK_ADDED) {
745 processLinkAdded((Link) event.subject());
746 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
Pier Ventre6d593892016-09-13 21:33:40 -0700747 Link linkRemoved = (Link) event.subject();
748 if (linkRemoved.src().elementId() instanceof DeviceId &&
749 !deviceService.isAvailable(linkRemoved.src().deviceId())) {
750 continue;
751 }
752 if (linkRemoved.dst().elementId() instanceof DeviceId &&
753 !deviceService.isAvailable(linkRemoved.dst().deviceId())) {
754 continue;
755 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700756 processLinkRemoved((Link) event.subject());
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700757 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
758 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
759 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
Saurav Das62af8802015-12-04 10:52:59 -0800760 DeviceId deviceId = ((Device) event.subject()).id();
761 if (deviceService.isAvailable(deviceId)) {
Saurav Dasc28b3432015-10-30 17:45:38 -0700762 log.info("Processing device event {} for available device {}",
763 event.type(), ((Device) event.subject()).id());
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700764 processDeviceAdded((Device) event.subject());
Saurav Dasc3604f12016-03-23 11:22:49 -0700765 } else {
766 log.info("Processing device event {} for unavailable device {}",
767 event.type(), ((Device) event.subject()).id());
768 processDeviceRemoved((Device) event.subject());
769 }
Saurav Dasf0f592d2016-11-18 15:21:57 -0800770 } else if (event.type() == DeviceEvent.Type.PORT_ADDED) {
Saurav Dasd1872b02016-12-02 15:43:47 -0800771 // typically these calls come when device is added first time
772 // so port filtering rules are handled at the device_added event.
773 // port added calls represent all ports on the device,
774 // enabled or not.
Saurav Dasf0f592d2016-11-18 15:21:57 -0800775 log.debug("** PORT ADDED {}/{} -> {}",
Saurav Dasd1872b02016-12-02 15:43:47 -0800776 ((DeviceEvent) event).subject().id(),
777 ((DeviceEvent) event).port().number(),
778 event.type());
Saurav Dasf0f592d2016-11-18 15:21:57 -0800779 } else if (event.type() == DeviceEvent.Type.PORT_UPDATED) {
Saurav Dasd1872b02016-12-02 15:43:47 -0800780 // these calls happen for every subsequent event
781 // ports enabled, disabled, switch goes away, comes back
Saurav Dasf0f592d2016-11-18 15:21:57 -0800782 log.info("** PORT UPDATED {}/{} -> {}",
783 event.subject(),
784 ((DeviceEvent) event).port(),
785 event.type());
786 processPortUpdated(((Device) event.subject()),
787 ((DeviceEvent) event).port());
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700788 } else {
789 log.warn("Unhandled event type: {}", event.type());
790 }
sangho80f11cb2015-04-01 13:05:26 -0700791 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700792 } catch (Exception e) {
793 log.error("SegmentRouting event handler "
794 + "thread thrown an exception: {}", e);
sangho80f11cb2015-04-01 13:05:26 -0700795 }
sangho80f11cb2015-04-01 13:05:26 -0700796 }
797 }
798
sangho80f11cb2015-04-01 13:05:26 -0700799 private void processLinkAdded(Link link) {
Saurav Dasb149be12016-06-07 10:08:06 -0700800 log.info("** LINK ADDED {}", link.toString());
Charles Chan319d1a22015-11-03 10:42:14 -0800801 if (!deviceConfiguration.isConfigured(link.src().deviceId())) {
802 log.warn("Source device of this link is not configured.");
803 return;
804 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700805 //Irrespective whether the local is a MASTER or not for this device,
806 //create group handler instance and push default TTP flow rules.
807 //Because in a multi-instance setup, instances can initiate
808 //groups for any devices. Also the default TTP rules are needed
809 //to be pushed before inserting any IP table entries for any device
810 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
811 .deviceId());
812 if (groupHandler != null) {
Saurav Das4c35fc42015-11-20 15:27:53 -0800813 groupHandler.linkUp(link, mastershipService.isLocalMaster(
814 link.src().deviceId()));
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700815 } else {
816 Device device = deviceService.getDevice(link.src().deviceId());
817 if (device != null) {
818 log.warn("processLinkAdded: Link Added "
819 + "Notification without Device Added "
820 + "event, still handling it");
821 processDeviceAdded(device);
822 groupHandler = groupHandlerMap.get(link.src()
823 .deviceId());
Saurav Das4c35fc42015-11-20 15:27:53 -0800824 groupHandler.linkUp(link, mastershipService.isLocalMaster(device.id()));
sangho80f11cb2015-04-01 13:05:26 -0700825 }
826 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700827
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700828 log.trace("Starting optimized route population process");
829 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
830 //log.trace("processLinkAdded: re-starting route population process");
831 //defaultRoutingHandler.startPopulationProcess();
Charles Chan72779502016-04-23 17:36:10 -0700832
833 mcastHandler.init();
sangho80f11cb2015-04-01 13:05:26 -0700834 }
835
836 private void processLinkRemoved(Link link) {
Saurav Dasb149be12016-06-07 10:08:06 -0700837 log.info("** LINK REMOVED {}", link.toString());
sangho2165d222015-05-01 09:38:25 -0700838 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId());
839 if (groupHandler != null) {
Saurav Das62af8802015-12-04 10:52:59 -0800840 groupHandler.portDown(link.src().port(),
841 mastershipService.isLocalMaster(link.src().deviceId()));
sangho2165d222015-05-01 09:38:25 -0700842 }
Srikanth Vavilapalli64d96c12015-05-14 20:22:47 -0700843 log.trace("Starting optimized route population process");
844 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
845 //log.trace("processLinkRemoved: re-starting route population process");
846 //defaultRoutingHandler.startPopulationProcess();
Charles Chan72779502016-04-23 17:36:10 -0700847
848 mcastHandler.processLinkDown(link);
sangho80f11cb2015-04-01 13:05:26 -0700849 }
850
851 private void processDeviceAdded(Device device) {
Saurav Dasb149be12016-06-07 10:08:06 -0700852 log.info("** DEVICE ADDED with ID {}", device.id());
Charles Chan319d1a22015-11-03 10:42:14 -0800853 if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
Saurav Das8ec0ec42015-11-03 14:39:27 -0800854 log.warn("Device configuration uploading. Device {} will be "
855 + "processed after config completes.", device.id());
856 return;
857 }
Charles Chan72779502016-04-23 17:36:10 -0700858 processDeviceAddedInternal(device.id());
859 }
860
861 private void processDeviceAddedInternal(DeviceId deviceId) {
Saurav Dasc28b3432015-10-30 17:45:38 -0700862 // Irrespective of whether the local is a MASTER or not for this device,
863 // we need to create a SR-group-handler instance. This is because in a
864 // multi-instance setup, any instance can initiate forwarding/next-objectives
865 // for any switch (even if this instance is a SLAVE or not even connected
866 // to the switch). To handle this, a default-group-handler instance is necessary
867 // per switch.
Charles Chan72779502016-04-23 17:36:10 -0700868 log.debug("Current groupHandlerMap devs: {}", groupHandlerMap.keySet());
869 if (groupHandlerMap.get(deviceId) == null) {
Charles Chan319d1a22015-11-03 10:42:14 -0800870 DefaultGroupHandler groupHandler;
871 try {
872 groupHandler = DefaultGroupHandler.
Charles Chan72779502016-04-23 17:36:10 -0700873 createGroupHandler(deviceId,
874 appId,
875 deviceConfiguration,
876 linkService,
877 flowObjectiveService,
878 this);
Charles Chan319d1a22015-11-03 10:42:14 -0800879 } catch (DeviceConfigNotFoundException e) {
880 log.warn(e.getMessage() + " Aborting processDeviceAdded.");
881 return;
882 }
Charles Chan72779502016-04-23 17:36:10 -0700883 log.debug("updating groupHandlerMap with new config for device: {}",
884 deviceId);
885 groupHandlerMap.put(deviceId, groupHandler);
Saurav Das8ec0ec42015-11-03 14:39:27 -0800886 }
Saurav Dasb149be12016-06-07 10:08:06 -0700887
Charles Chan72779502016-04-23 17:36:10 -0700888 if (mastershipService.isLocalMaster(deviceId)) {
Saurav Dasf9332192017-02-18 14:05:44 -0800889 defaultRoutingHandler.populatePortAddressingRules(deviceId);
Charles Chandebfea32016-10-24 14:52:01 -0700890 hostHandler.init(deviceId);
Charles Chan82f19972016-05-17 13:13:55 -0700891 xConnectHandler.init(deviceId);
Charles Chan41f5ec02016-06-13 18:54:31 -0700892 cordConfigHandler.init(deviceId);
Charles Chan72779502016-04-23 17:36:10 -0700893 DefaultGroupHandler groupHandler = groupHandlerMap.get(deviceId);
Charles Chan10b0fb72017-02-02 16:20:42 -0800894 groupHandler.createGroupsFromVlanConfig();
Charles Chan72779502016-04-23 17:36:10 -0700895 routingRulePopulator.populateSubnetBroadcastRule(deviceId);
Charles Chan77277672015-10-20 16:24:19 -0700896 }
Charles Chan82ab1932016-01-30 23:22:37 -0800897
Charles Chandebfea32016-10-24 14:52:01 -0700898 appCfgHandler.init(deviceId);
899 routeHandler.init(deviceId);
sangho80f11cb2015-04-01 13:05:26 -0700900 }
901
Saurav Dasc3604f12016-03-23 11:22:49 -0700902 private void processDeviceRemoved(Device device) {
903 nsNextObjStore.entrySet().stream()
904 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
905 .forEach(entry -> {
906 nsNextObjStore.remove(entry.getKey());
907 });
Charles Chan10b0fb72017-02-02 16:20:42 -0800908 vlanNextObjStore.entrySet().stream()
Saurav Dasc3604f12016-03-23 11:22:49 -0700909 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
910 .forEach(entry -> {
Charles Chan10b0fb72017-02-02 16:20:42 -0800911 vlanNextObjStore.remove(entry.getKey());
Saurav Dasc3604f12016-03-23 11:22:49 -0700912 });
Saurav Dasc3604f12016-03-23 11:22:49 -0700913 portNextObjStore.entrySet().stream()
914 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
915 .forEach(entry -> {
916 portNextObjStore.remove(entry.getKey());
917 });
Saurav Dasc3604f12016-03-23 11:22:49 -0700918 groupHandlerMap.remove(device.id());
Saurav Dasc3604f12016-03-23 11:22:49 -0700919 defaultRoutingHandler.purgeEcmpGraph(device.id());
Charles Chan72779502016-04-23 17:36:10 -0700920 mcastHandler.removeDevice(device.id());
Charles Chan82f19972016-05-17 13:13:55 -0700921 xConnectHandler.removeDevice(device.id());
Saurav Dasc3604f12016-03-23 11:22:49 -0700922 }
923
Saurav Dasf0f592d2016-11-18 15:21:57 -0800924 private void processPortUpdated(Device device, Port port) {
925 if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
926 log.warn("Device configuration uploading. Not handling port event for"
927 + "dev: {} port: {}", device.id(), port.number());
928 return;
929 }
Saurav Dasf9332192017-02-18 14:05:44 -0800930
931 if (!mastershipService.isLocalMaster(device.id())) {
932 log.debug("Not master for dev:{} .. not handling port updated event"
933 + "for port {}", device.id(), port.number());
934 return;
935 }
936
937 // first we handle filtering rules associated with the port
938 if (port.isEnabled()) {
939 log.info("Switchport {}/{} enabled..programming filters",
940 device.id(), port.number());
941 defaultRoutingHandler.populateSinglePortFilteringRules(device.id(),
942 port.number());
943 } else {
944 log.info("Switchport {}/{} disabled..removing filters",
945 device.id(), port.number());
946 defaultRoutingHandler.revokeSinglePortFilteringRules(device.id(),
947 port.number());
948 }
Saurav Dasf0f592d2016-11-18 15:21:57 -0800949
950 // portUpdated calls are for ports that have gone down or up. For switch
951 // to switch ports, link-events should take care of any re-routing or
952 // group editing necessary for port up/down. Here we only process edge ports
953 // that are already configured.
Charles Chan10b0fb72017-02-02 16:20:42 -0800954 VlanId untaggedVlan = getUntaggedVlanId(new ConnectPoint(device.id(), port.number()));
955 VlanId vlanId = (untaggedVlan != null) ? untaggedVlan : INTERNAL_VLAN;
956
957 if (vlanId.equals(INTERNAL_VLAN)) {
Saurav Dasf0f592d2016-11-18 15:21:57 -0800958 log.debug("Not handling port updated event for unconfigured port "
959 + "dev/port: {}/{}", device.id(), port.number());
960 return;
961 }
Charles Chan10b0fb72017-02-02 16:20:42 -0800962 processEdgePort(device, port, vlanId);
Saurav Dasf0f592d2016-11-18 15:21:57 -0800963 }
964
Charles Chan10b0fb72017-02-02 16:20:42 -0800965 private void processEdgePort(Device device, Port port, VlanId vlanId) {
Saurav Dasf0f592d2016-11-18 15:21:57 -0800966 boolean portUp = port.isEnabled();
967 if (portUp) {
968 log.info("Device:EdgePort {}:{} is enabled in subnet: {}", device.id(),
Charles Chan10b0fb72017-02-02 16:20:42 -0800969 port.number(), vlanId);
Saurav Dasf0f592d2016-11-18 15:21:57 -0800970 } else {
971 log.info("Device:EdgePort {}:{} is disabled in subnet: {}", device.id(),
Charles Chan10b0fb72017-02-02 16:20:42 -0800972 port.number(), vlanId);
Saurav Dasf0f592d2016-11-18 15:21:57 -0800973 }
974
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700975 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
sangho80f11cb2015-04-01 13:05:26 -0700976 if (groupHandler != null) {
Charles Chan10b0fb72017-02-02 16:20:42 -0800977 groupHandler.processEdgePort(port.number(), vlanId, portUp);
Saurav Dasf0f592d2016-11-18 15:21:57 -0800978 } else {
979 log.warn("Group handler not found for dev:{}. Not handling edge port"
980 + " {} event for port:{}", device.id(),
981 (portUp) ? "UP" : "DOWN", port.number());
sangho80f11cb2015-04-01 13:05:26 -0700982 }
983 }
sangho27462c62015-05-14 00:39:53 -0700984
Pier Ventreb6a7f342016-11-26 21:05:22 -0800985 /**
986 * Registers the given connect point with the NRS, this is necessary
987 * to receive the NDP and ARP packets from the NRS.
988 *
989 * @param portToRegister connect point to register
990 */
991 public void registerConnectPoint(ConnectPoint portToRegister) {
Charles Chan2e71ef32017-02-23 15:44:08 -0800992 neighbourResolutionService.registerNeighbourHandler(
Pier Ventreb6a7f342016-11-26 21:05:22 -0800993 portToRegister,
994 neighbourHandler,
995 appId
996 );
997 }
998
Charles Chan72f556a2015-10-05 17:50:33 -0700999 private class InternalConfigListener implements NetworkConfigListener {
Charles Chan46fdfaf2016-11-09 20:51:44 -08001000 SegmentRoutingManager srManager;
Charles Chane7c61022015-10-07 14:21:45 -07001001
Charles Chanb7f75ac2016-01-11 18:28:54 -08001002 /**
1003 * Constructs the internal network config listener.
1004 *
Charles Chan46fdfaf2016-11-09 20:51:44 -08001005 * @param srManager segment routing manager
Charles Chanb7f75ac2016-01-11 18:28:54 -08001006 */
Charles Chan46fdfaf2016-11-09 20:51:44 -08001007 public InternalConfigListener(SegmentRoutingManager srManager) {
1008 this.srManager = srManager;
Charles Chane7c61022015-10-07 14:21:45 -07001009 }
1010
Charles Chanb7f75ac2016-01-11 18:28:54 -08001011 /**
1012 * Reads network config and initializes related data structure accordingly.
1013 */
Charles Chane7c61022015-10-07 14:21:45 -07001014 public void configureNetwork() {
Pier Ventreb6a7f342016-11-26 21:05:22 -08001015
Charles Chan46fdfaf2016-11-09 20:51:44 -08001016 deviceConfiguration = new DeviceConfiguration(srManager);
Charles Chane7c61022015-10-07 14:21:45 -07001017
Charles Chan46fdfaf2016-11-09 20:51:44 -08001018 arpHandler = new ArpHandler(srManager);
1019 icmpHandler = new IcmpHandler(srManager);
1020 ipHandler = new IpHandler(srManager);
1021 routingRulePopulator = new RoutingRulePopulator(srManager);
1022 defaultRoutingHandler = new DefaultRoutingHandler(srManager);
Charles Chane7c61022015-10-07 14:21:45 -07001023
1024 tunnelHandler = new TunnelHandler(linkService, deviceConfiguration,
1025 groupHandlerMap, tunnelStore);
1026 policyHandler = new PolicyHandler(appId, deviceConfiguration,
1027 flowObjectiveService,
1028 tunnelHandler, policyStore);
1029
Charles Chane7c61022015-10-07 14:21:45 -07001030 for (Device device : deviceService.getDevices()) {
Charles Chan72779502016-04-23 17:36:10 -07001031 processDeviceAddedInternal(device.id());
Charles Chane7c61022015-10-07 14:21:45 -07001032 }
1033
1034 defaultRoutingHandler.startPopulationProcess();
Charles Chan72779502016-04-23 17:36:10 -07001035 mcastHandler.init();
Charles Chane7c61022015-10-07 14:21:45 -07001036 }
1037
Charles Chan72f556a2015-10-05 17:50:33 -07001038 @Override
1039 public void event(NetworkConfigEvent event) {
Charles Chan82ab1932016-01-30 23:22:37 -08001040 // TODO move this part to NetworkConfigEventHandler
1041 if (event.configClass().equals(SegmentRoutingDeviceConfig.class)) {
1042 switch (event.type()) {
1043 case CONFIG_ADDED:
1044 log.info("Segment Routing Config added.");
1045 configureNetwork();
1046 break;
1047 case CONFIG_UPDATED:
1048 log.info("Segment Routing Config updated.");
1049 // TODO support dynamic configuration
1050 break;
1051 default:
1052 break;
Charles Chan2b078ae2015-10-14 11:24:40 -07001053 }
Charles Chan82ab1932016-01-30 23:22:37 -08001054 } else if (event.configClass().equals(SegmentRoutingAppConfig.class)) {
Charles Chan82f19972016-05-17 13:13:55 -07001055 checkState(appCfgHandler != null, "NetworkConfigEventHandler is not initialized");
Charles Chan82ab1932016-01-30 23:22:37 -08001056 switch (event.type()) {
1057 case CONFIG_ADDED:
Charles Chan82f19972016-05-17 13:13:55 -07001058 appCfgHandler.processAppConfigAdded(event);
Charles Chan82ab1932016-01-30 23:22:37 -08001059 break;
1060 case CONFIG_UPDATED:
Charles Chan82f19972016-05-17 13:13:55 -07001061 appCfgHandler.processAppConfigUpdated(event);
Charles Chan82ab1932016-01-30 23:22:37 -08001062 break;
1063 case CONFIG_REMOVED:
Charles Chan82f19972016-05-17 13:13:55 -07001064 appCfgHandler.processAppConfigRemoved(event);
1065 break;
1066 default:
1067 break;
1068 }
Charles Chandebfea32016-10-24 14:52:01 -07001069 configureNetwork();
Charles Chan82f19972016-05-17 13:13:55 -07001070 } else if (event.configClass().equals(XConnectConfig.class)) {
1071 checkState(xConnectHandler != null, "XConnectHandler is not initialized");
1072 switch (event.type()) {
1073 case CONFIG_ADDED:
1074 xConnectHandler.processXConnectConfigAdded(event);
1075 break;
1076 case CONFIG_UPDATED:
1077 xConnectHandler.processXConnectConfigUpdated(event);
1078 break;
1079 case CONFIG_REMOVED:
1080 xConnectHandler.processXConnectConfigRemoved(event);
Charles Chan82ab1932016-01-30 23:22:37 -08001081 break;
1082 default:
1083 break;
Charles Chan2b078ae2015-10-14 11:24:40 -07001084 }
Pier Luigi37a35432017-02-01 13:50:04 -08001085 // XXX Neighbour hacking. This method is looking for
1086 // the Internet-Router interface. In order to retrieve
1087 // the upstream port.
1088 } else if (event.configClass().equals(InterfaceConfig.class)) {
1089 switch (event.type()) {
1090 case CONFIG_ADDED:
1091 case CONFIG_UPDATED:
Pier Luigiad0a67f2017-02-03 13:34:21 -08001092 updateUPstreamCP();
Pier Luigi37a35432017-02-01 13:50:04 -08001093 case CONFIG_REGISTERED:
1094 case CONFIG_UNREGISTERED:
1095 case CONFIG_REMOVED:
1096 break;
1097 default:
1098 break;
1099 }
1100 // XXX Neighbour hacking. This method is looking for
1101 // the vrouter port.
1102 } else if (event.configClass().equals(RouterConfig.class)) {
1103 switch (event.type()) {
1104 case CONFIG_ADDED:
1105 case CONFIG_UPDATED:
Pier Luigiad0a67f2017-02-03 13:34:21 -08001106 updateVRouterCP(event);
Pier Luigi37a35432017-02-01 13:50:04 -08001107 case CONFIG_REGISTERED:
1108 case CONFIG_UNREGISTERED:
1109 case CONFIG_REMOVED:
1110 break;
1111 default:
1112 break;
1113 }
Pier Ventre6b19e482016-11-07 16:21:04 -08001114 } else if (event.configClass().equals(PwaasConfig.class)) {
1115 checkState(l2TunnelHandler != null, "L2TunnelHandler is not initialized");
1116 switch (event.type()) {
1117 case CONFIG_ADDED:
1118 l2TunnelHandler.processPwaasConfigAdded(event);
1119 break;
1120 case CONFIG_UPDATED:
1121 l2TunnelHandler.processPwaasConfigUpdated(event);
1122 break;
1123 case CONFIG_REMOVED:
1124 l2TunnelHandler.processPwaasConfigRemoved(event);
1125 break;
1126 default:
1127 break;
1128 }
Charles Chan72f556a2015-10-05 17:50:33 -07001129 }
1130 }
1131 }
Charles Chanf4586112015-11-09 16:37:23 -08001132
Pier Luigiad0a67f2017-02-03 13:34:21 -08001133 /////////////////////////////////////////////////////////////////
1134 // XXX Neighbour hacking, temporary workaround will be //
Saurav Dasf9332192017-02-18 14:05:44 -08001135 // removed as soon as possible, when bridging based //
1136 // control plane redirect is implemented. //
Pier Luigiad0a67f2017-02-03 13:34:21 -08001137 /////////////////////////////////////////////////////////////////
1138
1139 // XXX Neighbour hacking. To store upstream connect
1140 // point and vRouter connect point
1141 ConnectPoint upstreamCP = null;
1142 ConnectPoint vRouterCP = null;
1143
1144 // XXX Neighbour hacking. To update the Upstream CP
1145 public void updateUPstreamCP() {
1146 Set<ConnectPoint> portSubjects = cfgService.getSubjects(ConnectPoint.class, InterfaceConfig.class);
1147 upstreamCP = null;
1148 portSubjects.stream().forEach(subject -> {
1149 InterfaceConfig config = cfgService.getConfig(subject, InterfaceConfig.class);
1150 Set<Interface> networkInterfaces;
1151 try {
1152 networkInterfaces = config.getInterfaces();
1153 } catch (ConfigException e) {
1154 log.error("Error loading port configuration");
1155 return;
1156 }
1157 networkInterfaces.forEach(networkInterface -> {
1158 if (networkInterface.name().equals("internet-router")) {
1159 upstreamCP = subject;
1160 }
1161 });
1162 });
1163
1164 }
1165
1166 // XXX Neighbour hacking. To update the Upstream CP
1167 public void updateVRouterCP(NetworkConfigEvent event) {
1168 RouterConfig config = (RouterConfig) event.config().get();
1169 if (config == null) {
1170 log.warn("Router config not available");
1171 vRouterCP = null;
1172 return;
1173 }
1174 vRouterCP = config.getControlPlaneConnectPoint();
1175 }
1176
Charles Chanf4586112015-11-09 16:37:23 -08001177 private class InternalHostListener implements HostListener {
Charles Chanf4586112015-11-09 16:37:23 -08001178 @Override
1179 public void event(HostEvent event) {
1180 // Do not proceed without mastership
1181 DeviceId deviceId = event.subject().location().deviceId();
1182 if (!mastershipService.isLocalMaster(deviceId)) {
1183 return;
1184 }
1185
1186 switch (event.type()) {
1187 case HOST_ADDED:
Charles Chan1eaf4802016-04-18 13:44:03 -07001188 hostHandler.processHostAddedEvent(event);
Charles Chanf4586112015-11-09 16:37:23 -08001189 break;
1190 case HOST_MOVED:
Charles Chan1eaf4802016-04-18 13:44:03 -07001191 hostHandler.processHostMovedEvent(event);
Charles Chanf4586112015-11-09 16:37:23 -08001192 break;
1193 case HOST_REMOVED:
Charles Chan1eaf4802016-04-18 13:44:03 -07001194 hostHandler.processHostRemoveEvent(event);
Charles Chanf4586112015-11-09 16:37:23 -08001195 break;
1196 case HOST_UPDATED:
Charles Chan1eaf4802016-04-18 13:44:03 -07001197 hostHandler.processHostUpdatedEvent(event);
Charles Chanf4586112015-11-09 16:37:23 -08001198 break;
1199 default:
1200 log.warn("Unsupported host event type: {}", event.type());
1201 break;
1202 }
1203 }
1204 }
1205
Charles Chanc91c8782016-03-30 17:54:24 -07001206 private class InternalMcastListener implements McastListener {
1207 @Override
1208 public void event(McastEvent event) {
1209 switch (event.type()) {
1210 case SOURCE_ADDED:
Charles Chan1eaf4802016-04-18 13:44:03 -07001211 mcastHandler.processSourceAdded(event);
Charles Chanc91c8782016-03-30 17:54:24 -07001212 break;
1213 case SINK_ADDED:
Charles Chan1eaf4802016-04-18 13:44:03 -07001214 mcastHandler.processSinkAdded(event);
Charles Chanc91c8782016-03-30 17:54:24 -07001215 break;
1216 case SINK_REMOVED:
Charles Chan1eaf4802016-04-18 13:44:03 -07001217 mcastHandler.processSinkRemoved(event);
Charles Chanc91c8782016-03-30 17:54:24 -07001218 break;
1219 case ROUTE_ADDED:
1220 case ROUTE_REMOVED:
1221 default:
1222 break;
1223 }
1224 }
1225 }
Charles Chan41f5ec02016-06-13 18:54:31 -07001226
1227 private class InternalCordConfigListener implements CordConfigListener {
1228 @Override
1229 public void event(CordConfigEvent event) {
1230 switch (event.type()) {
1231 case ACCESS_AGENT_ADDED:
1232 cordConfigHandler.processAccessAgentAddedEvent(event);
1233 break;
1234 case ACCESS_AGENT_UPDATED:
1235 cordConfigHandler.processAccessAgentUpdatedEvent(event);
1236 break;
1237 case ACCESS_AGENT_REMOVED:
1238 cordConfigHandler.processAccessAgentRemovedEvent(event);
1239 break;
1240 case ACCESS_DEVICE_ADDED:
1241 case ACCESS_DEVICE_UPDATED:
1242 case ACCESS_DEVICE_REMOVED:
1243 default:
1244 break;
1245 }
1246 }
1247 }
Charles Chandebfea32016-10-24 14:52:01 -07001248
1249 private class InternalRouteEventListener implements RouteListener {
1250 @Override
1251 public void event(RouteEvent event) {
1252 switch (event.type()) {
1253 case ROUTE_ADDED:
1254 routeHandler.processRouteAdded(event);
1255 break;
1256 case ROUTE_UPDATED:
1257 routeHandler.processRouteUpdated(event);
1258 break;
1259 case ROUTE_REMOVED:
1260 routeHandler.processRouteRemoved(event);
1261 break;
1262 default:
1263 break;
1264 }
1265 }
1266 }
sangho80f11cb2015-04-01 13:05:26 -07001267}