blob: 0e444fdb5358d15af64940682fc6fb5f6d852763 [file] [log] [blame]
sanghob35a6192015-04-01 13:05:26 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
sanghob35a6192015-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 Chan7ffd81f2017-02-08 15:52:08 -080018import com.google.common.collect.HashMultimap;
Charles Chanc81c45b2016-10-20 17:02:44 -070019import com.google.common.collect.Maps;
Charles Chan7ffd81f2017-02-08 15:52:08 -080020import com.google.common.collect.Multimap;
sanghob35a6192015-04-01 13:05:26 -070021import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
sangho1e575652015-05-14 00:39:53 -070026import org.apache.felix.scr.annotations.Service;
sanghob35a6192015-04-01 13:05:26 -070027import org.onlab.packet.Ethernet;
Pier Ventre735b8c82016-12-02 08:16:05 -080028import org.onlab.packet.ICMP6;
Charles Chanc42e84e2015-10-20 16:24:19 -070029import org.onlab.packet.IPv4;
Pier Ventre10bd8d12016-11-26 21:05:22 -080030import org.onlab.packet.IPv6;
Charles Chanc42e84e2015-10-20 16:24:19 -070031import org.onlab.packet.IpPrefix;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070032import org.onlab.packet.VlanId;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070033import org.onlab.util.KryoNamespace;
Saurav Das80980c72016-03-23 11:22:49 -070034import org.onosproject.cfg.ComponentConfigService;
sanghob35a6192015-04-01 13:05:26 -070035import org.onosproject.core.ApplicationId;
36import org.onosproject.core.CoreService;
37import org.onosproject.event.Event;
Pier Luigi721b6622017-02-03 13:34:21 -080038import org.onosproject.incubator.net.config.basics.ConfigException;
Pier Luigi7dad71c2017-02-01 13:50:04 -080039import org.onosproject.incubator.net.config.basics.InterfaceConfig;
Charles Chand55e84d2016-03-30 17:54:24 -070040import org.onosproject.incubator.net.config.basics.McastConfig;
Pier Luigi721b6622017-02-03 13:34:21 -080041import org.onosproject.incubator.net.intf.Interface;
Charles Chan2c15aca2016-11-09 20:51:44 -080042import org.onosproject.incubator.net.intf.InterfaceService;
Charles Chan03a73e02016-10-24 14:52:01 -070043import org.onosproject.incubator.net.routing.RouteEvent;
44import org.onosproject.incubator.net.routing.RouteListener;
45import org.onosproject.incubator.net.routing.RouteService;
Pier Ventre735b8c82016-12-02 08:16:05 -080046import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070047import org.onosproject.mastership.MastershipService;
Pier Ventre10bd8d12016-11-26 21:05:22 -080048import org.onosproject.net.ConnectPoint;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070049import org.onosproject.net.Device;
50import org.onosproject.net.DeviceId;
51import org.onosproject.net.Link;
52import org.onosproject.net.Port;
Charles Chan68aa62d2015-11-09 16:37:23 -080053import org.onosproject.net.PortNumber;
Charles Chand6832882015-10-05 17:50:33 -070054import org.onosproject.net.config.ConfigFactory;
55import org.onosproject.net.config.NetworkConfigEvent;
Charles Chand6832882015-10-05 17:50:33 -070056import org.onosproject.net.config.NetworkConfigListener;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070057import org.onosproject.net.config.NetworkConfigRegistry;
Charles Chand6832882015-10-05 17:50:33 -070058import org.onosproject.net.config.basics.SubjectFactories;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070059import org.onosproject.net.device.DeviceEvent;
60import org.onosproject.net.device.DeviceListener;
61import org.onosproject.net.device.DeviceService;
Charles Chan68aa62d2015-11-09 16:37:23 -080062import org.onosproject.net.flow.TrafficSelector;
63import org.onosproject.net.flow.TrafficTreatment;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070064import org.onosproject.net.flowobjective.FlowObjectiveService;
Charles Chan68aa62d2015-11-09 16:37:23 -080065import org.onosproject.net.host.HostEvent;
66import org.onosproject.net.host.HostListener;
Pier Ventre10bd8d12016-11-26 21:05:22 -080067import org.onosproject.net.host.HostService;
68import org.onosproject.net.link.LinkEvent;
69import org.onosproject.net.link.LinkListener;
70import org.onosproject.net.link.LinkService;
Charles Chand55e84d2016-03-30 17:54:24 -070071import org.onosproject.net.mcast.McastEvent;
72import org.onosproject.net.mcast.McastListener;
73import org.onosproject.net.mcast.MulticastRouteService;
Pier Ventre10bd8d12016-11-26 21:05:22 -080074import org.onosproject.net.packet.InboundPacket;
75import org.onosproject.net.packet.PacketContext;
76import org.onosproject.net.packet.PacketProcessor;
77import org.onosproject.net.packet.PacketService;
Pier Ventre42287df2016-11-09 14:17:26 -080078import org.onosproject.net.topology.PathService;
Charles Chand55e84d2016-03-30 17:54:24 -070079import org.onosproject.net.topology.TopologyService;
Pier Luigi7dad71c2017-02-01 13:50:04 -080080import org.onosproject.routing.config.RouterConfig;
Charles Chand55e84d2016-03-30 17:54:24 -070081import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
82import org.onosproject.segmentrouting.config.DeviceConfiguration;
Pier Ventref34966c2016-11-07 16:21:04 -080083import org.onosproject.segmentrouting.config.PwaasConfig;
Pier Ventre10bd8d12016-11-26 21:05:22 -080084import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
Pier Ventref34966c2016-11-07 16:21:04 -080085import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
Charles Chanfc5c7802016-05-17 13:13:55 -070086import org.onosproject.segmentrouting.config.XConnectConfig;
Charles Chand55e84d2016-03-30 17:54:24 -070087import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
88import org.onosproject.segmentrouting.grouphandler.NeighborSet;
Charles Chand2990362016-04-18 13:44:03 -070089import org.onosproject.segmentrouting.storekey.NeighborSetNextObjectiveStoreKey;
90import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
Charles Chand2990362016-04-18 13:44:03 -070091import org.onosproject.segmentrouting.storekey.SubnetAssignedVidStoreKey;
Charles Chan59cc16d2017-02-02 16:20:42 -080092import org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey;
Charles Chanfc5c7802016-05-17 13:13:55 -070093import org.onosproject.segmentrouting.storekey.XConnectStoreKey;
Pier Ventref34966c2016-11-07 16:21:04 -080094import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070095import org.onosproject.store.serializers.KryoNamespaces;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070096import org.onosproject.store.service.EventuallyConsistentMap;
97import org.onosproject.store.service.EventuallyConsistentMapBuilder;
98import org.onosproject.store.service.StorageService;
99import org.onosproject.store.service.WallClockTimestamp;
Charles Chan35fd1a72016-06-13 18:54:31 -0700100import org.opencord.cordconfig.CordConfigEvent;
101import org.opencord.cordconfig.CordConfigListener;
102import org.opencord.cordconfig.CordConfigService;
sanghob35a6192015-04-01 13:05:26 -0700103import org.slf4j.Logger;
104import org.slf4j.LoggerFactory;
105
sangho1e575652015-05-14 00:39:53 -0700106import java.util.List;
sanghob35a6192015-04-01 13:05:26 -0700107import java.util.Map;
Saurav Das0e99e2b2015-10-28 12:39:42 -0700108import java.util.Set;
sanghob35a6192015-04-01 13:05:26 -0700109import java.util.concurrent.ConcurrentHashMap;
110import java.util.concurrent.ConcurrentLinkedQueue;
111import java.util.concurrent.Executors;
112import java.util.concurrent.ScheduledExecutorService;
113import java.util.concurrent.ScheduledFuture;
114import java.util.concurrent.TimeUnit;
Charles Chan7ffd81f2017-02-08 15:52:08 -0800115import java.util.stream.Collectors;
sanghob35a6192015-04-01 13:05:26 -0700116
Charles Chan3e783d02016-02-26 22:19:52 -0800117import static com.google.common.base.Preconditions.checkState;
Pier Ventree0ae7a32016-11-23 09:57:42 -0800118import static org.onlab.packet.Ethernet.TYPE_ARP;
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700119import static org.onlab.util.Tools.groupedThreads;
Charles Chan3e783d02016-02-26 22:19:52 -0800120
Charles Chane849c192016-01-11 18:28:54 -0800121/**
122 * Segment routing manager.
123 */
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700124@Service
125@Component(immediate = true)
sangho1e575652015-05-14 00:39:53 -0700126public class SegmentRoutingManager implements SegmentRoutingService {
sanghob35a6192015-04-01 13:05:26 -0700127
Charles Chan2c15aca2016-11-09 20:51:44 -0800128 private static Logger log = LoggerFactory.getLogger(SegmentRoutingManager.class);
sanghob35a6192015-04-01 13:05:26 -0700129
130 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700131 private ComponentConfigService compCfgService;
sanghob35a6192015-04-01 13:05:26 -0700132
133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre10bd8d12016-11-26 21:05:22 -0800134 private NeighbourResolutionService neighbourResolutionService;
135
136 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre42287df2016-11-09 14:17:26 -0800137 public PathService pathService;
138
139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700140 CoreService coreService;
sanghob35a6192015-04-01 13:05:26 -0700141
142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700143 PacketService packetService;
sanghob35a6192015-04-01 13:05:26 -0700144
145 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700146 HostService hostService;
sanghob35a6192015-04-01 13:05:26 -0700147
148 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700149 DeviceService deviceService;
sanghob35a6192015-04-01 13:05:26 -0700150
151 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre42287df2016-11-09 14:17:26 -0800152 public FlowObjectiveService flowObjectiveService;
sanghob35a6192015-04-01 13:05:26 -0700153
154 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700155 LinkService linkService;
sangho1e575652015-05-14 00:39:53 -0700156
Charles Chan5270ed02016-01-30 23:22:37 -0800157 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre42287df2016-11-09 14:17:26 -0800158 public MastershipService mastershipService;
Charles Chan03a73e02016-10-24 14:52:01 -0700159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre42287df2016-11-09 14:17:26 -0800161 public StorageService storageService;
Charles Chan03a73e02016-10-24 14:52:01 -0700162
163 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
164 MulticastRouteService multicastRouteService;
165
166 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
167 TopologyService topologyService;
168
169 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
170 CordConfigService cordConfigService;
171
172 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
173 RouteService routeService;
Charles Chan5270ed02016-01-30 23:22:37 -0800174
175 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan2c15aca2016-11-09 20:51:44 -0800176 public NetworkConfigRegistry cfgService;
Charles Chan5270ed02016-01-30 23:22:37 -0800177
Saurav Das80980c72016-03-23 11:22:49 -0700178 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan2c15aca2016-11-09 20:51:44 -0800179 public InterfaceService interfaceService;
180
Charles Chan03a73e02016-10-24 14:52:01 -0700181 ArpHandler arpHandler = null;
182 IcmpHandler icmpHandler = null;
183 IpHandler ipHandler = null;
184 RoutingRulePopulator routingRulePopulator = null;
Charles Chan2c15aca2016-11-09 20:51:44 -0800185 public ApplicationId appId;
Pier Ventre42287df2016-11-09 14:17:26 -0800186 public DeviceConfiguration deviceConfiguration = null;
sanghob35a6192015-04-01 13:05:26 -0700187
Charles Chan03a73e02016-10-24 14:52:01 -0700188 DefaultRoutingHandler defaultRoutingHandler = null;
sangho1e575652015-05-14 00:39:53 -0700189 private TunnelHandler tunnelHandler = null;
190 private PolicyHandler policyHandler = null;
Charles Chanb8e10c82015-10-14 11:24:40 -0700191 private InternalPacketProcessor processor = null;
192 private InternalLinkListener linkListener = null;
193 private InternalDeviceListener deviceListener = null;
Charles Chanfc5c7802016-05-17 13:13:55 -0700194 private AppConfigHandler appCfgHandler = null;
Charles Chan03a73e02016-10-24 14:52:01 -0700195 XConnectHandler xConnectHandler = null;
Charles Chand2990362016-04-18 13:44:03 -0700196 private McastHandler mcastHandler = null;
Charles Chan03a73e02016-10-24 14:52:01 -0700197 HostHandler hostHandler = null;
Charles Chan35fd1a72016-06-13 18:54:31 -0700198 private CordConfigHandler cordConfigHandler = null;
Pier Ventre10bd8d12016-11-26 21:05:22 -0800199 private RouteHandler routeHandler = null;
Pier Ventre735b8c82016-12-02 08:16:05 -0800200 private SegmentRoutingNeighbourDispatcher neighbourHandler = null;
Pier Ventref34966c2016-11-07 16:21:04 -0800201 private L2TunnelHandler l2TunnelHandler = null;
sanghob35a6192015-04-01 13:05:26 -0700202 private InternalEventHandler eventHandler = new InternalEventHandler();
Charles Chan5270ed02016-01-30 23:22:37 -0800203 private final InternalHostListener hostListener = new InternalHostListener();
Charles Chand55e84d2016-03-30 17:54:24 -0700204 private final InternalConfigListener cfgListener = new InternalConfigListener(this);
205 private final InternalMcastListener mcastListener = new InternalMcastListener();
Charles Chan35fd1a72016-06-13 18:54:31 -0700206 private final InternalCordConfigListener cordConfigListener = new InternalCordConfigListener();
Charles Chan03a73e02016-10-24 14:52:01 -0700207 private final InternalRouteEventListener routeListener = new InternalRouteEventListener();
sanghob35a6192015-04-01 13:05:26 -0700208
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700209 private ScheduledExecutorService executorService = Executors
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700210 .newScheduledThreadPool(1, groupedThreads("SegmentRoutingManager", "event-%d", log));
sanghob35a6192015-04-01 13:05:26 -0700211
Saurav Das4ce45962015-11-24 23:21:05 -0800212 @SuppressWarnings("unused")
sanghob35a6192015-04-01 13:05:26 -0700213 private static ScheduledFuture<?> eventHandlerFuture = null;
Saurav Das4ce45962015-11-24 23:21:05 -0800214 @SuppressWarnings("rawtypes")
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700215 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<>();
Charles Chan68aa62d2015-11-09 16:37:23 -0800216 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap =
Charles Chane849c192016-01-11 18:28:54 -0800217 new ConcurrentHashMap<>();
218 /**
219 * Per device next objective ID store with (device id + neighbor set) as key.
220 */
221 public EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer>
Charles Chan68aa62d2015-11-09 16:37:23 -0800222 nsNextObjStore = null;
Charles Chane849c192016-01-11 18:28:54 -0800223 /**
224 * Per device next objective ID store with (device id + subnet) as key.
225 */
Charles Chan59cc16d2017-02-02 16:20:42 -0800226 public EventuallyConsistentMap<VlanNextObjectiveStoreKey, Integer>
227 vlanNextObjStore = null;
Charles Chane849c192016-01-11 18:28:54 -0800228 /**
229 * Per device next objective ID store with (device id + port) as key.
230 */
231 public EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer>
Saurav Das4ce45962015-11-24 23:21:05 -0800232 portNextObjStore = null;
Charles Chan59cc16d2017-02-02 16:20:42 -0800233
Saurav Das4ce45962015-11-24 23:21:05 -0800234 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
235 private EventuallyConsistentMap<String, Policy> policyStore = null;
sangho0b2b6d12015-05-20 22:16:38 -0700236
Charles Chand55e84d2016-03-30 17:54:24 -0700237 private final ConfigFactory<DeviceId, SegmentRoutingDeviceConfig> deviceConfigFactory =
Charles Chanfc5c7802016-05-17 13:13:55 -0700238 new ConfigFactory<DeviceId, SegmentRoutingDeviceConfig>(
239 SubjectFactories.DEVICE_SUBJECT_FACTORY,
Charles Chand55e84d2016-03-30 17:54:24 -0700240 SegmentRoutingDeviceConfig.class, "segmentrouting") {
Charles Chand6832882015-10-05 17:50:33 -0700241 @Override
Charles Chan5270ed02016-01-30 23:22:37 -0800242 public SegmentRoutingDeviceConfig createConfig() {
243 return new SegmentRoutingDeviceConfig();
Charles Chand6832882015-10-05 17:50:33 -0700244 }
245 };
Pier Ventref34966c2016-11-07 16:21:04 -0800246
Charles Chand55e84d2016-03-30 17:54:24 -0700247 private final ConfigFactory<ApplicationId, SegmentRoutingAppConfig> appConfigFactory =
Charles Chanfc5c7802016-05-17 13:13:55 -0700248 new ConfigFactory<ApplicationId, SegmentRoutingAppConfig>(
249 SubjectFactories.APP_SUBJECT_FACTORY,
Charles Chand55e84d2016-03-30 17:54:24 -0700250 SegmentRoutingAppConfig.class, "segmentrouting") {
Charles Chan5270ed02016-01-30 23:22:37 -0800251 @Override
252 public SegmentRoutingAppConfig createConfig() {
253 return new SegmentRoutingAppConfig();
254 }
255 };
Pier Ventref34966c2016-11-07 16:21:04 -0800256
Charles Chanfc5c7802016-05-17 13:13:55 -0700257 private final ConfigFactory<ApplicationId, XConnectConfig> xConnectConfigFactory =
258 new ConfigFactory<ApplicationId, XConnectConfig>(
259 SubjectFactories.APP_SUBJECT_FACTORY,
260 XConnectConfig.class, "xconnect") {
261 @Override
262 public XConnectConfig createConfig() {
263 return new XConnectConfig();
264 }
265 };
Pier Ventref34966c2016-11-07 16:21:04 -0800266
Charles Chand55e84d2016-03-30 17:54:24 -0700267 private ConfigFactory<ApplicationId, McastConfig> mcastConfigFactory =
Charles Chanfc5c7802016-05-17 13:13:55 -0700268 new ConfigFactory<ApplicationId, McastConfig>(
269 SubjectFactories.APP_SUBJECT_FACTORY,
Charles Chand55e84d2016-03-30 17:54:24 -0700270 McastConfig.class, "multicast") {
271 @Override
272 public McastConfig createConfig() {
273 return new McastConfig();
274 }
275 };
276
Pier Ventref34966c2016-11-07 16:21:04 -0800277 private final ConfigFactory<ApplicationId, PwaasConfig> pwaasConfigFactory =
278 new ConfigFactory<ApplicationId, PwaasConfig>(
279 SubjectFactories.APP_SUBJECT_FACTORY,
280 PwaasConfig.class, "pwaas") {
281 @Override
282 public PwaasConfig createConfig() {
283 return new PwaasConfig();
284 }
285 };
286
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700287 private Object threadSchedulerLock = new Object();
288 private static int numOfEventsQueued = 0;
289 private static int numOfEventsExecuted = 0;
sanghob35a6192015-04-01 13:05:26 -0700290 private static int numOfHandlerExecution = 0;
291 private static int numOfHandlerScheduled = 0;
292
Charles Chan116188d2016-02-18 14:22:42 -0800293 /**
294 * Segment Routing App ID.
295 */
Charles Chan2c15aca2016-11-09 20:51:44 -0800296 public static final String APP_NAME = "org.onosproject.segmentrouting";
Charles Chan59cc16d2017-02-02 16:20:42 -0800297
Charles Chane849c192016-01-11 18:28:54 -0800298 /**
299 * The default VLAN ID assigned to the interfaces without subnet config.
300 */
Charles Chan59cc16d2017-02-02 16:20:42 -0800301 public static final VlanId INTERNAL_VLAN = VlanId.vlanId((short) 4094);
Saurav Das0e99e2b2015-10-28 12:39:42 -0700302
sanghob35a6192015-04-01 13:05:26 -0700303 @Activate
304 protected void activate() {
Charles Chan2c15aca2016-11-09 20:51:44 -0800305 appId = coreService.registerApplication(APP_NAME);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700306
307 log.debug("Creating EC map nsnextobjectivestore");
308 EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
309 nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700310 nsNextObjStore = nsNextObjMapBuilder
311 .withName("nsnextobjectivestore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700312 .withSerializer(createSerializer())
Madan Jampanibcf1a482015-06-24 19:05:56 -0700313 .withTimestampProvider((k, v) -> new WallClockTimestamp())
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700314 .build();
315 log.trace("Current size {}", nsNextObjStore.size());
316
Charles Chan59cc16d2017-02-02 16:20:42 -0800317 log.debug("Creating EC map vlannextobjectivestore");
318 EventuallyConsistentMapBuilder<VlanNextObjectiveStoreKey, Integer>
319 vlanNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
320 vlanNextObjStore = vlanNextObjMapBuilder
321 .withName("vlannextobjectivestore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700322 .withSerializer(createSerializer())
Charles Chanc42e84e2015-10-20 16:24:19 -0700323 .withTimestampProvider((k, v) -> new WallClockTimestamp())
324 .build();
325
Saurav Das4ce45962015-11-24 23:21:05 -0800326 log.debug("Creating EC map subnetnextobjectivestore");
327 EventuallyConsistentMapBuilder<PortNextObjectiveStoreKey, Integer>
328 portNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
329 portNextObjStore = portNextObjMapBuilder
330 .withName("portnextobjectivestore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700331 .withSerializer(createSerializer())
Saurav Das4ce45962015-11-24 23:21:05 -0800332 .withTimestampProvider((k, v) -> new WallClockTimestamp())
333 .build();
334
sangho0b2b6d12015-05-20 22:16:38 -0700335 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
336 storageService.eventuallyConsistentMapBuilder();
sangho0b2b6d12015-05-20 22:16:38 -0700337 tunnelStore = tunnelMapBuilder
338 .withName("tunnelstore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700339 .withSerializer(createSerializer())
Madan Jampanibcf1a482015-06-24 19:05:56 -0700340 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho0b2b6d12015-05-20 22:16:38 -0700341 .build();
342
343 EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
344 storageService.eventuallyConsistentMapBuilder();
sangho0b2b6d12015-05-20 22:16:38 -0700345 policyStore = policyMapBuilder
346 .withName("policystore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700347 .withSerializer(createSerializer())
Madan Jampanibcf1a482015-06-24 19:05:56 -0700348 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho0b2b6d12015-05-20 22:16:38 -0700349 .build();
350
Saurav Das80980c72016-03-23 11:22:49 -0700351 compCfgService.preSetProperty("org.onosproject.net.group.impl.GroupManager",
Pier Luigi9e5c5ca2017-01-12 18:14:58 -0800352 "purgeOnDisconnection", "true");
Saurav Das80980c72016-03-23 11:22:49 -0700353 compCfgService.preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
Pier Luigi9e5c5ca2017-01-12 18:14:58 -0800354 "purgeOnDisconnection", "true");
Pier Luigi9e5c5ca2017-01-12 18:14:58 -0800355 compCfgService.preSetProperty("org.onosproject.provider.host.impl.HostLocationProvider",
356 "requestInterceptsEnabled", "false");
Pier Luigi7e415132017-01-12 22:46:39 -0800357 compCfgService.preSetProperty("org.onosproject.incubator.net.neighbour.impl.NeighbourResolutionManager",
358 "requestInterceptsEnabled", "false");
359 compCfgService.preSetProperty("org.onosproject.dhcprelay.DhcpRelay",
360 "arpEnabled", "false");
Pier Luigi9b1d6262017-02-02 22:31:34 -0800361 compCfgService.preSetProperty("org.onosproject.net.host.impl.HostManager",
362 "greedyLearningIpv6", "true");
363
Saurav Das80980c72016-03-23 11:22:49 -0700364
Charles Chanb8e10c82015-10-14 11:24:40 -0700365 processor = new InternalPacketProcessor();
366 linkListener = new InternalLinkListener();
367 deviceListener = new InternalDeviceListener();
Charles Chanfc5c7802016-05-17 13:13:55 -0700368 appCfgHandler = new AppConfigHandler(this);
369 xConnectHandler = new XConnectHandler(this);
Charles Chand2990362016-04-18 13:44:03 -0700370 mcastHandler = new McastHandler(this);
371 hostHandler = new HostHandler(this);
Charles Chan35fd1a72016-06-13 18:54:31 -0700372 cordConfigHandler = new CordConfigHandler(this);
Charles Chan03a73e02016-10-24 14:52:01 -0700373 routeHandler = new RouteHandler(this);
Pier Ventre735b8c82016-12-02 08:16:05 -0800374 neighbourHandler = new SegmentRoutingNeighbourDispatcher(this);
Pier Ventref34966c2016-11-07 16:21:04 -0800375 l2TunnelHandler = new L2TunnelHandler(this);
Charles Chanb8e10c82015-10-14 11:24:40 -0700376
Charles Chan3e783d02016-02-26 22:19:52 -0800377 cfgService.addListener(cfgListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700378 cfgService.registerConfigFactory(deviceConfigFactory);
379 cfgService.registerConfigFactory(appConfigFactory);
Charles Chanfc5c7802016-05-17 13:13:55 -0700380 cfgService.registerConfigFactory(xConnectConfigFactory);
Charles Chand55e84d2016-03-30 17:54:24 -0700381 cfgService.registerConfigFactory(mcastConfigFactory);
Pier Ventref34966c2016-11-07 16:21:04 -0800382 cfgService.registerConfigFactory(pwaasConfigFactory);
Charles Chan5270ed02016-01-30 23:22:37 -0800383 hostService.addListener(hostListener);
Charles Chanb8e10c82015-10-14 11:24:40 -0700384 packetService.addProcessor(processor, PacketProcessor.director(2));
385 linkService.addListener(linkListener);
386 deviceService.addListener(deviceListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700387 multicastRouteService.addListener(mcastListener);
Charles Chan35fd1a72016-06-13 18:54:31 -0700388 cordConfigService.addListener(cordConfigListener);
Charles Chanb8e10c82015-10-14 11:24:40 -0700389
390 cfgListener.configureNetwork();
391
Charles Chan03a73e02016-10-24 14:52:01 -0700392 routeService.addListener(routeListener);
393
sanghob35a6192015-04-01 13:05:26 -0700394 log.info("Started");
395 }
396
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700397 private KryoNamespace.Builder createSerializer() {
398 return new KryoNamespace.Builder()
399 .register(KryoNamespaces.API)
400 .register(NeighborSetNextObjectiveStoreKey.class,
Charles Chan59cc16d2017-02-02 16:20:42 -0800401 VlanNextObjectiveStoreKey.class,
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700402 SubnetAssignedVidStoreKey.class,
403 NeighborSet.class,
404 Tunnel.class,
405 DefaultTunnel.class,
406 Policy.class,
407 TunnelPolicy.class,
408 Policy.Type.class,
409 PortNextObjectiveStoreKey.class,
Charles Chanfc5c7802016-05-17 13:13:55 -0700410 XConnectStoreKey.class
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700411 );
412 }
413
sanghob35a6192015-04-01 13:05:26 -0700414 @Deactivate
415 protected void deactivate() {
Charles Chand6832882015-10-05 17:50:33 -0700416 cfgService.removeListener(cfgListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700417 cfgService.unregisterConfigFactory(deviceConfigFactory);
418 cfgService.unregisterConfigFactory(appConfigFactory);
Charles Chan03a73e02016-10-24 14:52:01 -0700419 cfgService.unregisterConfigFactory(xConnectConfigFactory);
Charles Chand55e84d2016-03-30 17:54:24 -0700420 cfgService.unregisterConfigFactory(mcastConfigFactory);
Pier Ventref34966c2016-11-07 16:21:04 -0800421 cfgService.unregisterConfigFactory(pwaasConfigFactory);
Charles Chand6832882015-10-05 17:50:33 -0700422
sanghob35a6192015-04-01 13:05:26 -0700423 packetService.removeProcessor(processor);
Charles Chanb8e10c82015-10-14 11:24:40 -0700424 linkService.removeListener(linkListener);
425 deviceService.removeListener(deviceListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700426 multicastRouteService.removeListener(mcastListener);
Charles Chan35fd1a72016-06-13 18:54:31 -0700427 cordConfigService.removeListener(cordConfigListener);
Charles Chan03a73e02016-10-24 14:52:01 -0700428 routeService.removeListener(routeListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700429
Charles Chan0aa674e2017-02-23 15:44:08 -0800430 neighbourResolutionService.unregisterNeighbourHandlers(appId);
431
sanghob35a6192015-04-01 13:05:26 -0700432 processor = null;
Charles Chanb8e10c82015-10-14 11:24:40 -0700433 linkListener = null;
Charles Chand55e84d2016-03-30 17:54:24 -0700434 deviceListener = null;
Charles Chanb8e10c82015-10-14 11:24:40 -0700435 groupHandlerMap.clear();
436
Charles Chand55e84d2016-03-30 17:54:24 -0700437 nsNextObjStore.destroy();
Charles Chan59cc16d2017-02-02 16:20:42 -0800438 vlanNextObjStore.destroy();
Charles Chand55e84d2016-03-30 17:54:24 -0700439 portNextObjStore.destroy();
Charles Chand55e84d2016-03-30 17:54:24 -0700440 tunnelStore.destroy();
441 policyStore.destroy();
sanghob35a6192015-04-01 13:05:26 -0700442 log.info("Stopped");
443 }
444
sangho1e575652015-05-14 00:39:53 -0700445 @Override
446 public List<Tunnel> getTunnels() {
447 return tunnelHandler.getTunnels();
448 }
449
450 @Override
sangho71abe1b2015-06-29 14:58:47 -0700451 public TunnelHandler.Result createTunnel(Tunnel tunnel) {
452 return tunnelHandler.createTunnel(tunnel);
sangho1e575652015-05-14 00:39:53 -0700453 }
454
455 @Override
sangho71abe1b2015-06-29 14:58:47 -0700456 public TunnelHandler.Result removeTunnel(Tunnel tunnel) {
sangho1e575652015-05-14 00:39:53 -0700457 for (Policy policy: policyHandler.getPolicies()) {
458 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
459 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
460 if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
461 log.warn("Cannot remove the tunnel used by a policy");
sangho71abe1b2015-06-29 14:58:47 -0700462 return TunnelHandler.Result.TUNNEL_IN_USE;
sangho1e575652015-05-14 00:39:53 -0700463 }
464 }
465 }
sangho71abe1b2015-06-29 14:58:47 -0700466 return tunnelHandler.removeTunnel(tunnel);
sangho1e575652015-05-14 00:39:53 -0700467 }
468
469 @Override
sangho71abe1b2015-06-29 14:58:47 -0700470 public PolicyHandler.Result removePolicy(Policy policy) {
471 return policyHandler.removePolicy(policy);
sangho1e575652015-05-14 00:39:53 -0700472 }
473
474 @Override
sangho71abe1b2015-06-29 14:58:47 -0700475 public PolicyHandler.Result createPolicy(Policy policy) {
476 return policyHandler.createPolicy(policy);
sangho1e575652015-05-14 00:39:53 -0700477 }
478
479 @Override
480 public List<Policy> getPolicies() {
481 return policyHandler.getPolicies();
482 }
483
Saurav Das59232cf2016-04-27 18:35:50 -0700484 @Override
485 public void rerouteNetwork() {
486 cfgListener.configureNetwork();
487 for (Device device : deviceService.getDevices()) {
Saurav Das018605f2017-02-18 14:05:44 -0800488 if (mastershipService.isLocalMaster(device.id())) {
489 defaultRoutingHandler.populatePortAddressingRules(device.id());
490 }
Saurav Das59232cf2016-04-27 18:35:50 -0700491 }
492 defaultRoutingHandler.startPopulationProcess();
493 }
494
Charles Chanc81c45b2016-10-20 17:02:44 -0700495 @Override
Pier Ventre10bd8d12016-11-26 21:05:22 -0800496 public Map<DeviceId, Set<IpPrefix>> getDeviceSubnetMap() {
497 Map<DeviceId, Set<IpPrefix>> deviceSubnetMap = Maps.newHashMap();
Charles Chanc81c45b2016-10-20 17:02:44 -0700498 deviceService.getAvailableDevices().forEach(device -> {
499 deviceSubnetMap.put(device.id(), deviceConfiguration.getSubnets(device.id()));
500 });
501 return deviceSubnetMap;
502 }
503
sanghof9d0bf12015-05-19 11:57:42 -0700504 /**
Pier Ventre98161782016-10-31 15:00:01 -0700505 * Returns the MPLS-ECMP configuration.
506 *
507 * @return MPLS-ECMP value
508 */
509 public boolean getMplsEcmp() {
510 SegmentRoutingAppConfig segmentRoutingAppConfig = cfgService
511 .getConfig(this.appId, SegmentRoutingAppConfig.class);
512 return segmentRoutingAppConfig != null && segmentRoutingAppConfig.mplsEcmp();
513 }
514
515 /**
sanghof9d0bf12015-05-19 11:57:42 -0700516 * Returns the tunnel object with the tunnel ID.
517 *
518 * @param tunnelId Tunnel ID
519 * @return Tunnel reference
520 */
sangho1e575652015-05-14 00:39:53 -0700521 public Tunnel getTunnel(String tunnelId) {
522 return tunnelHandler.getTunnel(tunnelId);
523 }
524
Charles Chan7ffd81f2017-02-08 15:52:08 -0800525 // TODO Consider moving these to InterfaceService
sanghob35a6192015-04-01 13:05:26 -0700526 /**
Charles Chan59cc16d2017-02-02 16:20:42 -0800527 * Returns untagged VLAN configured on given connect point.
Charles Chan7ffd81f2017-02-08 15:52:08 -0800528 * <p>
529 * Only returns the first match if there are multiple untagged VLAN configured
530 * on the connect point.
sanghob35a6192015-04-01 13:05:26 -0700531 *
Charles Chan59cc16d2017-02-02 16:20:42 -0800532 * @param connectPoint connect point
533 * @return untagged VLAN or null if not configured
sanghob35a6192015-04-01 13:05:26 -0700534 */
Charles Chan59cc16d2017-02-02 16:20:42 -0800535 public VlanId getUntaggedVlanId(ConnectPoint connectPoint) {
536 return interfaceService.getInterfacesByPort(connectPoint).stream()
537 .filter(intf -> !intf.vlanUntagged().equals(VlanId.NONE))
538 .map(Interface::vlanUntagged)
539 .findFirst().orElse(null);
sanghob35a6192015-04-01 13:05:26 -0700540 }
541
sangho1e575652015-05-14 00:39:53 -0700542 /**
Charles Chan7ffd81f2017-02-08 15:52:08 -0800543 * Returns tagged VLAN configured on given connect point.
544 * <p>
545 * Returns all matches if there are multiple tagged VLAN configured
546 * on the connect point.
547 *
548 * @param connectPoint connect point
549 * @return tagged VLAN or empty set if not configured
550 */
551 public Set<VlanId> getTaggedVlanId(ConnectPoint connectPoint) {
552 Set<Interface> interfaces = interfaceService.getInterfacesByPort(connectPoint);
553 return interfaces.stream()
554 .map(Interface::vlanTagged)
555 .flatMap(vlanIds -> vlanIds.stream())
556 .collect(Collectors.toSet());
557 }
558
559 /**
560 * Returns native VLAN configured on given connect point.
561 * <p>
562 * Only returns the first match if there are multiple native VLAN configured
563 * on the connect point.
564 *
565 * @param connectPoint connect point
566 * @return native VLAN or null if not configured
567 */
568 public VlanId getNativeVlanId(ConnectPoint connectPoint) {
569 Set<Interface> interfaces = interfaceService.getInterfacesByPort(connectPoint);
570 return interfaces.stream()
571 .filter(intf -> !intf.vlanNative().equals(VlanId.NONE))
572 .map(Interface::vlanNative)
573 .findFirst()
574 .orElse(null);
575 }
576
577 /**
578 * Returns vlan port map of given device.
579 *
580 * @param deviceId device id
581 * @return vlan-port multimap
582 */
583 public Multimap<VlanId, PortNumber> getVlanPortMap(DeviceId deviceId) {
584 HashMultimap<VlanId, PortNumber> vlanPortMap = HashMultimap.create();
585
586 interfaceService.getInterfaces().stream()
587 .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
588 .forEach(intf -> {
589 vlanPortMap.put(intf.vlanUntagged(), intf.connectPoint().port());
590 intf.vlanTagged().forEach(vlanTagged -> {
591 vlanPortMap.put(vlanTagged, intf.connectPoint().port());
592 });
593 vlanPortMap.put(intf.vlanNative(), intf.connectPoint().port());
594 });
595 vlanPortMap.removeAll(VlanId.NONE);
596
597 return vlanPortMap;
598 }
599
600 /**
Saurav Das0e99e2b2015-10-28 12:39:42 -0700601 * Returns the next objective ID for the given NeighborSet.
Saurav Das8a0732e2015-11-20 15:27:53 -0800602 * If the nextObjective does not exist, a new one is created and
Saurav Das4ce45962015-11-24 23:21:05 -0800603 * its id is returned.
sangho1e575652015-05-14 00:39:53 -0700604 *
sanghof9d0bf12015-05-19 11:57:42 -0700605 * @param deviceId Device ID
606 * @param ns NegighborSet
Saurav Das8a0732e2015-11-20 15:27:53 -0800607 * @param meta metadata passed into the creation of a Next Objective
Pier Ventre917127a2016-10-31 16:49:19 -0700608 * @param isBos indicates if it is BoS or not
Saurav Das8a0732e2015-11-20 15:27:53 -0800609 * @return next objective ID or -1 if an error was encountered during the
610 * creation of the nextObjective
sangho1e575652015-05-14 00:39:53 -0700611 */
Saurav Das8a0732e2015-11-20 15:27:53 -0800612 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns,
Pier Ventre917127a2016-10-31 16:49:19 -0700613 TrafficSelector meta, boolean isBos) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700614 if (groupHandlerMap.get(deviceId) != null) {
615 log.trace("getNextObjectiveId query in device {}", deviceId);
616 return groupHandlerMap
Pier Ventre917127a2016-10-31 16:49:19 -0700617 .get(deviceId).getNextObjectiveId(ns, meta, isBos);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700618 } else {
Saurav Das4ce45962015-11-24 23:21:05 -0800619 log.warn("getNextObjectiveId query - groupHandler for device {} "
620 + "not found", deviceId);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700621 return -1;
622 }
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700623 }
624
Charles Chanc42e84e2015-10-20 16:24:19 -0700625 /**
Pier Ventre917127a2016-10-31 16:49:19 -0700626 * Returns the next objective ID for the given NeighborSet.
627 * If the nextObjective does not exist, a new one is created and
628 * its id is returned.
629 *
630 * @param deviceId Device ID
631 * @param ns NegighborSet
632 * @param meta metadata passed into the creation of a Next Objective
633 * @return next objective ID or -1 if an error was encountered during the
634 * creation of the nextObjective
635 */
636 public int getNextObjectiveId(DeviceId deviceId,
637 NeighborSet ns,
638 TrafficSelector meta) {
639 return this.getNextObjectiveId(deviceId, ns, meta, true);
640 }
641
642 /**
Saurav Das4ce45962015-11-24 23:21:05 -0800643 * Returns the next objective ID for the given subnet prefix. It is expected
Charles Chan59cc16d2017-02-02 16:20:42 -0800644 * Returns the next objective ID for the given vlan id. It is expected
Saurav Das4ce45962015-11-24 23:21:05 -0800645 * that the next-objective has been pre-created from configuration.
Charles Chanc42e84e2015-10-20 16:24:19 -0700646 *
647 * @param deviceId Device ID
Charles Chan59cc16d2017-02-02 16:20:42 -0800648 * @param vlanId VLAN ID
Saurav Das4ce45962015-11-24 23:21:05 -0800649 * @return next objective ID or -1 if it was not found
Charles Chanc42e84e2015-10-20 16:24:19 -0700650 */
Charles Chan59cc16d2017-02-02 16:20:42 -0800651 public int getVlanNextObjectiveId(DeviceId deviceId, VlanId vlanId) {
Charles Chanc42e84e2015-10-20 16:24:19 -0700652 if (groupHandlerMap.get(deviceId) != null) {
Charles Chan59cc16d2017-02-02 16:20:42 -0800653 log.trace("getVlanNextObjectiveId query in device {}", deviceId);
654 return groupHandlerMap.get(deviceId).getVlanNextObjectiveId(vlanId);
Charles Chanc42e84e2015-10-20 16:24:19 -0700655 } else {
Charles Chan59cc16d2017-02-02 16:20:42 -0800656 log.warn("getVlanNextObjectiveId query - groupHandler for "
Saurav Das4ce45962015-11-24 23:21:05 -0800657 + "device {} not found", deviceId);
658 return -1;
659 }
660 }
661
662 /**
663 * Returns the next objective ID for the given portNumber, given the treatment.
664 * There could be multiple different treatments to the same outport, which
665 * would result in different objectives. If the next object
666 * does not exist, a new one is created and its id is returned.
667 *
668 * @param deviceId Device ID
669 * @param portNum port number on device for which NextObjective is queried
670 * @param treatment the actions to apply on the packets (should include outport)
671 * @param meta metadata passed into the creation of a Next Objective if necessary
Saurav Das59232cf2016-04-27 18:35:50 -0700672 * @return next objective ID or -1 if an error occurred during retrieval or creation
Saurav Das4ce45962015-11-24 23:21:05 -0800673 */
674 public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum,
675 TrafficTreatment treatment,
676 TrafficSelector meta) {
677 DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId);
678 if (ghdlr != null) {
679 return ghdlr.getPortNextObjectiveId(portNum, treatment, meta);
680 } else {
Charles Chane849c192016-01-11 18:28:54 -0800681 log.warn("getPortNextObjectiveId query - groupHandler for device {}"
682 + " not found", deviceId);
683 return -1;
684 }
685 }
686
sanghob35a6192015-04-01 13:05:26 -0700687 private class InternalPacketProcessor implements PacketProcessor {
sanghob35a6192015-04-01 13:05:26 -0700688 @Override
689 public void process(PacketContext context) {
690
691 if (context.isHandled()) {
692 return;
693 }
694
695 InboundPacket pkt = context.inPacket();
696 Ethernet ethernet = pkt.parsed();
Pier Luigi7dad71c2017-02-01 13:50:04 -0800697
698 if (ethernet == null) {
699 return;
700 }
701
Saurav Das4ce45962015-11-24 23:21:05 -0800702 log.trace("Rcvd pktin: {}", ethernet);
Pier Ventree0ae7a32016-11-23 09:57:42 -0800703 if (ethernet.getEtherType() == TYPE_ARP) {
Charles Chan7a068742017-02-16 11:45:52 -0800704 log.warn("Receive unexpected ARP packet on {}", context.inPacket().receivedFrom());
Pier Ventre10bd8d12016-11-26 21:05:22 -0800705 log.debug("{}", ethernet);
Pier Ventre968da122016-12-09 17:26:04 -0800706 return;
sanghob35a6192015-04-01 13:05:26 -0700707 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
Pier Ventre735b8c82016-12-02 08:16:05 -0800708 IPv4 ipv4Packet = (IPv4) ethernet.getPayload();
709 //ipHandler.addToPacketBuffer(ipv4Packet);
710 if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_ICMP) {
711 icmpHandler.processIcmp(ethernet, pkt.receivedFrom());
sanghob35a6192015-04-01 13:05:26 -0700712 } else {
Charles Chan50035632017-01-13 17:20:44 -0800713 // NOTE: We don't support IP learning at this moment so this
714 // is not necessary. Also it causes duplication of DHCP packets.
Pier Ventre968da122016-12-09 17:26:04 -0800715 // ipHandler.processPacketIn(ipv4Packet, pkt.receivedFrom());
sanghob35a6192015-04-01 13:05:26 -0700716 }
Pier Ventre10bd8d12016-11-26 21:05:22 -0800717 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV6) {
718 IPv6 ipv6Packet = (IPv6) ethernet.getPayload();
Pier Ventre735b8c82016-12-02 08:16:05 -0800719 //ipHandler.addToPacketBuffer(ipv6Packet);
Pier Luigi7dad71c2017-02-01 13:50:04 -0800720 // We deal with the packet only if the packet is a ICMP6 ECHO/REPLY
Pier Ventre735b8c82016-12-02 08:16:05 -0800721 if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
722 ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload();
723 if (icmp6Packet.getIcmpType() == ICMP6.ECHO_REQUEST ||
724 icmp6Packet.getIcmpType() == ICMP6.ECHO_REPLY) {
725 icmpHandler.processIcmpv6(ethernet, pkt.receivedFrom());
726 } else {
Pier Luigi7dad71c2017-02-01 13:50:04 -0800727 // XXX Neigbour hacking, to handle the ICMPv6 packet
728 // not under our control
729 if (icmpHandler.handleUPstreamPackets(context)) {
730 log.debug("Rcvd pktin from UpStream: {}", ipv6Packet);
731 } else {
732 log.debug("Received ICMPv6 0x{} - not handled",
733 Integer.toHexString(icmp6Packet.getIcmpType() & 0xff));
734 }
Pier Ventre735b8c82016-12-02 08:16:05 -0800735 }
736 } else {
737 // NOTE: We don't support IP learning at this moment so this
738 // is not necessary. Also it causes duplication of DHCPv6 packets.
739 // ipHandler.processPacketIn(ipv6Packet, pkt.receivedFrom());
740 }
sanghob35a6192015-04-01 13:05:26 -0700741 }
742 }
743 }
744
745 private class InternalLinkListener implements LinkListener {
746 @Override
747 public void event(LinkEvent event) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700748 if (event.type() == LinkEvent.Type.LINK_ADDED
749 || event.type() == LinkEvent.Type.LINK_REMOVED) {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700750 log.debug("Event {} received from Link Service", event.type());
sanghob35a6192015-04-01 13:05:26 -0700751 scheduleEventHandlerIfNotScheduled(event);
752 }
753 }
754 }
755
756 private class InternalDeviceListener implements DeviceListener {
sanghob35a6192015-04-01 13:05:26 -0700757 @Override
758 public void event(DeviceEvent event) {
sanghob35a6192015-04-01 13:05:26 -0700759 switch (event.type()) {
760 case DEVICE_ADDED:
Saurav Das1a129a02016-11-18 15:21:57 -0800761 case PORT_UPDATED:
762 case PORT_ADDED:
sangho20eff1d2015-04-13 15:15:58 -0700763 case DEVICE_UPDATED:
764 case DEVICE_AVAILABILITY_CHANGED:
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700765 log.debug("Event {} received from Device Service", event.type());
sanghob35a6192015-04-01 13:05:26 -0700766 scheduleEventHandlerIfNotScheduled(event);
767 break;
768 default:
769 }
770 }
771 }
772
Saurav Das4ce45962015-11-24 23:21:05 -0800773 @SuppressWarnings("rawtypes")
sanghob35a6192015-04-01 13:05:26 -0700774 private void scheduleEventHandlerIfNotScheduled(Event event) {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700775 synchronized (threadSchedulerLock) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700776 eventQueue.add(event);
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700777 numOfEventsQueued++;
778
779 if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
780 //No pending scheduled event handling threads. So start a new one.
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700781 eventHandlerFuture = executorService
782 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
783 numOfHandlerScheduled++;
784 }
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700785 log.trace("numOfEventsQueued {}, numOfEventHandlerScheduled {}",
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700786 numOfEventsQueued,
787 numOfHandlerScheduled);
sanghob35a6192015-04-01 13:05:26 -0700788 }
sanghob35a6192015-04-01 13:05:26 -0700789 }
790
791 private class InternalEventHandler implements Runnable {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700792 @Override
sanghob35a6192015-04-01 13:05:26 -0700793 public void run() {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700794 try {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700795 while (true) {
Saurav Das4ce45962015-11-24 23:21:05 -0800796 @SuppressWarnings("rawtypes")
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700797 Event event = null;
798 synchronized (threadSchedulerLock) {
799 if (!eventQueue.isEmpty()) {
800 event = eventQueue.poll();
801 numOfEventsExecuted++;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700802 } else {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700803 numOfHandlerExecution++;
804 log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
805 numOfHandlerExecution, numOfEventsExecuted);
806 break;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700807 }
sangho20eff1d2015-04-13 15:15:58 -0700808 }
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700809 if (event.type() == LinkEvent.Type.LINK_ADDED) {
810 processLinkAdded((Link) event.subject());
811 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
Pier Ventre2c515312016-09-13 21:33:40 -0700812 Link linkRemoved = (Link) event.subject();
813 if (linkRemoved.src().elementId() instanceof DeviceId &&
814 !deviceService.isAvailable(linkRemoved.src().deviceId())) {
815 continue;
816 }
817 if (linkRemoved.dst().elementId() instanceof DeviceId &&
818 !deviceService.isAvailable(linkRemoved.dst().deviceId())) {
819 continue;
820 }
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700821 processLinkRemoved((Link) event.subject());
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700822 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
823 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
824 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
Saurav Das423fe2b2015-12-04 10:52:59 -0800825 DeviceId deviceId = ((Device) event.subject()).id();
826 if (deviceService.isAvailable(deviceId)) {
Saurav Das837e0bb2015-10-30 17:45:38 -0700827 log.info("Processing device event {} for available device {}",
828 event.type(), ((Device) event.subject()).id());
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700829 processDeviceAdded((Device) event.subject());
Saurav Das80980c72016-03-23 11:22:49 -0700830 } else {
831 log.info("Processing device event {} for unavailable device {}",
832 event.type(), ((Device) event.subject()).id());
833 processDeviceRemoved((Device) event.subject());
834 }
Saurav Das1a129a02016-11-18 15:21:57 -0800835 } else if (event.type() == DeviceEvent.Type.PORT_ADDED) {
Saurav Dasd2fded02016-12-02 15:43:47 -0800836 // typically these calls come when device is added first time
837 // so port filtering rules are handled at the device_added event.
838 // port added calls represent all ports on the device,
839 // enabled or not.
Saurav Das1a129a02016-11-18 15:21:57 -0800840 log.debug("** PORT ADDED {}/{} -> {}",
Saurav Dasd2fded02016-12-02 15:43:47 -0800841 ((DeviceEvent) event).subject().id(),
842 ((DeviceEvent) event).port().number(),
843 event.type());
Saurav Das1a129a02016-11-18 15:21:57 -0800844 } else if (event.type() == DeviceEvent.Type.PORT_UPDATED) {
Saurav Dasd2fded02016-12-02 15:43:47 -0800845 // these calls happen for every subsequent event
846 // ports enabled, disabled, switch goes away, comes back
Saurav Das1a129a02016-11-18 15:21:57 -0800847 log.info("** PORT UPDATED {}/{} -> {}",
848 event.subject(),
849 ((DeviceEvent) event).port(),
850 event.type());
851 processPortUpdated(((Device) event.subject()),
852 ((DeviceEvent) event).port());
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700853 } else {
854 log.warn("Unhandled event type: {}", event.type());
855 }
sanghob35a6192015-04-01 13:05:26 -0700856 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700857 } catch (Exception e) {
858 log.error("SegmentRouting event handler "
859 + "thread thrown an exception: {}", e);
sanghob35a6192015-04-01 13:05:26 -0700860 }
sanghob35a6192015-04-01 13:05:26 -0700861 }
862 }
863
sanghob35a6192015-04-01 13:05:26 -0700864 private void processLinkAdded(Link link) {
Saurav Dasb5c236e2016-06-07 10:08:06 -0700865 log.info("** LINK ADDED {}", link.toString());
Charles Chan0b4e6182015-11-03 10:42:14 -0800866 if (!deviceConfiguration.isConfigured(link.src().deviceId())) {
867 log.warn("Source device of this link is not configured.");
868 return;
869 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700870 //Irrespective whether the local is a MASTER or not for this device,
871 //create group handler instance and push default TTP flow rules.
872 //Because in a multi-instance setup, instances can initiate
873 //groups for any devices. Also the default TTP rules are needed
874 //to be pushed before inserting any IP table entries for any device
875 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
876 .deviceId());
877 if (groupHandler != null) {
Saurav Das8a0732e2015-11-20 15:27:53 -0800878 groupHandler.linkUp(link, mastershipService.isLocalMaster(
879 link.src().deviceId()));
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700880 } else {
881 Device device = deviceService.getDevice(link.src().deviceId());
882 if (device != null) {
883 log.warn("processLinkAdded: Link Added "
884 + "Notification without Device Added "
885 + "event, still handling it");
886 processDeviceAdded(device);
887 groupHandler = groupHandlerMap.get(link.src()
888 .deviceId());
Saurav Das8a0732e2015-11-20 15:27:53 -0800889 groupHandler.linkUp(link, mastershipService.isLocalMaster(device.id()));
sanghob35a6192015-04-01 13:05:26 -0700890 }
891 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700892
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700893 log.trace("Starting optimized route population process");
894 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
895 //log.trace("processLinkAdded: re-starting route population process");
896 //defaultRoutingHandler.startPopulationProcess();
Charles Chan2199c302016-04-23 17:36:10 -0700897
898 mcastHandler.init();
sanghob35a6192015-04-01 13:05:26 -0700899 }
900
901 private void processLinkRemoved(Link link) {
Saurav Dasb5c236e2016-06-07 10:08:06 -0700902 log.info("** LINK REMOVED {}", link.toString());
sangho834e4b02015-05-01 09:38:25 -0700903 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId());
904 if (groupHandler != null) {
Saurav Das423fe2b2015-12-04 10:52:59 -0800905 groupHandler.portDown(link.src().port(),
906 mastershipService.isLocalMaster(link.src().deviceId()));
sangho834e4b02015-05-01 09:38:25 -0700907 }
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700908 log.trace("Starting optimized route population process");
909 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
910 //log.trace("processLinkRemoved: re-starting route population process");
911 //defaultRoutingHandler.startPopulationProcess();
Charles Chan2199c302016-04-23 17:36:10 -0700912
913 mcastHandler.processLinkDown(link);
sanghob35a6192015-04-01 13:05:26 -0700914 }
915
916 private void processDeviceAdded(Device device) {
Saurav Dasb5c236e2016-06-07 10:08:06 -0700917 log.info("** DEVICE ADDED with ID {}", device.id());
Charles Chan0b4e6182015-11-03 10:42:14 -0800918 if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
Saurav Das2857f382015-11-03 14:39:27 -0800919 log.warn("Device configuration uploading. Device {} will be "
920 + "processed after config completes.", device.id());
921 return;
922 }
Charles Chan2199c302016-04-23 17:36:10 -0700923 processDeviceAddedInternal(device.id());
924 }
925
926 private void processDeviceAddedInternal(DeviceId deviceId) {
Saurav Das837e0bb2015-10-30 17:45:38 -0700927 // Irrespective of whether the local is a MASTER or not for this device,
928 // we need to create a SR-group-handler instance. This is because in a
929 // multi-instance setup, any instance can initiate forwarding/next-objectives
930 // for any switch (even if this instance is a SLAVE or not even connected
931 // to the switch). To handle this, a default-group-handler instance is necessary
932 // per switch.
Charles Chan2199c302016-04-23 17:36:10 -0700933 log.debug("Current groupHandlerMap devs: {}", groupHandlerMap.keySet());
934 if (groupHandlerMap.get(deviceId) == null) {
Charles Chan0b4e6182015-11-03 10:42:14 -0800935 DefaultGroupHandler groupHandler;
936 try {
937 groupHandler = DefaultGroupHandler.
Charles Chan2199c302016-04-23 17:36:10 -0700938 createGroupHandler(deviceId,
939 appId,
940 deviceConfiguration,
941 linkService,
942 flowObjectiveService,
943 this);
Charles Chan0b4e6182015-11-03 10:42:14 -0800944 } catch (DeviceConfigNotFoundException e) {
945 log.warn(e.getMessage() + " Aborting processDeviceAdded.");
946 return;
947 }
Charles Chan2199c302016-04-23 17:36:10 -0700948 log.debug("updating groupHandlerMap with new config for device: {}",
949 deviceId);
950 groupHandlerMap.put(deviceId, groupHandler);
Saurav Das2857f382015-11-03 14:39:27 -0800951 }
Saurav Dasb5c236e2016-06-07 10:08:06 -0700952
Charles Chan2199c302016-04-23 17:36:10 -0700953 if (mastershipService.isLocalMaster(deviceId)) {
Saurav Das018605f2017-02-18 14:05:44 -0800954 defaultRoutingHandler.populatePortAddressingRules(deviceId);
Charles Chan03a73e02016-10-24 14:52:01 -0700955 hostHandler.init(deviceId);
Charles Chanfc5c7802016-05-17 13:13:55 -0700956 xConnectHandler.init(deviceId);
Charles Chan35fd1a72016-06-13 18:54:31 -0700957 cordConfigHandler.init(deviceId);
Charles Chan2199c302016-04-23 17:36:10 -0700958 DefaultGroupHandler groupHandler = groupHandlerMap.get(deviceId);
Charles Chan59cc16d2017-02-02 16:20:42 -0800959 groupHandler.createGroupsFromVlanConfig();
Charles Chan2199c302016-04-23 17:36:10 -0700960 routingRulePopulator.populateSubnetBroadcastRule(deviceId);
Charles Chanc42e84e2015-10-20 16:24:19 -0700961 }
Charles Chan5270ed02016-01-30 23:22:37 -0800962
Charles Chan03a73e02016-10-24 14:52:01 -0700963 appCfgHandler.init(deviceId);
964 routeHandler.init(deviceId);
sanghob35a6192015-04-01 13:05:26 -0700965 }
966
Saurav Das80980c72016-03-23 11:22:49 -0700967 private void processDeviceRemoved(Device device) {
968 nsNextObjStore.entrySet().stream()
969 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
970 .forEach(entry -> {
971 nsNextObjStore.remove(entry.getKey());
972 });
Charles Chan59cc16d2017-02-02 16:20:42 -0800973 vlanNextObjStore.entrySet().stream()
Saurav Das80980c72016-03-23 11:22:49 -0700974 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
975 .forEach(entry -> {
Charles Chan59cc16d2017-02-02 16:20:42 -0800976 vlanNextObjStore.remove(entry.getKey());
Saurav Das80980c72016-03-23 11:22:49 -0700977 });
Saurav Das80980c72016-03-23 11:22:49 -0700978 portNextObjStore.entrySet().stream()
979 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
980 .forEach(entry -> {
981 portNextObjStore.remove(entry.getKey());
982 });
Saurav Das80980c72016-03-23 11:22:49 -0700983 groupHandlerMap.remove(device.id());
Saurav Das80980c72016-03-23 11:22:49 -0700984 defaultRoutingHandler.purgeEcmpGraph(device.id());
Charles Chan2199c302016-04-23 17:36:10 -0700985 mcastHandler.removeDevice(device.id());
Charles Chanfc5c7802016-05-17 13:13:55 -0700986 xConnectHandler.removeDevice(device.id());
Saurav Das80980c72016-03-23 11:22:49 -0700987 }
988
Saurav Das1a129a02016-11-18 15:21:57 -0800989 private void processPortUpdated(Device device, Port port) {
990 if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
991 log.warn("Device configuration uploading. Not handling port event for"
992 + "dev: {} port: {}", device.id(), port.number());
993 return;
994 }
Saurav Das018605f2017-02-18 14:05:44 -0800995
996 if (!mastershipService.isLocalMaster(device.id())) {
997 log.debug("Not master for dev:{} .. not handling port updated event"
998 + "for port {}", device.id(), port.number());
999 return;
1000 }
1001
1002 // first we handle filtering rules associated with the port
1003 if (port.isEnabled()) {
1004 log.info("Switchport {}/{} enabled..programming filters",
1005 device.id(), port.number());
Charles Chan7e4f8192017-02-26 22:59:35 -08001006 routingRulePopulator.processSinglePortFilters(device.id(), port.number(), true);
Saurav Das018605f2017-02-18 14:05:44 -08001007 } else {
1008 log.info("Switchport {}/{} disabled..removing filters",
1009 device.id(), port.number());
Charles Chan7e4f8192017-02-26 22:59:35 -08001010 routingRulePopulator.processSinglePortFilters(device.id(), port.number(), false);
Saurav Das018605f2017-02-18 14:05:44 -08001011 }
Saurav Das1a129a02016-11-18 15:21:57 -08001012
1013 // portUpdated calls are for ports that have gone down or up. For switch
1014 // to switch ports, link-events should take care of any re-routing or
1015 // group editing necessary for port up/down. Here we only process edge ports
1016 // that are already configured.
Charles Chan59cc16d2017-02-02 16:20:42 -08001017 VlanId untaggedVlan = getUntaggedVlanId(new ConnectPoint(device.id(), port.number()));
1018 VlanId vlanId = (untaggedVlan != null) ? untaggedVlan : INTERNAL_VLAN;
1019
1020 if (vlanId.equals(INTERNAL_VLAN)) {
Saurav Das1a129a02016-11-18 15:21:57 -08001021 log.debug("Not handling port updated event for unconfigured port "
1022 + "dev/port: {}/{}", device.id(), port.number());
1023 return;
1024 }
Charles Chan59cc16d2017-02-02 16:20:42 -08001025 processEdgePort(device, port, vlanId);
Saurav Das1a129a02016-11-18 15:21:57 -08001026 }
1027
Charles Chan59cc16d2017-02-02 16:20:42 -08001028 private void processEdgePort(Device device, Port port, VlanId vlanId) {
Saurav Das1a129a02016-11-18 15:21:57 -08001029 boolean portUp = port.isEnabled();
1030 if (portUp) {
1031 log.info("Device:EdgePort {}:{} is enabled in subnet: {}", device.id(),
Charles Chan59cc16d2017-02-02 16:20:42 -08001032 port.number(), vlanId);
Saurav Das1a129a02016-11-18 15:21:57 -08001033 } else {
1034 log.info("Device:EdgePort {}:{} is disabled in subnet: {}", device.id(),
Charles Chan59cc16d2017-02-02 16:20:42 -08001035 port.number(), vlanId);
Saurav Das1a129a02016-11-18 15:21:57 -08001036 }
1037
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -07001038 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
sanghob35a6192015-04-01 13:05:26 -07001039 if (groupHandler != null) {
Charles Chan59cc16d2017-02-02 16:20:42 -08001040 groupHandler.processEdgePort(port.number(), vlanId, portUp);
Saurav Das1a129a02016-11-18 15:21:57 -08001041 } else {
1042 log.warn("Group handler not found for dev:{}. Not handling edge port"
1043 + " {} event for port:{}", device.id(),
1044 (portUp) ? "UP" : "DOWN", port.number());
sanghob35a6192015-04-01 13:05:26 -07001045 }
1046 }
sangho1e575652015-05-14 00:39:53 -07001047
Pier Ventre10bd8d12016-11-26 21:05:22 -08001048 /**
1049 * Registers the given connect point with the NRS, this is necessary
1050 * to receive the NDP and ARP packets from the NRS.
1051 *
1052 * @param portToRegister connect point to register
1053 */
1054 public void registerConnectPoint(ConnectPoint portToRegister) {
Charles Chan0aa674e2017-02-23 15:44:08 -08001055 neighbourResolutionService.registerNeighbourHandler(
Pier Ventre10bd8d12016-11-26 21:05:22 -08001056 portToRegister,
1057 neighbourHandler,
1058 appId
1059 );
1060 }
1061
Charles Chand6832882015-10-05 17:50:33 -07001062 private class InternalConfigListener implements NetworkConfigListener {
Charles Chan2c15aca2016-11-09 20:51:44 -08001063 SegmentRoutingManager srManager;
Charles Chan4636be02015-10-07 14:21:45 -07001064
Charles Chane849c192016-01-11 18:28:54 -08001065 /**
1066 * Constructs the internal network config listener.
1067 *
Charles Chan2c15aca2016-11-09 20:51:44 -08001068 * @param srManager segment routing manager
Charles Chane849c192016-01-11 18:28:54 -08001069 */
Charles Chan2c15aca2016-11-09 20:51:44 -08001070 public InternalConfigListener(SegmentRoutingManager srManager) {
1071 this.srManager = srManager;
Charles Chan4636be02015-10-07 14:21:45 -07001072 }
1073
Charles Chane849c192016-01-11 18:28:54 -08001074 /**
1075 * Reads network config and initializes related data structure accordingly.
1076 */
Charles Chan4636be02015-10-07 14:21:45 -07001077 public void configureNetwork() {
Pier Ventre10bd8d12016-11-26 21:05:22 -08001078
Charles Chan2c15aca2016-11-09 20:51:44 -08001079 deviceConfiguration = new DeviceConfiguration(srManager);
Charles Chan4636be02015-10-07 14:21:45 -07001080
Charles Chan2c15aca2016-11-09 20:51:44 -08001081 arpHandler = new ArpHandler(srManager);
1082 icmpHandler = new IcmpHandler(srManager);
1083 ipHandler = new IpHandler(srManager);
1084 routingRulePopulator = new RoutingRulePopulator(srManager);
1085 defaultRoutingHandler = new DefaultRoutingHandler(srManager);
Charles Chan4636be02015-10-07 14:21:45 -07001086
1087 tunnelHandler = new TunnelHandler(linkService, deviceConfiguration,
1088 groupHandlerMap, tunnelStore);
1089 policyHandler = new PolicyHandler(appId, deviceConfiguration,
1090 flowObjectiveService,
1091 tunnelHandler, policyStore);
1092
Charles Chan4636be02015-10-07 14:21:45 -07001093 for (Device device : deviceService.getDevices()) {
Charles Chan2199c302016-04-23 17:36:10 -07001094 processDeviceAddedInternal(device.id());
Charles Chan4636be02015-10-07 14:21:45 -07001095 }
1096
1097 defaultRoutingHandler.startPopulationProcess();
Charles Chan2199c302016-04-23 17:36:10 -07001098 mcastHandler.init();
Charles Chan4636be02015-10-07 14:21:45 -07001099 }
1100
Charles Chand6832882015-10-05 17:50:33 -07001101 @Override
1102 public void event(NetworkConfigEvent event) {
Charles Chan5270ed02016-01-30 23:22:37 -08001103 // TODO move this part to NetworkConfigEventHandler
1104 if (event.configClass().equals(SegmentRoutingDeviceConfig.class)) {
1105 switch (event.type()) {
1106 case CONFIG_ADDED:
1107 log.info("Segment Routing Config added.");
1108 configureNetwork();
1109 break;
1110 case CONFIG_UPDATED:
1111 log.info("Segment Routing Config updated.");
1112 // TODO support dynamic configuration
1113 break;
1114 default:
1115 break;
Charles Chanb8e10c82015-10-14 11:24:40 -07001116 }
Charles Chan5270ed02016-01-30 23:22:37 -08001117 } else if (event.configClass().equals(SegmentRoutingAppConfig.class)) {
Charles Chanfc5c7802016-05-17 13:13:55 -07001118 checkState(appCfgHandler != null, "NetworkConfigEventHandler is not initialized");
Charles Chan5270ed02016-01-30 23:22:37 -08001119 switch (event.type()) {
1120 case CONFIG_ADDED:
Charles Chanfc5c7802016-05-17 13:13:55 -07001121 appCfgHandler.processAppConfigAdded(event);
Charles Chan5270ed02016-01-30 23:22:37 -08001122 break;
1123 case CONFIG_UPDATED:
Charles Chanfc5c7802016-05-17 13:13:55 -07001124 appCfgHandler.processAppConfigUpdated(event);
Charles Chan5270ed02016-01-30 23:22:37 -08001125 break;
1126 case CONFIG_REMOVED:
Charles Chanfc5c7802016-05-17 13:13:55 -07001127 appCfgHandler.processAppConfigRemoved(event);
1128 break;
1129 default:
1130 break;
1131 }
Charles Chan03a73e02016-10-24 14:52:01 -07001132 configureNetwork();
Charles Chanfc5c7802016-05-17 13:13:55 -07001133 } else if (event.configClass().equals(XConnectConfig.class)) {
1134 checkState(xConnectHandler != null, "XConnectHandler is not initialized");
1135 switch (event.type()) {
1136 case CONFIG_ADDED:
1137 xConnectHandler.processXConnectConfigAdded(event);
1138 break;
1139 case CONFIG_UPDATED:
1140 xConnectHandler.processXConnectConfigUpdated(event);
1141 break;
1142 case CONFIG_REMOVED:
1143 xConnectHandler.processXConnectConfigRemoved(event);
Charles Chan5270ed02016-01-30 23:22:37 -08001144 break;
1145 default:
1146 break;
Charles Chanb8e10c82015-10-14 11:24:40 -07001147 }
Pier Luigi7dad71c2017-02-01 13:50:04 -08001148 // XXX Neighbour hacking. This method is looking for
1149 // the Internet-Router interface. In order to retrieve
1150 // the upstream port.
1151 } else if (event.configClass().equals(InterfaceConfig.class)) {
1152 switch (event.type()) {
1153 case CONFIG_ADDED:
1154 case CONFIG_UPDATED:
Pier Luigi721b6622017-02-03 13:34:21 -08001155 updateUPstreamCP();
Pier Luigi7dad71c2017-02-01 13:50:04 -08001156 case CONFIG_REGISTERED:
1157 case CONFIG_UNREGISTERED:
1158 case CONFIG_REMOVED:
1159 break;
1160 default:
1161 break;
1162 }
1163 // XXX Neighbour hacking. This method is looking for
1164 // the vrouter port.
1165 } else if (event.configClass().equals(RouterConfig.class)) {
1166 switch (event.type()) {
1167 case CONFIG_ADDED:
1168 case CONFIG_UPDATED:
Pier Luigi721b6622017-02-03 13:34:21 -08001169 updateVRouterCP(event);
Pier Luigi7dad71c2017-02-01 13:50:04 -08001170 case CONFIG_REGISTERED:
1171 case CONFIG_UNREGISTERED:
1172 case CONFIG_REMOVED:
1173 break;
1174 default:
1175 break;
1176 }
Pier Ventref34966c2016-11-07 16:21:04 -08001177 } else if (event.configClass().equals(PwaasConfig.class)) {
1178 checkState(l2TunnelHandler != null, "L2TunnelHandler is not initialized");
1179 switch (event.type()) {
1180 case CONFIG_ADDED:
1181 l2TunnelHandler.processPwaasConfigAdded(event);
1182 break;
1183 case CONFIG_UPDATED:
1184 l2TunnelHandler.processPwaasConfigUpdated(event);
1185 break;
1186 case CONFIG_REMOVED:
1187 l2TunnelHandler.processPwaasConfigRemoved(event);
1188 break;
1189 default:
1190 break;
1191 }
Charles Chand6832882015-10-05 17:50:33 -07001192 }
1193 }
1194 }
Charles Chan68aa62d2015-11-09 16:37:23 -08001195
Pier Luigi721b6622017-02-03 13:34:21 -08001196 /////////////////////////////////////////////////////////////////
1197 // XXX Neighbour hacking, temporary workaround will be //
Saurav Das018605f2017-02-18 14:05:44 -08001198 // removed as soon as possible, when bridging based //
1199 // control plane redirect is implemented. //
Pier Luigi721b6622017-02-03 13:34:21 -08001200 /////////////////////////////////////////////////////////////////
1201
1202 // XXX Neighbour hacking. To store upstream connect
1203 // point and vRouter connect point
1204 ConnectPoint upstreamCP = null;
1205 ConnectPoint vRouterCP = null;
1206
1207 // XXX Neighbour hacking. To update the Upstream CP
1208 public void updateUPstreamCP() {
1209 Set<ConnectPoint> portSubjects = cfgService.getSubjects(ConnectPoint.class, InterfaceConfig.class);
1210 upstreamCP = null;
1211 portSubjects.stream().forEach(subject -> {
1212 InterfaceConfig config = cfgService.getConfig(subject, InterfaceConfig.class);
1213 Set<Interface> networkInterfaces;
1214 try {
1215 networkInterfaces = config.getInterfaces();
1216 } catch (ConfigException e) {
1217 log.error("Error loading port configuration");
1218 return;
1219 }
1220 networkInterfaces.forEach(networkInterface -> {
1221 if (networkInterface.name().equals("internet-router")) {
1222 upstreamCP = subject;
1223 }
1224 });
1225 });
1226
1227 }
1228
1229 // XXX Neighbour hacking. To update the Upstream CP
1230 public void updateVRouterCP(NetworkConfigEvent event) {
1231 RouterConfig config = (RouterConfig) event.config().get();
1232 if (config == null) {
1233 log.warn("Router config not available");
1234 vRouterCP = null;
1235 return;
1236 }
1237 vRouterCP = config.getControlPlaneConnectPoint();
1238 }
1239
Charles Chan68aa62d2015-11-09 16:37:23 -08001240 private class InternalHostListener implements HostListener {
Charles Chan68aa62d2015-11-09 16:37:23 -08001241 @Override
1242 public void event(HostEvent event) {
1243 // Do not proceed without mastership
1244 DeviceId deviceId = event.subject().location().deviceId();
1245 if (!mastershipService.isLocalMaster(deviceId)) {
1246 return;
1247 }
1248
1249 switch (event.type()) {
1250 case HOST_ADDED:
Charles Chand2990362016-04-18 13:44:03 -07001251 hostHandler.processHostAddedEvent(event);
Charles Chan68aa62d2015-11-09 16:37:23 -08001252 break;
1253 case HOST_MOVED:
Charles Chand2990362016-04-18 13:44:03 -07001254 hostHandler.processHostMovedEvent(event);
Charles Chan68aa62d2015-11-09 16:37:23 -08001255 break;
1256 case HOST_REMOVED:
Charles Chand2990362016-04-18 13:44:03 -07001257 hostHandler.processHostRemoveEvent(event);
Charles Chan68aa62d2015-11-09 16:37:23 -08001258 break;
1259 case HOST_UPDATED:
Charles Chand2990362016-04-18 13:44:03 -07001260 hostHandler.processHostUpdatedEvent(event);
Charles Chan68aa62d2015-11-09 16:37:23 -08001261 break;
1262 default:
1263 log.warn("Unsupported host event type: {}", event.type());
1264 break;
1265 }
1266 }
1267 }
1268
Charles Chand55e84d2016-03-30 17:54:24 -07001269 private class InternalMcastListener implements McastListener {
1270 @Override
1271 public void event(McastEvent event) {
1272 switch (event.type()) {
1273 case SOURCE_ADDED:
Charles Chand2990362016-04-18 13:44:03 -07001274 mcastHandler.processSourceAdded(event);
Charles Chand55e84d2016-03-30 17:54:24 -07001275 break;
1276 case SINK_ADDED:
Charles Chand2990362016-04-18 13:44:03 -07001277 mcastHandler.processSinkAdded(event);
Charles Chand55e84d2016-03-30 17:54:24 -07001278 break;
1279 case SINK_REMOVED:
Charles Chand2990362016-04-18 13:44:03 -07001280 mcastHandler.processSinkRemoved(event);
Charles Chand55e84d2016-03-30 17:54:24 -07001281 break;
1282 case ROUTE_ADDED:
1283 case ROUTE_REMOVED:
1284 default:
1285 break;
1286 }
1287 }
1288 }
Charles Chan35fd1a72016-06-13 18:54:31 -07001289
1290 private class InternalCordConfigListener implements CordConfigListener {
1291 @Override
1292 public void event(CordConfigEvent event) {
1293 switch (event.type()) {
1294 case ACCESS_AGENT_ADDED:
1295 cordConfigHandler.processAccessAgentAddedEvent(event);
1296 break;
1297 case ACCESS_AGENT_UPDATED:
1298 cordConfigHandler.processAccessAgentUpdatedEvent(event);
1299 break;
1300 case ACCESS_AGENT_REMOVED:
1301 cordConfigHandler.processAccessAgentRemovedEvent(event);
1302 break;
1303 case ACCESS_DEVICE_ADDED:
1304 case ACCESS_DEVICE_UPDATED:
1305 case ACCESS_DEVICE_REMOVED:
1306 default:
1307 break;
1308 }
1309 }
1310 }
Charles Chan03a73e02016-10-24 14:52:01 -07001311
1312 private class InternalRouteEventListener implements RouteListener {
1313 @Override
1314 public void event(RouteEvent event) {
1315 switch (event.type()) {
1316 case ROUTE_ADDED:
1317 routeHandler.processRouteAdded(event);
1318 break;
1319 case ROUTE_UPDATED:
1320 routeHandler.processRouteUpdated(event);
1321 break;
1322 case ROUTE_REMOVED:
1323 routeHandler.processRouteRemoved(event);
1324 break;
1325 default:
1326 break;
1327 }
1328 }
1329 }
sanghob35a6192015-04-01 13:05:26 -07001330}