blob: c783081cccd2742559f617baa8df0d6ad9b05afc [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;
Charles Chand55e84d2016-03-30 17:54:24 -070038import org.onosproject.incubator.net.config.basics.McastConfig;
Pier Luigi721b6622017-02-03 13:34:21 -080039import org.onosproject.incubator.net.intf.Interface;
Charles Chan2c15aca2016-11-09 20:51:44 -080040import org.onosproject.incubator.net.intf.InterfaceService;
Charles Chan03a73e02016-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 Ventre735b8c82016-12-02 08:16:05 -080044import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070045import org.onosproject.mastership.MastershipService;
Pier Ventre10bd8d12016-11-26 21:05:22 -080046import org.onosproject.net.ConnectPoint;
Jonathan Hartc19f7c12016-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 Chan68aa62d2015-11-09 16:37:23 -080051import org.onosproject.net.PortNumber;
Charles Chand6832882015-10-05 17:50:33 -070052import org.onosproject.net.config.ConfigFactory;
53import org.onosproject.net.config.NetworkConfigEvent;
Charles Chand6832882015-10-05 17:50:33 -070054import org.onosproject.net.config.NetworkConfigListener;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070055import org.onosproject.net.config.NetworkConfigRegistry;
Charles Chand6832882015-10-05 17:50:33 -070056import org.onosproject.net.config.basics.SubjectFactories;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070057import org.onosproject.net.device.DeviceEvent;
58import org.onosproject.net.device.DeviceListener;
59import org.onosproject.net.device.DeviceService;
Charles Chan68aa62d2015-11-09 16:37:23 -080060import org.onosproject.net.flow.TrafficSelector;
61import org.onosproject.net.flow.TrafficTreatment;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070062import org.onosproject.net.flowobjective.FlowObjectiveService;
Charles Chan68aa62d2015-11-09 16:37:23 -080063import org.onosproject.net.host.HostEvent;
64import org.onosproject.net.host.HostListener;
Pier Ventre10bd8d12016-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 Chand55e84d2016-03-30 17:54:24 -070069import org.onosproject.net.mcast.McastEvent;
70import org.onosproject.net.mcast.McastListener;
71import org.onosproject.net.mcast.MulticastRouteService;
Pier Ventre10bd8d12016-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 Ventre42287df2016-11-09 14:17:26 -080076import org.onosproject.net.topology.PathService;
Charles Chand55e84d2016-03-30 17:54:24 -070077import org.onosproject.net.topology.TopologyService;
78import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
79import org.onosproject.segmentrouting.config.DeviceConfiguration;
Pier Ventref34966c2016-11-07 16:21:04 -080080import org.onosproject.segmentrouting.config.PwaasConfig;
Pier Ventre10bd8d12016-11-26 21:05:22 -080081import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
Pier Ventref34966c2016-11-07 16:21:04 -080082import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
Charles Chanfc5c7802016-05-17 13:13:55 -070083import org.onosproject.segmentrouting.config.XConnectConfig;
Charles Chand55e84d2016-03-30 17:54:24 -070084import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
85import org.onosproject.segmentrouting.grouphandler.NeighborSet;
Charles Chand2990362016-04-18 13:44:03 -070086import org.onosproject.segmentrouting.storekey.NeighborSetNextObjectiveStoreKey;
87import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
Charles Chand2990362016-04-18 13:44:03 -070088import org.onosproject.segmentrouting.storekey.SubnetAssignedVidStoreKey;
Charles Chan59cc16d2017-02-02 16:20:42 -080089import org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey;
Charles Chanfc5c7802016-05-17 13:13:55 -070090import org.onosproject.segmentrouting.storekey.XConnectStoreKey;
Pier Ventref34966c2016-11-07 16:21:04 -080091import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
Jonathan Hartc19f7c12016-04-12 15:39:44 -070092import org.onosproject.store.serializers.KryoNamespaces;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070093import org.onosproject.store.service.EventuallyConsistentMap;
94import org.onosproject.store.service.EventuallyConsistentMapBuilder;
95import org.onosproject.store.service.StorageService;
96import org.onosproject.store.service.WallClockTimestamp;
sanghob35a6192015-04-01 13:05:26 -070097import org.slf4j.Logger;
98import org.slf4j.LoggerFactory;
99
sangho1e575652015-05-14 00:39:53 -0700100import java.util.List;
sanghob35a6192015-04-01 13:05:26 -0700101import java.util.Map;
Saurav Das0e99e2b2015-10-28 12:39:42 -0700102import java.util.Set;
sanghob35a6192015-04-01 13:05:26 -0700103import java.util.concurrent.ConcurrentHashMap;
104import java.util.concurrent.ConcurrentLinkedQueue;
105import java.util.concurrent.Executors;
106import java.util.concurrent.ScheduledExecutorService;
107import java.util.concurrent.ScheduledFuture;
108import java.util.concurrent.TimeUnit;
Charles Chan7ffd81f2017-02-08 15:52:08 -0800109import java.util.stream.Collectors;
sanghob35a6192015-04-01 13:05:26 -0700110
Charles Chan3e783d02016-02-26 22:19:52 -0800111import static com.google.common.base.Preconditions.checkState;
Pier Ventree0ae7a32016-11-23 09:57:42 -0800112import static org.onlab.packet.Ethernet.TYPE_ARP;
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700113import static org.onlab.util.Tools.groupedThreads;
Charles Chan3e783d02016-02-26 22:19:52 -0800114
Charles Chane849c192016-01-11 18:28:54 -0800115/**
116 * Segment routing manager.
117 */
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700118@Service
119@Component(immediate = true)
sangho1e575652015-05-14 00:39:53 -0700120public class SegmentRoutingManager implements SegmentRoutingService {
sanghob35a6192015-04-01 13:05:26 -0700121
Charles Chan2c15aca2016-11-09 20:51:44 -0800122 private static Logger log = LoggerFactory.getLogger(SegmentRoutingManager.class);
sanghob35a6192015-04-01 13:05:26 -0700123
124 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700125 private ComponentConfigService compCfgService;
sanghob35a6192015-04-01 13:05:26 -0700126
127 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre10bd8d12016-11-26 21:05:22 -0800128 private NeighbourResolutionService neighbourResolutionService;
129
130 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre42287df2016-11-09 14:17:26 -0800131 public PathService pathService;
132
133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700134 CoreService coreService;
sanghob35a6192015-04-01 13:05:26 -0700135
136 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700137 PacketService packetService;
sanghob35a6192015-04-01 13:05:26 -0700138
139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700140 HostService hostService;
sanghob35a6192015-04-01 13:05:26 -0700141
142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700143 DeviceService deviceService;
sanghob35a6192015-04-01 13:05:26 -0700144
145 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre42287df2016-11-09 14:17:26 -0800146 public FlowObjectiveService flowObjectiveService;
sanghob35a6192015-04-01 13:05:26 -0700147
148 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700149 LinkService linkService;
sangho1e575652015-05-14 00:39:53 -0700150
Charles Chan5270ed02016-01-30 23:22:37 -0800151 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre42287df2016-11-09 14:17:26 -0800152 public MastershipService mastershipService;
Charles Chan03a73e02016-10-24 14:52:01 -0700153
154 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pier Ventre42287df2016-11-09 14:17:26 -0800155 public StorageService storageService;
Charles Chan03a73e02016-10-24 14:52:01 -0700156
157 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
158 MulticastRouteService multicastRouteService;
159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
161 TopologyService topologyService;
162
163 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan03a73e02016-10-24 14:52:01 -0700164 RouteService routeService;
Charles Chan5270ed02016-01-30 23:22:37 -0800165
166 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan2c15aca2016-11-09 20:51:44 -0800167 public NetworkConfigRegistry cfgService;
Charles Chan5270ed02016-01-30 23:22:37 -0800168
Saurav Das80980c72016-03-23 11:22:49 -0700169 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Charles Chan2c15aca2016-11-09 20:51:44 -0800170 public InterfaceService interfaceService;
171
Charles Chan03a73e02016-10-24 14:52:01 -0700172 ArpHandler arpHandler = null;
173 IcmpHandler icmpHandler = null;
174 IpHandler ipHandler = null;
175 RoutingRulePopulator routingRulePopulator = null;
Ray Milkeye4afdb52017-04-05 09:42:04 -0700176 ApplicationId appId;
177 DeviceConfiguration deviceConfiguration = null;
sanghob35a6192015-04-01 13:05:26 -0700178
Charles Chan03a73e02016-10-24 14:52:01 -0700179 DefaultRoutingHandler defaultRoutingHandler = null;
sangho1e575652015-05-14 00:39:53 -0700180 private TunnelHandler tunnelHandler = null;
181 private PolicyHandler policyHandler = null;
Charles Chanb8e10c82015-10-14 11:24:40 -0700182 private InternalPacketProcessor processor = null;
183 private InternalLinkListener linkListener = null;
184 private InternalDeviceListener deviceListener = null;
Charles Chanfc5c7802016-05-17 13:13:55 -0700185 private AppConfigHandler appCfgHandler = null;
Charles Chan03a73e02016-10-24 14:52:01 -0700186 XConnectHandler xConnectHandler = null;
Charles Chand2990362016-04-18 13:44:03 -0700187 private McastHandler mcastHandler = null;
Charles Chan03a73e02016-10-24 14:52:01 -0700188 HostHandler hostHandler = null;
Pier Ventre10bd8d12016-11-26 21:05:22 -0800189 private RouteHandler routeHandler = null;
Pier Ventre735b8c82016-12-02 08:16:05 -0800190 private SegmentRoutingNeighbourDispatcher neighbourHandler = null;
Pier Ventref34966c2016-11-07 16:21:04 -0800191 private L2TunnelHandler l2TunnelHandler = null;
sanghob35a6192015-04-01 13:05:26 -0700192 private InternalEventHandler eventHandler = new InternalEventHandler();
Charles Chan5270ed02016-01-30 23:22:37 -0800193 private final InternalHostListener hostListener = new InternalHostListener();
Charles Chand55e84d2016-03-30 17:54:24 -0700194 private final InternalConfigListener cfgListener = new InternalConfigListener(this);
195 private final InternalMcastListener mcastListener = new InternalMcastListener();
Charles Chan03a73e02016-10-24 14:52:01 -0700196 private final InternalRouteEventListener routeListener = new InternalRouteEventListener();
sanghob35a6192015-04-01 13:05:26 -0700197
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700198 private ScheduledExecutorService executorService = Executors
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700199 .newScheduledThreadPool(1, groupedThreads("SegmentRoutingManager", "event-%d", log));
sanghob35a6192015-04-01 13:05:26 -0700200
Saurav Das4ce45962015-11-24 23:21:05 -0800201 @SuppressWarnings("unused")
sanghob35a6192015-04-01 13:05:26 -0700202 private static ScheduledFuture<?> eventHandlerFuture = null;
Saurav Das4ce45962015-11-24 23:21:05 -0800203 @SuppressWarnings("rawtypes")
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700204 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<>();
Charles Chan68aa62d2015-11-09 16:37:23 -0800205 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap =
Charles Chane849c192016-01-11 18:28:54 -0800206 new ConcurrentHashMap<>();
207 /**
208 * Per device next objective ID store with (device id + neighbor set) as key.
209 */
Ray Milkeye4afdb52017-04-05 09:42:04 -0700210 EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer>
Charles Chan68aa62d2015-11-09 16:37:23 -0800211 nsNextObjStore = null;
Charles Chane849c192016-01-11 18:28:54 -0800212 /**
213 * Per device next objective ID store with (device id + subnet) as key.
214 */
Ray Milkeye4afdb52017-04-05 09:42:04 -0700215 EventuallyConsistentMap<VlanNextObjectiveStoreKey, Integer>
Charles Chan59cc16d2017-02-02 16:20:42 -0800216 vlanNextObjStore = null;
Charles Chane849c192016-01-11 18:28:54 -0800217 /**
218 * Per device next objective ID store with (device id + port) as key.
219 */
Ray Milkeye4afdb52017-04-05 09:42:04 -0700220 EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer>
Saurav Das4ce45962015-11-24 23:21:05 -0800221 portNextObjStore = null;
Charles Chan59cc16d2017-02-02 16:20:42 -0800222
Saurav Das4ce45962015-11-24 23:21:05 -0800223 private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
224 private EventuallyConsistentMap<String, Policy> policyStore = null;
sangho0b2b6d12015-05-20 22:16:38 -0700225
Charles Chand55e84d2016-03-30 17:54:24 -0700226 private final ConfigFactory<DeviceId, SegmentRoutingDeviceConfig> deviceConfigFactory =
Charles Chanfc5c7802016-05-17 13:13:55 -0700227 new ConfigFactory<DeviceId, SegmentRoutingDeviceConfig>(
228 SubjectFactories.DEVICE_SUBJECT_FACTORY,
Charles Chand55e84d2016-03-30 17:54:24 -0700229 SegmentRoutingDeviceConfig.class, "segmentrouting") {
Charles Chand6832882015-10-05 17:50:33 -0700230 @Override
Charles Chan5270ed02016-01-30 23:22:37 -0800231 public SegmentRoutingDeviceConfig createConfig() {
232 return new SegmentRoutingDeviceConfig();
Charles Chand6832882015-10-05 17:50:33 -0700233 }
234 };
Pier Ventref34966c2016-11-07 16:21:04 -0800235
Charles Chand55e84d2016-03-30 17:54:24 -0700236 private final ConfigFactory<ApplicationId, SegmentRoutingAppConfig> appConfigFactory =
Charles Chanfc5c7802016-05-17 13:13:55 -0700237 new ConfigFactory<ApplicationId, SegmentRoutingAppConfig>(
238 SubjectFactories.APP_SUBJECT_FACTORY,
Charles Chand55e84d2016-03-30 17:54:24 -0700239 SegmentRoutingAppConfig.class, "segmentrouting") {
Charles Chan5270ed02016-01-30 23:22:37 -0800240 @Override
241 public SegmentRoutingAppConfig createConfig() {
242 return new SegmentRoutingAppConfig();
243 }
244 };
Pier Ventref34966c2016-11-07 16:21:04 -0800245
Charles Chanfc5c7802016-05-17 13:13:55 -0700246 private final ConfigFactory<ApplicationId, XConnectConfig> xConnectConfigFactory =
247 new ConfigFactory<ApplicationId, XConnectConfig>(
248 SubjectFactories.APP_SUBJECT_FACTORY,
249 XConnectConfig.class, "xconnect") {
250 @Override
251 public XConnectConfig createConfig() {
252 return new XConnectConfig();
253 }
254 };
Pier Ventref34966c2016-11-07 16:21:04 -0800255
Charles Chand55e84d2016-03-30 17:54:24 -0700256 private ConfigFactory<ApplicationId, McastConfig> mcastConfigFactory =
Charles Chanfc5c7802016-05-17 13:13:55 -0700257 new ConfigFactory<ApplicationId, McastConfig>(
258 SubjectFactories.APP_SUBJECT_FACTORY,
Charles Chand55e84d2016-03-30 17:54:24 -0700259 McastConfig.class, "multicast") {
260 @Override
261 public McastConfig createConfig() {
262 return new McastConfig();
263 }
264 };
265
Pier Ventref34966c2016-11-07 16:21:04 -0800266 private final ConfigFactory<ApplicationId, PwaasConfig> pwaasConfigFactory =
267 new ConfigFactory<ApplicationId, PwaasConfig>(
268 SubjectFactories.APP_SUBJECT_FACTORY,
269 PwaasConfig.class, "pwaas") {
270 @Override
271 public PwaasConfig createConfig() {
272 return new PwaasConfig();
273 }
274 };
275
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700276 private Object threadSchedulerLock = new Object();
277 private static int numOfEventsQueued = 0;
278 private static int numOfEventsExecuted = 0;
sanghob35a6192015-04-01 13:05:26 -0700279 private static int numOfHandlerExecution = 0;
280 private static int numOfHandlerScheduled = 0;
281
Charles Chan116188d2016-02-18 14:22:42 -0800282 /**
283 * Segment Routing App ID.
284 */
Charles Chan2c15aca2016-11-09 20:51:44 -0800285 public static final String APP_NAME = "org.onosproject.segmentrouting";
Charles Chan59cc16d2017-02-02 16:20:42 -0800286
Charles Chane849c192016-01-11 18:28:54 -0800287 /**
288 * The default VLAN ID assigned to the interfaces without subnet config.
289 */
Charles Chan59cc16d2017-02-02 16:20:42 -0800290 public static final VlanId INTERNAL_VLAN = VlanId.vlanId((short) 4094);
Saurav Das0e99e2b2015-10-28 12:39:42 -0700291
sanghob35a6192015-04-01 13:05:26 -0700292 @Activate
293 protected void activate() {
Charles Chan2c15aca2016-11-09 20:51:44 -0800294 appId = coreService.registerApplication(APP_NAME);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700295
296 log.debug("Creating EC map nsnextobjectivestore");
297 EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
298 nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700299 nsNextObjStore = nsNextObjMapBuilder
300 .withName("nsnextobjectivestore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700301 .withSerializer(createSerializer())
Madan Jampanibcf1a482015-06-24 19:05:56 -0700302 .withTimestampProvider((k, v) -> new WallClockTimestamp())
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700303 .build();
304 log.trace("Current size {}", nsNextObjStore.size());
305
Charles Chan59cc16d2017-02-02 16:20:42 -0800306 log.debug("Creating EC map vlannextobjectivestore");
307 EventuallyConsistentMapBuilder<VlanNextObjectiveStoreKey, Integer>
308 vlanNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
309 vlanNextObjStore = vlanNextObjMapBuilder
310 .withName("vlannextobjectivestore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700311 .withSerializer(createSerializer())
Charles Chanc42e84e2015-10-20 16:24:19 -0700312 .withTimestampProvider((k, v) -> new WallClockTimestamp())
313 .build();
314
Saurav Das4ce45962015-11-24 23:21:05 -0800315 log.debug("Creating EC map subnetnextobjectivestore");
316 EventuallyConsistentMapBuilder<PortNextObjectiveStoreKey, Integer>
317 portNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
318 portNextObjStore = portNextObjMapBuilder
319 .withName("portnextobjectivestore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700320 .withSerializer(createSerializer())
Saurav Das4ce45962015-11-24 23:21:05 -0800321 .withTimestampProvider((k, v) -> new WallClockTimestamp())
322 .build();
323
sangho0b2b6d12015-05-20 22:16:38 -0700324 EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
325 storageService.eventuallyConsistentMapBuilder();
sangho0b2b6d12015-05-20 22:16:38 -0700326 tunnelStore = tunnelMapBuilder
327 .withName("tunnelstore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700328 .withSerializer(createSerializer())
Madan Jampanibcf1a482015-06-24 19:05:56 -0700329 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho0b2b6d12015-05-20 22:16:38 -0700330 .build();
331
332 EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
333 storageService.eventuallyConsistentMapBuilder();
sangho0b2b6d12015-05-20 22:16:38 -0700334 policyStore = policyMapBuilder
335 .withName("policystore")
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700336 .withSerializer(createSerializer())
Madan Jampanibcf1a482015-06-24 19:05:56 -0700337 .withTimestampProvider((k, v) -> new WallClockTimestamp())
sangho0b2b6d12015-05-20 22:16:38 -0700338 .build();
339
Saurav Das80980c72016-03-23 11:22:49 -0700340 compCfgService.preSetProperty("org.onosproject.net.group.impl.GroupManager",
Pier Luigi9e5c5ca2017-01-12 18:14:58 -0800341 "purgeOnDisconnection", "true");
Saurav Das80980c72016-03-23 11:22:49 -0700342 compCfgService.preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
Pier Luigi9e5c5ca2017-01-12 18:14:58 -0800343 "purgeOnDisconnection", "true");
Pier Luigi9e5c5ca2017-01-12 18:14:58 -0800344 compCfgService.preSetProperty("org.onosproject.provider.host.impl.HostLocationProvider",
345 "requestInterceptsEnabled", "false");
Pier Luigi7e415132017-01-12 22:46:39 -0800346 compCfgService.preSetProperty("org.onosproject.incubator.net.neighbour.impl.NeighbourResolutionManager",
347 "requestInterceptsEnabled", "false");
348 compCfgService.preSetProperty("org.onosproject.dhcprelay.DhcpRelay",
349 "arpEnabled", "false");
Pier Luigi9b1d6262017-02-02 22:31:34 -0800350 compCfgService.preSetProperty("org.onosproject.net.host.impl.HostManager",
351 "greedyLearningIpv6", "true");
Charles Chanc6d227e2017-02-28 15:15:17 -0800352 compCfgService.preSetProperty("org.onosproject.routing.cpr.ControlPlaneRedirectManager",
353 "forceUnprovision", "true");
Saurav Das80980c72016-03-23 11:22:49 -0700354
Charles Chanb8e10c82015-10-14 11:24:40 -0700355 processor = new InternalPacketProcessor();
356 linkListener = new InternalLinkListener();
357 deviceListener = new InternalDeviceListener();
Charles Chanfc5c7802016-05-17 13:13:55 -0700358 appCfgHandler = new AppConfigHandler(this);
359 xConnectHandler = new XConnectHandler(this);
Charles Chand2990362016-04-18 13:44:03 -0700360 mcastHandler = new McastHandler(this);
361 hostHandler = new HostHandler(this);
Charles Chan03a73e02016-10-24 14:52:01 -0700362 routeHandler = new RouteHandler(this);
Pier Ventre735b8c82016-12-02 08:16:05 -0800363 neighbourHandler = new SegmentRoutingNeighbourDispatcher(this);
Pier Ventref34966c2016-11-07 16:21:04 -0800364 l2TunnelHandler = new L2TunnelHandler(this);
Charles Chanb8e10c82015-10-14 11:24:40 -0700365
Charles Chan3e783d02016-02-26 22:19:52 -0800366 cfgService.addListener(cfgListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700367 cfgService.registerConfigFactory(deviceConfigFactory);
368 cfgService.registerConfigFactory(appConfigFactory);
Charles Chanfc5c7802016-05-17 13:13:55 -0700369 cfgService.registerConfigFactory(xConnectConfigFactory);
Charles Chand55e84d2016-03-30 17:54:24 -0700370 cfgService.registerConfigFactory(mcastConfigFactory);
Pier Ventref34966c2016-11-07 16:21:04 -0800371 cfgService.registerConfigFactory(pwaasConfigFactory);
Charles Chan5270ed02016-01-30 23:22:37 -0800372 hostService.addListener(hostListener);
Charles Chanb8e10c82015-10-14 11:24:40 -0700373 packetService.addProcessor(processor, PacketProcessor.director(2));
374 linkService.addListener(linkListener);
375 deviceService.addListener(deviceListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700376 multicastRouteService.addListener(mcastListener);
Charles Chanb8e10c82015-10-14 11:24:40 -0700377
378 cfgListener.configureNetwork();
379
Charles Chan03a73e02016-10-24 14:52:01 -0700380 routeService.addListener(routeListener);
381
sanghob35a6192015-04-01 13:05:26 -0700382 log.info("Started");
383 }
384
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700385 private KryoNamespace.Builder createSerializer() {
386 return new KryoNamespace.Builder()
387 .register(KryoNamespaces.API)
388 .register(NeighborSetNextObjectiveStoreKey.class,
Charles Chan59cc16d2017-02-02 16:20:42 -0800389 VlanNextObjectiveStoreKey.class,
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700390 SubnetAssignedVidStoreKey.class,
391 NeighborSet.class,
392 Tunnel.class,
393 DefaultTunnel.class,
394 Policy.class,
395 TunnelPolicy.class,
396 Policy.Type.class,
397 PortNextObjectiveStoreKey.class,
Charles Chanfc5c7802016-05-17 13:13:55 -0700398 XConnectStoreKey.class
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700399 );
400 }
401
sanghob35a6192015-04-01 13:05:26 -0700402 @Deactivate
403 protected void deactivate() {
Charles Chand6832882015-10-05 17:50:33 -0700404 cfgService.removeListener(cfgListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700405 cfgService.unregisterConfigFactory(deviceConfigFactory);
406 cfgService.unregisterConfigFactory(appConfigFactory);
Charles Chan03a73e02016-10-24 14:52:01 -0700407 cfgService.unregisterConfigFactory(xConnectConfigFactory);
Charles Chand55e84d2016-03-30 17:54:24 -0700408 cfgService.unregisterConfigFactory(mcastConfigFactory);
Pier Ventref34966c2016-11-07 16:21:04 -0800409 cfgService.unregisterConfigFactory(pwaasConfigFactory);
Charles Chand6832882015-10-05 17:50:33 -0700410
sanghob35a6192015-04-01 13:05:26 -0700411 packetService.removeProcessor(processor);
Charles Chanb8e10c82015-10-14 11:24:40 -0700412 linkService.removeListener(linkListener);
413 deviceService.removeListener(deviceListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700414 multicastRouteService.removeListener(mcastListener);
Charles Chan03a73e02016-10-24 14:52:01 -0700415 routeService.removeListener(routeListener);
Charles Chand55e84d2016-03-30 17:54:24 -0700416
Charles Chan0aa674e2017-02-23 15:44:08 -0800417 neighbourResolutionService.unregisterNeighbourHandlers(appId);
418
sanghob35a6192015-04-01 13:05:26 -0700419 processor = null;
Charles Chanb8e10c82015-10-14 11:24:40 -0700420 linkListener = null;
Charles Chand55e84d2016-03-30 17:54:24 -0700421 deviceListener = null;
Charles Chanb8e10c82015-10-14 11:24:40 -0700422 groupHandlerMap.clear();
423
Charles Chand55e84d2016-03-30 17:54:24 -0700424 nsNextObjStore.destroy();
Charles Chan59cc16d2017-02-02 16:20:42 -0800425 vlanNextObjStore.destroy();
Charles Chand55e84d2016-03-30 17:54:24 -0700426 portNextObjStore.destroy();
Charles Chand55e84d2016-03-30 17:54:24 -0700427 tunnelStore.destroy();
428 policyStore.destroy();
sanghob35a6192015-04-01 13:05:26 -0700429 log.info("Stopped");
430 }
431
sangho1e575652015-05-14 00:39:53 -0700432 @Override
433 public List<Tunnel> getTunnels() {
434 return tunnelHandler.getTunnels();
435 }
436
437 @Override
sangho71abe1b2015-06-29 14:58:47 -0700438 public TunnelHandler.Result createTunnel(Tunnel tunnel) {
439 return tunnelHandler.createTunnel(tunnel);
sangho1e575652015-05-14 00:39:53 -0700440 }
441
442 @Override
sangho71abe1b2015-06-29 14:58:47 -0700443 public TunnelHandler.Result removeTunnel(Tunnel tunnel) {
sangho1e575652015-05-14 00:39:53 -0700444 for (Policy policy: policyHandler.getPolicies()) {
445 if (policy.type() == Policy.Type.TUNNEL_FLOW) {
446 TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
447 if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
448 log.warn("Cannot remove the tunnel used by a policy");
sangho71abe1b2015-06-29 14:58:47 -0700449 return TunnelHandler.Result.TUNNEL_IN_USE;
sangho1e575652015-05-14 00:39:53 -0700450 }
451 }
452 }
sangho71abe1b2015-06-29 14:58:47 -0700453 return tunnelHandler.removeTunnel(tunnel);
sangho1e575652015-05-14 00:39:53 -0700454 }
455
456 @Override
sangho71abe1b2015-06-29 14:58:47 -0700457 public PolicyHandler.Result removePolicy(Policy policy) {
458 return policyHandler.removePolicy(policy);
sangho1e575652015-05-14 00:39:53 -0700459 }
460
461 @Override
sangho71abe1b2015-06-29 14:58:47 -0700462 public PolicyHandler.Result createPolicy(Policy policy) {
463 return policyHandler.createPolicy(policy);
sangho1e575652015-05-14 00:39:53 -0700464 }
465
466 @Override
467 public List<Policy> getPolicies() {
468 return policyHandler.getPolicies();
469 }
470
Saurav Das59232cf2016-04-27 18:35:50 -0700471 @Override
472 public void rerouteNetwork() {
473 cfgListener.configureNetwork();
474 for (Device device : deviceService.getDevices()) {
Saurav Das018605f2017-02-18 14:05:44 -0800475 if (mastershipService.isLocalMaster(device.id())) {
476 defaultRoutingHandler.populatePortAddressingRules(device.id());
477 }
Saurav Das59232cf2016-04-27 18:35:50 -0700478 }
479 defaultRoutingHandler.startPopulationProcess();
480 }
481
Charles Chanc81c45b2016-10-20 17:02:44 -0700482 @Override
Pier Ventre10bd8d12016-11-26 21:05:22 -0800483 public Map<DeviceId, Set<IpPrefix>> getDeviceSubnetMap() {
484 Map<DeviceId, Set<IpPrefix>> deviceSubnetMap = Maps.newHashMap();
Charles Chanc81c45b2016-10-20 17:02:44 -0700485 deviceService.getAvailableDevices().forEach(device -> {
486 deviceSubnetMap.put(device.id(), deviceConfiguration.getSubnets(device.id()));
487 });
488 return deviceSubnetMap;
489 }
490
sanghof9d0bf12015-05-19 11:57:42 -0700491 /**
Ray Milkeye4afdb52017-04-05 09:42:04 -0700492 * Extracts the application ID from the manager.
493 *
494 * @return application ID
495 */
496 public ApplicationId appId() {
497 return appId;
498 }
499
500 /**
501 * Returns the device configuration.
502 *
503 * @return device configuration
504 */
505 public DeviceConfiguration deviceConfiguration() {
506 return deviceConfiguration;
507 }
508
509 /**
510 * Per device next objective ID store with (device id + neighbor set) as key.
511 *
512 * @return next objective ID store
513 */
514 public EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore() {
515 return nsNextObjStore;
516 }
517
518 /**
519 * Per device next objective ID store with (device id + subnet) as key.
520 *
521 * @return vlan next object store
522 */
523 public EventuallyConsistentMap<VlanNextObjectiveStoreKey, Integer> vlanNextObjStore() {
524 return vlanNextObjStore;
525 }
526
527 /**
528 * Per device next objective ID store with (device id + port) as key.
529 *
530 * @return port next object store.
531 */
532 public EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer> portNextObjStore() {
533 return portNextObjStore;
534 }
535
536 /**
Pier Ventre98161782016-10-31 15:00:01 -0700537 * Returns the MPLS-ECMP configuration.
538 *
539 * @return MPLS-ECMP value
540 */
541 public boolean getMplsEcmp() {
542 SegmentRoutingAppConfig segmentRoutingAppConfig = cfgService
543 .getConfig(this.appId, SegmentRoutingAppConfig.class);
544 return segmentRoutingAppConfig != null && segmentRoutingAppConfig.mplsEcmp();
545 }
546
547 /**
sanghof9d0bf12015-05-19 11:57:42 -0700548 * Returns the tunnel object with the tunnel ID.
549 *
550 * @param tunnelId Tunnel ID
551 * @return Tunnel reference
552 */
sangho1e575652015-05-14 00:39:53 -0700553 public Tunnel getTunnel(String tunnelId) {
554 return tunnelHandler.getTunnel(tunnelId);
555 }
556
Charles Chan7ffd81f2017-02-08 15:52:08 -0800557 // TODO Consider moving these to InterfaceService
sanghob35a6192015-04-01 13:05:26 -0700558 /**
Charles Chan59cc16d2017-02-02 16:20:42 -0800559 * Returns untagged VLAN configured on given connect point.
Charles Chan7ffd81f2017-02-08 15:52:08 -0800560 * <p>
561 * Only returns the first match if there are multiple untagged VLAN configured
562 * on the connect point.
sanghob35a6192015-04-01 13:05:26 -0700563 *
Charles Chan59cc16d2017-02-02 16:20:42 -0800564 * @param connectPoint connect point
565 * @return untagged VLAN or null if not configured
sanghob35a6192015-04-01 13:05:26 -0700566 */
Charles Chan59cc16d2017-02-02 16:20:42 -0800567 public VlanId getUntaggedVlanId(ConnectPoint connectPoint) {
568 return interfaceService.getInterfacesByPort(connectPoint).stream()
569 .filter(intf -> !intf.vlanUntagged().equals(VlanId.NONE))
570 .map(Interface::vlanUntagged)
571 .findFirst().orElse(null);
sanghob35a6192015-04-01 13:05:26 -0700572 }
573
sangho1e575652015-05-14 00:39:53 -0700574 /**
Charles Chan7ffd81f2017-02-08 15:52:08 -0800575 * Returns tagged VLAN configured on given connect point.
576 * <p>
577 * Returns all matches if there are multiple tagged VLAN configured
578 * on the connect point.
579 *
580 * @param connectPoint connect point
581 * @return tagged VLAN or empty set if not configured
582 */
583 public Set<VlanId> getTaggedVlanId(ConnectPoint connectPoint) {
584 Set<Interface> interfaces = interfaceService.getInterfacesByPort(connectPoint);
585 return interfaces.stream()
586 .map(Interface::vlanTagged)
587 .flatMap(vlanIds -> vlanIds.stream())
588 .collect(Collectors.toSet());
589 }
590
591 /**
592 * Returns native VLAN configured on given connect point.
593 * <p>
594 * Only returns the first match if there are multiple native VLAN configured
595 * on the connect point.
596 *
597 * @param connectPoint connect point
598 * @return native VLAN or null if not configured
599 */
600 public VlanId getNativeVlanId(ConnectPoint connectPoint) {
601 Set<Interface> interfaces = interfaceService.getInterfacesByPort(connectPoint);
602 return interfaces.stream()
603 .filter(intf -> !intf.vlanNative().equals(VlanId.NONE))
604 .map(Interface::vlanNative)
605 .findFirst()
606 .orElse(null);
607 }
608
609 /**
610 * Returns vlan port map of given device.
611 *
612 * @param deviceId device id
613 * @return vlan-port multimap
614 */
615 public Multimap<VlanId, PortNumber> getVlanPortMap(DeviceId deviceId) {
616 HashMultimap<VlanId, PortNumber> vlanPortMap = HashMultimap.create();
617
618 interfaceService.getInterfaces().stream()
619 .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
620 .forEach(intf -> {
621 vlanPortMap.put(intf.vlanUntagged(), intf.connectPoint().port());
622 intf.vlanTagged().forEach(vlanTagged -> {
623 vlanPortMap.put(vlanTagged, intf.connectPoint().port());
624 });
625 vlanPortMap.put(intf.vlanNative(), intf.connectPoint().port());
626 });
627 vlanPortMap.removeAll(VlanId.NONE);
628
629 return vlanPortMap;
630 }
631
632 /**
Saurav Das0e99e2b2015-10-28 12:39:42 -0700633 * Returns the next objective ID for the given NeighborSet.
Saurav Das8a0732e2015-11-20 15:27:53 -0800634 * If the nextObjective does not exist, a new one is created and
Saurav Das4ce45962015-11-24 23:21:05 -0800635 * its id is returned.
sangho1e575652015-05-14 00:39:53 -0700636 *
sanghof9d0bf12015-05-19 11:57:42 -0700637 * @param deviceId Device ID
638 * @param ns NegighborSet
Saurav Das8a0732e2015-11-20 15:27:53 -0800639 * @param meta metadata passed into the creation of a Next Objective
Pier Ventre917127a2016-10-31 16:49:19 -0700640 * @param isBos indicates if it is BoS or not
Saurav Das8a0732e2015-11-20 15:27:53 -0800641 * @return next objective ID or -1 if an error was encountered during the
642 * creation of the nextObjective
sangho1e575652015-05-14 00:39:53 -0700643 */
Saurav Das8a0732e2015-11-20 15:27:53 -0800644 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns,
Pier Ventre917127a2016-10-31 16:49:19 -0700645 TrafficSelector meta, boolean isBos) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700646 if (groupHandlerMap.get(deviceId) != null) {
647 log.trace("getNextObjectiveId query in device {}", deviceId);
648 return groupHandlerMap
Pier Ventre917127a2016-10-31 16:49:19 -0700649 .get(deviceId).getNextObjectiveId(ns, meta, isBos);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700650 } else {
Saurav Das4ce45962015-11-24 23:21:05 -0800651 log.warn("getNextObjectiveId query - groupHandler for device {} "
652 + "not found", deviceId);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700653 return -1;
654 }
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700655 }
656
Charles Chanc42e84e2015-10-20 16:24:19 -0700657 /**
Pier Ventre917127a2016-10-31 16:49:19 -0700658 * Returns the next objective ID for the given NeighborSet.
659 * If the nextObjective does not exist, a new one is created and
660 * its id is returned.
661 *
662 * @param deviceId Device ID
663 * @param ns NegighborSet
664 * @param meta metadata passed into the creation of a Next Objective
665 * @return next objective ID or -1 if an error was encountered during the
666 * creation of the nextObjective
667 */
668 public int getNextObjectiveId(DeviceId deviceId,
669 NeighborSet ns,
670 TrafficSelector meta) {
671 return this.getNextObjectiveId(deviceId, ns, meta, true);
672 }
673
674 /**
Saurav Das4ce45962015-11-24 23:21:05 -0800675 * Returns the next objective ID for the given subnet prefix. It is expected
Charles Chan59cc16d2017-02-02 16:20:42 -0800676 * Returns the next objective ID for the given vlan id. It is expected
Saurav Das4ce45962015-11-24 23:21:05 -0800677 * that the next-objective has been pre-created from configuration.
Charles Chanc42e84e2015-10-20 16:24:19 -0700678 *
679 * @param deviceId Device ID
Charles Chan59cc16d2017-02-02 16:20:42 -0800680 * @param vlanId VLAN ID
Saurav Das4ce45962015-11-24 23:21:05 -0800681 * @return next objective ID or -1 if it was not found
Charles Chanc42e84e2015-10-20 16:24:19 -0700682 */
Charles Chan59cc16d2017-02-02 16:20:42 -0800683 public int getVlanNextObjectiveId(DeviceId deviceId, VlanId vlanId) {
Charles Chanc42e84e2015-10-20 16:24:19 -0700684 if (groupHandlerMap.get(deviceId) != null) {
Charles Chan59cc16d2017-02-02 16:20:42 -0800685 log.trace("getVlanNextObjectiveId query in device {}", deviceId);
686 return groupHandlerMap.get(deviceId).getVlanNextObjectiveId(vlanId);
Charles Chanc42e84e2015-10-20 16:24:19 -0700687 } else {
Charles Chan59cc16d2017-02-02 16:20:42 -0800688 log.warn("getVlanNextObjectiveId query - groupHandler for "
Saurav Das4ce45962015-11-24 23:21:05 -0800689 + "device {} not found", deviceId);
690 return -1;
691 }
692 }
693
694 /**
695 * Returns the next objective ID for the given portNumber, given the treatment.
696 * There could be multiple different treatments to the same outport, which
Saurav Das961beb22017-03-29 19:09:17 -0700697 * would result in different objectives. If the next object does not exist,
698 * and should be created, a new one is created and its id is returned.
Saurav Das4ce45962015-11-24 23:21:05 -0800699 *
700 * @param deviceId Device ID
701 * @param portNum port number on device for which NextObjective is queried
702 * @param treatment the actions to apply on the packets (should include outport)
703 * @param meta metadata passed into the creation of a Next Objective if necessary
Saurav Das961beb22017-03-29 19:09:17 -0700704 * @param createIfMissing true if a next object should be created if not found
Saurav Das59232cf2016-04-27 18:35:50 -0700705 * @return next objective ID or -1 if an error occurred during retrieval or creation
Saurav Das4ce45962015-11-24 23:21:05 -0800706 */
707 public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum,
708 TrafficTreatment treatment,
Saurav Das961beb22017-03-29 19:09:17 -0700709 TrafficSelector meta,
710 boolean createIfMissing) {
Saurav Das4ce45962015-11-24 23:21:05 -0800711 DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId);
712 if (ghdlr != null) {
Saurav Das961beb22017-03-29 19:09:17 -0700713 return ghdlr.getPortNextObjectiveId(portNum, treatment, meta, createIfMissing);
Saurav Das4ce45962015-11-24 23:21:05 -0800714 } else {
Charles Chane849c192016-01-11 18:28:54 -0800715 log.warn("getPortNextObjectiveId query - groupHandler for device {}"
716 + " not found", deviceId);
717 return -1;
718 }
719 }
720
sanghob35a6192015-04-01 13:05:26 -0700721 private class InternalPacketProcessor implements PacketProcessor {
sanghob35a6192015-04-01 13:05:26 -0700722 @Override
723 public void process(PacketContext context) {
724
725 if (context.isHandled()) {
726 return;
727 }
728
729 InboundPacket pkt = context.inPacket();
730 Ethernet ethernet = pkt.parsed();
Pier Luigi7dad71c2017-02-01 13:50:04 -0800731
732 if (ethernet == null) {
733 return;
734 }
735
Saurav Das4ce45962015-11-24 23:21:05 -0800736 log.trace("Rcvd pktin: {}", ethernet);
Pier Ventree0ae7a32016-11-23 09:57:42 -0800737 if (ethernet.getEtherType() == TYPE_ARP) {
Saurav Das76ae6812017-03-15 15:15:14 -0700738 log.warn("Received unexpected ARP packet on {}", context.inPacket().receivedFrom());
739 log.trace("{}", ethernet);
Pier Ventre968da122016-12-09 17:26:04 -0800740 return;
sanghob35a6192015-04-01 13:05:26 -0700741 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
Pier Ventre735b8c82016-12-02 08:16:05 -0800742 IPv4 ipv4Packet = (IPv4) ethernet.getPayload();
743 //ipHandler.addToPacketBuffer(ipv4Packet);
744 if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_ICMP) {
745 icmpHandler.processIcmp(ethernet, pkt.receivedFrom());
sanghob35a6192015-04-01 13:05:26 -0700746 } else {
Charles Chan50035632017-01-13 17:20:44 -0800747 // NOTE: We don't support IP learning at this moment so this
748 // is not necessary. Also it causes duplication of DHCP packets.
Pier Ventre968da122016-12-09 17:26:04 -0800749 // ipHandler.processPacketIn(ipv4Packet, pkt.receivedFrom());
sanghob35a6192015-04-01 13:05:26 -0700750 }
Pier Ventre10bd8d12016-11-26 21:05:22 -0800751 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV6) {
752 IPv6 ipv6Packet = (IPv6) ethernet.getPayload();
Pier Ventre735b8c82016-12-02 08:16:05 -0800753 //ipHandler.addToPacketBuffer(ipv6Packet);
Pier Luigi7dad71c2017-02-01 13:50:04 -0800754 // We deal with the packet only if the packet is a ICMP6 ECHO/REPLY
Pier Ventre735b8c82016-12-02 08:16:05 -0800755 if (ipv6Packet.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
756 ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload();
757 if (icmp6Packet.getIcmpType() == ICMP6.ECHO_REQUEST ||
758 icmp6Packet.getIcmpType() == ICMP6.ECHO_REPLY) {
759 icmpHandler.processIcmpv6(ethernet, pkt.receivedFrom());
760 } else {
Charles Chan0ed44fb2017-03-13 13:10:30 -0700761 log.debug("Received ICMPv6 0x{} - not handled",
762 Integer.toHexString(icmp6Packet.getIcmpType() & 0xff));
Pier Ventre735b8c82016-12-02 08:16:05 -0800763 }
764 } else {
765 // NOTE: We don't support IP learning at this moment so this
766 // is not necessary. Also it causes duplication of DHCPv6 packets.
767 // ipHandler.processPacketIn(ipv6Packet, pkt.receivedFrom());
768 }
sanghob35a6192015-04-01 13:05:26 -0700769 }
770 }
771 }
772
773 private class InternalLinkListener implements LinkListener {
774 @Override
775 public void event(LinkEvent event) {
Charles Chanb1f8c762017-03-29 16:39:05 -0700776 if (event.type() == LinkEvent.Type.LINK_ADDED ||
777 event.type() == LinkEvent.Type.LINK_UPDATED ||
778 event.type() == LinkEvent.Type.LINK_REMOVED) {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700779 log.debug("Event {} received from Link Service", event.type());
sanghob35a6192015-04-01 13:05:26 -0700780 scheduleEventHandlerIfNotScheduled(event);
781 }
782 }
783 }
784
785 private class InternalDeviceListener implements DeviceListener {
sanghob35a6192015-04-01 13:05:26 -0700786 @Override
787 public void event(DeviceEvent event) {
sanghob35a6192015-04-01 13:05:26 -0700788 switch (event.type()) {
789 case DEVICE_ADDED:
Saurav Das1a129a02016-11-18 15:21:57 -0800790 case PORT_UPDATED:
791 case PORT_ADDED:
sangho20eff1d2015-04-13 15:15:58 -0700792 case DEVICE_UPDATED:
793 case DEVICE_AVAILABILITY_CHANGED:
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700794 log.debug("Event {} received from Device Service", event.type());
sanghob35a6192015-04-01 13:05:26 -0700795 scheduleEventHandlerIfNotScheduled(event);
796 break;
797 default:
798 }
799 }
800 }
801
Saurav Das4ce45962015-11-24 23:21:05 -0800802 @SuppressWarnings("rawtypes")
sanghob35a6192015-04-01 13:05:26 -0700803 private void scheduleEventHandlerIfNotScheduled(Event event) {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700804 synchronized (threadSchedulerLock) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700805 eventQueue.add(event);
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700806 numOfEventsQueued++;
807
808 if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) {
809 //No pending scheduled event handling threads. So start a new one.
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700810 eventHandlerFuture = executorService
811 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
812 numOfHandlerScheduled++;
813 }
Jonathan Hartc19f7c12016-04-12 15:39:44 -0700814 log.trace("numOfEventsQueued {}, numOfEventHandlerScheduled {}",
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700815 numOfEventsQueued,
816 numOfHandlerScheduled);
sanghob35a6192015-04-01 13:05:26 -0700817 }
sanghob35a6192015-04-01 13:05:26 -0700818 }
819
820 private class InternalEventHandler implements Runnable {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700821 @Override
sanghob35a6192015-04-01 13:05:26 -0700822 public void run() {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700823 try {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700824 while (true) {
Saurav Das4ce45962015-11-24 23:21:05 -0800825 @SuppressWarnings("rawtypes")
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700826 Event event = null;
827 synchronized (threadSchedulerLock) {
828 if (!eventQueue.isEmpty()) {
829 event = eventQueue.poll();
830 numOfEventsExecuted++;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700831 } else {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700832 numOfHandlerExecution++;
833 log.debug("numOfHandlerExecution {} numOfEventsExecuted {}",
834 numOfHandlerExecution, numOfEventsExecuted);
835 break;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700836 }
sangho20eff1d2015-04-13 15:15:58 -0700837 }
Charles Chanb1f8c762017-03-29 16:39:05 -0700838 if (event.type() == LinkEvent.Type.LINK_ADDED ||
839 event.type() == LinkEvent.Type.LINK_UPDATED) {
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700840 processLinkAdded((Link) event.subject());
841 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
Pier Ventre2c515312016-09-13 21:33:40 -0700842 Link linkRemoved = (Link) event.subject();
843 if (linkRemoved.src().elementId() instanceof DeviceId &&
844 !deviceService.isAvailable(linkRemoved.src().deviceId())) {
845 continue;
846 }
847 if (linkRemoved.dst().elementId() instanceof DeviceId &&
848 !deviceService.isAvailable(linkRemoved.dst().deviceId())) {
849 continue;
850 }
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700851 processLinkRemoved((Link) event.subject());
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700852 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
853 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
854 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
Saurav Das423fe2b2015-12-04 10:52:59 -0800855 DeviceId deviceId = ((Device) event.subject()).id();
856 if (deviceService.isAvailable(deviceId)) {
Saurav Das837e0bb2015-10-30 17:45:38 -0700857 log.info("Processing device event {} for available device {}",
858 event.type(), ((Device) event.subject()).id());
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700859 processDeviceAdded((Device) event.subject());
Saurav Das80980c72016-03-23 11:22:49 -0700860 } else {
861 log.info("Processing device event {} for unavailable device {}",
862 event.type(), ((Device) event.subject()).id());
863 processDeviceRemoved((Device) event.subject());
864 }
Saurav Das1a129a02016-11-18 15:21:57 -0800865 } else if (event.type() == DeviceEvent.Type.PORT_ADDED) {
Saurav Dasd2fded02016-12-02 15:43:47 -0800866 // typically these calls come when device is added first time
867 // so port filtering rules are handled at the device_added event.
868 // port added calls represent all ports on the device,
869 // enabled or not.
Saurav Das1a129a02016-11-18 15:21:57 -0800870 log.debug("** PORT ADDED {}/{} -> {}",
Saurav Dasd2fded02016-12-02 15:43:47 -0800871 ((DeviceEvent) event).subject().id(),
872 ((DeviceEvent) event).port().number(),
873 event.type());
Saurav Das1a129a02016-11-18 15:21:57 -0800874 } else if (event.type() == DeviceEvent.Type.PORT_UPDATED) {
Saurav Dasd2fded02016-12-02 15:43:47 -0800875 // these calls happen for every subsequent event
876 // ports enabled, disabled, switch goes away, comes back
Saurav Das1a129a02016-11-18 15:21:57 -0800877 log.info("** PORT UPDATED {}/{} -> {}",
878 event.subject(),
879 ((DeviceEvent) event).port(),
880 event.type());
881 processPortUpdated(((Device) event.subject()),
882 ((DeviceEvent) event).port());
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700883 } else {
884 log.warn("Unhandled event type: {}", event.type());
885 }
sanghob35a6192015-04-01 13:05:26 -0700886 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700887 } catch (Exception e) {
888 log.error("SegmentRouting event handler "
889 + "thread thrown an exception: {}", e);
sanghob35a6192015-04-01 13:05:26 -0700890 }
sanghob35a6192015-04-01 13:05:26 -0700891 }
892 }
893
sanghob35a6192015-04-01 13:05:26 -0700894 private void processLinkAdded(Link link) {
Saurav Dasb5c236e2016-06-07 10:08:06 -0700895 log.info("** LINK ADDED {}", link.toString());
Charles Chan0b4e6182015-11-03 10:42:14 -0800896 if (!deviceConfiguration.isConfigured(link.src().deviceId())) {
897 log.warn("Source device of this link is not configured.");
898 return;
899 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700900 //Irrespective whether the local is a MASTER or not for this device,
901 //create group handler instance and push default TTP flow rules.
902 //Because in a multi-instance setup, instances can initiate
903 //groups for any devices. Also the default TTP rules are needed
904 //to be pushed before inserting any IP table entries for any device
905 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
906 .deviceId());
907 if (groupHandler != null) {
Saurav Das8a0732e2015-11-20 15:27:53 -0800908 groupHandler.linkUp(link, mastershipService.isLocalMaster(
909 link.src().deviceId()));
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700910 } else {
911 Device device = deviceService.getDevice(link.src().deviceId());
912 if (device != null) {
913 log.warn("processLinkAdded: Link Added "
914 + "Notification without Device Added "
915 + "event, still handling it");
916 processDeviceAdded(device);
917 groupHandler = groupHandlerMap.get(link.src()
918 .deviceId());
Saurav Das8a0732e2015-11-20 15:27:53 -0800919 groupHandler.linkUp(link, mastershipService.isLocalMaster(device.id()));
sanghob35a6192015-04-01 13:05:26 -0700920 }
921 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700922
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700923 log.trace("Starting optimized route population process");
924 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
925 //log.trace("processLinkAdded: re-starting route population process");
926 //defaultRoutingHandler.startPopulationProcess();
Charles Chan2199c302016-04-23 17:36:10 -0700927
928 mcastHandler.init();
sanghob35a6192015-04-01 13:05:26 -0700929 }
930
931 private void processLinkRemoved(Link link) {
Saurav Dasb5c236e2016-06-07 10:08:06 -0700932 log.info("** LINK REMOVED {}", link.toString());
sangho834e4b02015-05-01 09:38:25 -0700933 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId());
934 if (groupHandler != null) {
Saurav Das423fe2b2015-12-04 10:52:59 -0800935 groupHandler.portDown(link.src().port(),
936 mastershipService.isLocalMaster(link.src().deviceId()));
sangho834e4b02015-05-01 09:38:25 -0700937 }
Srikanth Vavilapalli5428b6c2015-05-14 20:22:47 -0700938 log.trace("Starting optimized route population process");
939 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
940 //log.trace("processLinkRemoved: re-starting route population process");
941 //defaultRoutingHandler.startPopulationProcess();
Charles Chan2199c302016-04-23 17:36:10 -0700942
943 mcastHandler.processLinkDown(link);
sanghob35a6192015-04-01 13:05:26 -0700944 }
945
946 private void processDeviceAdded(Device device) {
Saurav Dasb5c236e2016-06-07 10:08:06 -0700947 log.info("** DEVICE ADDED with ID {}", device.id());
Charles Chan0b4e6182015-11-03 10:42:14 -0800948 if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
Saurav Das2857f382015-11-03 14:39:27 -0800949 log.warn("Device configuration uploading. Device {} will be "
950 + "processed after config completes.", device.id());
951 return;
952 }
Charles Chan2199c302016-04-23 17:36:10 -0700953 processDeviceAddedInternal(device.id());
954 }
955
956 private void processDeviceAddedInternal(DeviceId deviceId) {
Saurav Das837e0bb2015-10-30 17:45:38 -0700957 // Irrespective of whether the local is a MASTER or not for this device,
958 // we need to create a SR-group-handler instance. This is because in a
959 // multi-instance setup, any instance can initiate forwarding/next-objectives
960 // for any switch (even if this instance is a SLAVE or not even connected
961 // to the switch). To handle this, a default-group-handler instance is necessary
962 // per switch.
Charles Chan2199c302016-04-23 17:36:10 -0700963 log.debug("Current groupHandlerMap devs: {}", groupHandlerMap.keySet());
964 if (groupHandlerMap.get(deviceId) == null) {
Charles Chan0b4e6182015-11-03 10:42:14 -0800965 DefaultGroupHandler groupHandler;
966 try {
967 groupHandler = DefaultGroupHandler.
Charles Chan2199c302016-04-23 17:36:10 -0700968 createGroupHandler(deviceId,
969 appId,
970 deviceConfiguration,
971 linkService,
972 flowObjectiveService,
973 this);
Charles Chan0b4e6182015-11-03 10:42:14 -0800974 } catch (DeviceConfigNotFoundException e) {
975 log.warn(e.getMessage() + " Aborting processDeviceAdded.");
976 return;
977 }
Charles Chan2199c302016-04-23 17:36:10 -0700978 log.debug("updating groupHandlerMap with new config for device: {}",
979 deviceId);
980 groupHandlerMap.put(deviceId, groupHandler);
Saurav Das2857f382015-11-03 14:39:27 -0800981 }
Saurav Dasb5c236e2016-06-07 10:08:06 -0700982
Charles Chan2199c302016-04-23 17:36:10 -0700983 if (mastershipService.isLocalMaster(deviceId)) {
Saurav Das018605f2017-02-18 14:05:44 -0800984 defaultRoutingHandler.populatePortAddressingRules(deviceId);
Charles Chan03a73e02016-10-24 14:52:01 -0700985 hostHandler.init(deviceId);
Charles Chanfc5c7802016-05-17 13:13:55 -0700986 xConnectHandler.init(deviceId);
Charles Chan2199c302016-04-23 17:36:10 -0700987 DefaultGroupHandler groupHandler = groupHandlerMap.get(deviceId);
Charles Chan59cc16d2017-02-02 16:20:42 -0800988 groupHandler.createGroupsFromVlanConfig();
Charles Chan2199c302016-04-23 17:36:10 -0700989 routingRulePopulator.populateSubnetBroadcastRule(deviceId);
Charles Chanc42e84e2015-10-20 16:24:19 -0700990 }
Charles Chan5270ed02016-01-30 23:22:37 -0800991
Charles Chan03a73e02016-10-24 14:52:01 -0700992 appCfgHandler.init(deviceId);
993 routeHandler.init(deviceId);
sanghob35a6192015-04-01 13:05:26 -0700994 }
995
Saurav Das80980c72016-03-23 11:22:49 -0700996 private void processDeviceRemoved(Device device) {
997 nsNextObjStore.entrySet().stream()
998 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
999 .forEach(entry -> {
1000 nsNextObjStore.remove(entry.getKey());
1001 });
Charles Chan59cc16d2017-02-02 16:20:42 -08001002 vlanNextObjStore.entrySet().stream()
Saurav Das80980c72016-03-23 11:22:49 -07001003 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
1004 .forEach(entry -> {
Charles Chan59cc16d2017-02-02 16:20:42 -08001005 vlanNextObjStore.remove(entry.getKey());
Saurav Das80980c72016-03-23 11:22:49 -07001006 });
Saurav Das80980c72016-03-23 11:22:49 -07001007 portNextObjStore.entrySet().stream()
1008 .filter(entry -> entry.getKey().deviceId().equals(device.id()))
1009 .forEach(entry -> {
1010 portNextObjStore.remove(entry.getKey());
1011 });
Saurav Das80980c72016-03-23 11:22:49 -07001012 groupHandlerMap.remove(device.id());
Saurav Das80980c72016-03-23 11:22:49 -07001013 defaultRoutingHandler.purgeEcmpGraph(device.id());
Charles Chan2199c302016-04-23 17:36:10 -07001014 mcastHandler.removeDevice(device.id());
Charles Chanfc5c7802016-05-17 13:13:55 -07001015 xConnectHandler.removeDevice(device.id());
Saurav Das80980c72016-03-23 11:22:49 -07001016 }
1017
Saurav Das1a129a02016-11-18 15:21:57 -08001018 private void processPortUpdated(Device device, Port port) {
1019 if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
1020 log.warn("Device configuration uploading. Not handling port event for"
1021 + "dev: {} port: {}", device.id(), port.number());
1022 return;
1023 }
Saurav Das018605f2017-02-18 14:05:44 -08001024
1025 if (!mastershipService.isLocalMaster(device.id())) {
1026 log.debug("Not master for dev:{} .. not handling port updated event"
1027 + "for port {}", device.id(), port.number());
1028 return;
1029 }
1030
1031 // first we handle filtering rules associated with the port
1032 if (port.isEnabled()) {
1033 log.info("Switchport {}/{} enabled..programming filters",
1034 device.id(), port.number());
Charles Chan7e4f8192017-02-26 22:59:35 -08001035 routingRulePopulator.processSinglePortFilters(device.id(), port.number(), true);
Saurav Das018605f2017-02-18 14:05:44 -08001036 } else {
1037 log.info("Switchport {}/{} disabled..removing filters",
1038 device.id(), port.number());
Charles Chan7e4f8192017-02-26 22:59:35 -08001039 routingRulePopulator.processSinglePortFilters(device.id(), port.number(), false);
Saurav Das018605f2017-02-18 14:05:44 -08001040 }
Saurav Das1a129a02016-11-18 15:21:57 -08001041
1042 // portUpdated calls are for ports that have gone down or up. For switch
1043 // to switch ports, link-events should take care of any re-routing or
1044 // group editing necessary for port up/down. Here we only process edge ports
1045 // that are already configured.
Saurav Dasb0ae6ee2017-03-04 16:08:47 -08001046 ConnectPoint cp = new ConnectPoint(device.id(), port.number());
1047 VlanId untaggedVlan = getUntaggedVlanId(cp);
1048 VlanId nativeVlan = getNativeVlanId(cp);
1049 Set<VlanId> taggedVlans = getTaggedVlanId(cp);
Charles Chan59cc16d2017-02-02 16:20:42 -08001050
Saurav Dasb0ae6ee2017-03-04 16:08:47 -08001051 if (untaggedVlan == null && nativeVlan == null && taggedVlans.isEmpty()) {
Saurav Das1a129a02016-11-18 15:21:57 -08001052 log.debug("Not handling port updated event for unconfigured port "
1053 + "dev/port: {}/{}", device.id(), port.number());
1054 return;
1055 }
Saurav Dasb0ae6ee2017-03-04 16:08:47 -08001056 if (untaggedVlan != null) {
1057 processEdgePort(device, port, untaggedVlan, true);
1058 }
1059 if (nativeVlan != null) {
1060 processEdgePort(device, port, nativeVlan, true);
1061 }
1062 if (!taggedVlans.isEmpty()) {
1063 taggedVlans.forEach(tag -> processEdgePort(device, port, tag, false));
1064 }
Saurav Das1a129a02016-11-18 15:21:57 -08001065 }
1066
Saurav Dasb0ae6ee2017-03-04 16:08:47 -08001067 private void processEdgePort(Device device, Port port, VlanId vlanId,
1068 boolean popVlan) {
Saurav Das1a129a02016-11-18 15:21:57 -08001069 boolean portUp = port.isEnabled();
1070 if (portUp) {
Saurav Dasb0ae6ee2017-03-04 16:08:47 -08001071 log.info("Device:EdgePort {}:{} is enabled in vlan: {}", device.id(),
Charles Chan59cc16d2017-02-02 16:20:42 -08001072 port.number(), vlanId);
Saurav Das1a129a02016-11-18 15:21:57 -08001073 } else {
Saurav Dasb0ae6ee2017-03-04 16:08:47 -08001074 log.info("Device:EdgePort {}:{} is disabled in vlan: {}", device.id(),
Charles Chan59cc16d2017-02-02 16:20:42 -08001075 port.number(), vlanId);
Saurav Das1a129a02016-11-18 15:21:57 -08001076 }
1077
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -07001078 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
sanghob35a6192015-04-01 13:05:26 -07001079 if (groupHandler != null) {
Saurav Dasb0ae6ee2017-03-04 16:08:47 -08001080 groupHandler.processEdgePort(port.number(), vlanId, popVlan, portUp);
Saurav Das1a129a02016-11-18 15:21:57 -08001081 } else {
1082 log.warn("Group handler not found for dev:{}. Not handling edge port"
1083 + " {} event for port:{}", device.id(),
1084 (portUp) ? "UP" : "DOWN", port.number());
sanghob35a6192015-04-01 13:05:26 -07001085 }
1086 }
sangho1e575652015-05-14 00:39:53 -07001087
Pier Ventre10bd8d12016-11-26 21:05:22 -08001088 /**
1089 * Registers the given connect point with the NRS, this is necessary
1090 * to receive the NDP and ARP packets from the NRS.
1091 *
1092 * @param portToRegister connect point to register
1093 */
1094 public void registerConnectPoint(ConnectPoint portToRegister) {
Charles Chan0aa674e2017-02-23 15:44:08 -08001095 neighbourResolutionService.registerNeighbourHandler(
Pier Ventre10bd8d12016-11-26 21:05:22 -08001096 portToRegister,
1097 neighbourHandler,
1098 appId
1099 );
1100 }
1101
Charles Chand6832882015-10-05 17:50:33 -07001102 private class InternalConfigListener implements NetworkConfigListener {
Charles Chan2c15aca2016-11-09 20:51:44 -08001103 SegmentRoutingManager srManager;
Charles Chan4636be02015-10-07 14:21:45 -07001104
Charles Chane849c192016-01-11 18:28:54 -08001105 /**
1106 * Constructs the internal network config listener.
1107 *
Charles Chan2c15aca2016-11-09 20:51:44 -08001108 * @param srManager segment routing manager
Charles Chane849c192016-01-11 18:28:54 -08001109 */
Charles Chan2c15aca2016-11-09 20:51:44 -08001110 public InternalConfigListener(SegmentRoutingManager srManager) {
1111 this.srManager = srManager;
Charles Chan4636be02015-10-07 14:21:45 -07001112 }
1113
Charles Chane849c192016-01-11 18:28:54 -08001114 /**
1115 * Reads network config and initializes related data structure accordingly.
1116 */
Charles Chan4636be02015-10-07 14:21:45 -07001117 public void configureNetwork() {
Pier Ventre10bd8d12016-11-26 21:05:22 -08001118
Charles Chan2c15aca2016-11-09 20:51:44 -08001119 deviceConfiguration = new DeviceConfiguration(srManager);
Charles Chan4636be02015-10-07 14:21:45 -07001120
Charles Chan2c15aca2016-11-09 20:51:44 -08001121 arpHandler = new ArpHandler(srManager);
1122 icmpHandler = new IcmpHandler(srManager);
1123 ipHandler = new IpHandler(srManager);
1124 routingRulePopulator = new RoutingRulePopulator(srManager);
1125 defaultRoutingHandler = new DefaultRoutingHandler(srManager);
Charles Chan4636be02015-10-07 14:21:45 -07001126
1127 tunnelHandler = new TunnelHandler(linkService, deviceConfiguration,
1128 groupHandlerMap, tunnelStore);
1129 policyHandler = new PolicyHandler(appId, deviceConfiguration,
1130 flowObjectiveService,
1131 tunnelHandler, policyStore);
1132
Charles Chan4636be02015-10-07 14:21:45 -07001133 for (Device device : deviceService.getDevices()) {
Charles Chan2199c302016-04-23 17:36:10 -07001134 processDeviceAddedInternal(device.id());
Charles Chan4636be02015-10-07 14:21:45 -07001135 }
1136
1137 defaultRoutingHandler.startPopulationProcess();
Charles Chan2199c302016-04-23 17:36:10 -07001138 mcastHandler.init();
Charles Chan4636be02015-10-07 14:21:45 -07001139 }
1140
Charles Chand6832882015-10-05 17:50:33 -07001141 @Override
1142 public void event(NetworkConfigEvent event) {
Charles Chan5270ed02016-01-30 23:22:37 -08001143 // TODO move this part to NetworkConfigEventHandler
1144 if (event.configClass().equals(SegmentRoutingDeviceConfig.class)) {
1145 switch (event.type()) {
1146 case CONFIG_ADDED:
1147 log.info("Segment Routing Config added.");
1148 configureNetwork();
1149 break;
1150 case CONFIG_UPDATED:
1151 log.info("Segment Routing Config updated.");
1152 // TODO support dynamic configuration
1153 break;
1154 default:
1155 break;
Charles Chanb8e10c82015-10-14 11:24:40 -07001156 }
Charles Chan5270ed02016-01-30 23:22:37 -08001157 } else if (event.configClass().equals(SegmentRoutingAppConfig.class)) {
Charles Chanfc5c7802016-05-17 13:13:55 -07001158 checkState(appCfgHandler != null, "NetworkConfigEventHandler is not initialized");
Charles Chan5270ed02016-01-30 23:22:37 -08001159 switch (event.type()) {
1160 case CONFIG_ADDED:
Charles Chanfc5c7802016-05-17 13:13:55 -07001161 appCfgHandler.processAppConfigAdded(event);
Charles Chan5270ed02016-01-30 23:22:37 -08001162 break;
1163 case CONFIG_UPDATED:
Charles Chanfc5c7802016-05-17 13:13:55 -07001164 appCfgHandler.processAppConfigUpdated(event);
Charles Chan5270ed02016-01-30 23:22:37 -08001165 break;
1166 case CONFIG_REMOVED:
Charles Chanfc5c7802016-05-17 13:13:55 -07001167 appCfgHandler.processAppConfigRemoved(event);
1168 break;
1169 default:
1170 break;
1171 }
Charles Chan03a73e02016-10-24 14:52:01 -07001172 configureNetwork();
Charles Chanfc5c7802016-05-17 13:13:55 -07001173 } else if (event.configClass().equals(XConnectConfig.class)) {
1174 checkState(xConnectHandler != null, "XConnectHandler is not initialized");
1175 switch (event.type()) {
1176 case CONFIG_ADDED:
1177 xConnectHandler.processXConnectConfigAdded(event);
1178 break;
1179 case CONFIG_UPDATED:
1180 xConnectHandler.processXConnectConfigUpdated(event);
1181 break;
1182 case CONFIG_REMOVED:
1183 xConnectHandler.processXConnectConfigRemoved(event);
Charles Chan5270ed02016-01-30 23:22:37 -08001184 break;
1185 default:
1186 break;
Charles Chanb8e10c82015-10-14 11:24:40 -07001187 }
Pier Ventref34966c2016-11-07 16:21:04 -08001188 } else if (event.configClass().equals(PwaasConfig.class)) {
1189 checkState(l2TunnelHandler != null, "L2TunnelHandler is not initialized");
1190 switch (event.type()) {
1191 case CONFIG_ADDED:
1192 l2TunnelHandler.processPwaasConfigAdded(event);
1193 break;
1194 case CONFIG_UPDATED:
1195 l2TunnelHandler.processPwaasConfigUpdated(event);
1196 break;
1197 case CONFIG_REMOVED:
1198 l2TunnelHandler.processPwaasConfigRemoved(event);
1199 break;
1200 default:
1201 break;
1202 }
Charles Chand6832882015-10-05 17:50:33 -07001203 }
1204 }
1205 }
Charles Chan68aa62d2015-11-09 16:37:23 -08001206
1207 private class InternalHostListener implements HostListener {
Charles Chan68aa62d2015-11-09 16:37:23 -08001208 @Override
1209 public void event(HostEvent event) {
1210 // Do not proceed without mastership
1211 DeviceId deviceId = event.subject().location().deviceId();
1212 if (!mastershipService.isLocalMaster(deviceId)) {
1213 return;
1214 }
1215
1216 switch (event.type()) {
1217 case HOST_ADDED:
Charles Chand2990362016-04-18 13:44:03 -07001218 hostHandler.processHostAddedEvent(event);
Charles Chan68aa62d2015-11-09 16:37:23 -08001219 break;
1220 case HOST_MOVED:
Charles Chand2990362016-04-18 13:44:03 -07001221 hostHandler.processHostMovedEvent(event);
Charles Chan68aa62d2015-11-09 16:37:23 -08001222 break;
1223 case HOST_REMOVED:
Charles Chand2990362016-04-18 13:44:03 -07001224 hostHandler.processHostRemoveEvent(event);
Charles Chan68aa62d2015-11-09 16:37:23 -08001225 break;
1226 case HOST_UPDATED:
Charles Chand2990362016-04-18 13:44:03 -07001227 hostHandler.processHostUpdatedEvent(event);
Charles Chan68aa62d2015-11-09 16:37:23 -08001228 break;
1229 default:
1230 log.warn("Unsupported host event type: {}", event.type());
1231 break;
1232 }
1233 }
1234 }
1235
Charles Chand55e84d2016-03-30 17:54:24 -07001236 private class InternalMcastListener implements McastListener {
1237 @Override
1238 public void event(McastEvent event) {
1239 switch (event.type()) {
1240 case SOURCE_ADDED:
Charles Chand2990362016-04-18 13:44:03 -07001241 mcastHandler.processSourceAdded(event);
Charles Chand55e84d2016-03-30 17:54:24 -07001242 break;
1243 case SINK_ADDED:
Charles Chand2990362016-04-18 13:44:03 -07001244 mcastHandler.processSinkAdded(event);
Charles Chand55e84d2016-03-30 17:54:24 -07001245 break;
1246 case SINK_REMOVED:
Charles Chand2990362016-04-18 13:44:03 -07001247 mcastHandler.processSinkRemoved(event);
Charles Chand55e84d2016-03-30 17:54:24 -07001248 break;
1249 case ROUTE_ADDED:
1250 case ROUTE_REMOVED:
1251 default:
1252 break;
1253 }
1254 }
1255 }
Charles Chan35fd1a72016-06-13 18:54:31 -07001256
Charles Chan03a73e02016-10-24 14:52:01 -07001257 private class InternalRouteEventListener implements RouteListener {
1258 @Override
1259 public void event(RouteEvent event) {
1260 switch (event.type()) {
1261 case ROUTE_ADDED:
1262 routeHandler.processRouteAdded(event);
1263 break;
1264 case ROUTE_UPDATED:
1265 routeHandler.processRouteUpdated(event);
1266 break;
1267 case ROUTE_REMOVED:
1268 routeHandler.processRouteRemoved(event);
1269 break;
1270 default:
1271 break;
1272 }
1273 }
1274 }
sanghob35a6192015-04-01 13:05:26 -07001275}