blob: f2a971b69885cdd08437bfa4e8f86e5b3d1cf27e [file] [log] [blame]
Thomas Vachuska8fd25052015-09-10 16:15:33 -07001/*
Brian O'Connor0947d7e2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska8fd25052015-09-10 16:15:33 -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 */
Charles Chan319d1a22015-11-03 10:42:14 -080016package org.onosproject.segmentrouting.config;
sangho80f11cb2015-04-01 13:05:26 -070017
Charles Chan6191aca2017-09-12 12:09:22 -070018import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ArrayNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
Charles Chan82ab1932016-01-30 23:22:37 -080021import com.google.common.collect.HashMultimap;
Charles Chanc6ad7752015-10-29 14:58:10 -070022import com.google.common.collect.ImmutableSet;
Charles Chan19b70032019-04-17 14:20:26 -070023import com.google.common.collect.Lists;
Charles Chandc7d6f92018-03-20 13:30:38 -070024import com.google.common.collect.Multimaps;
Charles Chan82ab1932016-01-30 23:22:37 -080025import com.google.common.collect.SetMultimap;
Charles Chan19b70032019-04-17 14:20:26 -070026import com.google.common.collect.Sets;
sangho80f11cb2015-04-01 13:05:26 -070027import org.onlab.packet.Ip4Address;
Pier Ventreadb4ae62016-11-23 09:57:42 -080028import org.onlab.packet.Ip6Address;
Charles Chandebfea32016-10-24 14:52:01 -070029import org.onlab.packet.IpAddress;
Charles Chan82ab1932016-01-30 23:22:37 -080030import org.onlab.packet.IpPrefix;
sangho80f11cb2015-04-01 13:05:26 -070031import org.onlab.packet.MacAddress;
Charles Chanb7f75ac2016-01-11 18:28:54 -080032import org.onlab.packet.VlanId;
Charles Chane7c61022015-10-07 14:21:45 -070033import org.onosproject.net.ConnectPoint;
sangho80f11cb2015-04-01 13:05:26 -070034import org.onosproject.net.DeviceId;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070035import org.onosproject.net.PortNumber;
Jonathan Hart61e24e12017-11-30 18:23:42 -080036import org.onosproject.net.config.ConfigException;
37import org.onosproject.net.config.basics.InterfaceConfig;
38import org.onosproject.net.host.InterfaceIpAddress;
39import org.onosproject.net.intf.Interface;
Charles Chan19b70032019-04-17 14:20:26 -070040import org.onosproject.routeservice.Route;
Charles Chan46fdfaf2016-11-09 20:51:44 -080041import org.onosproject.segmentrouting.SegmentRoutingManager;
sangho80f11cb2015-04-01 13:05:26 -070042import org.slf4j.Logger;
43import org.slf4j.LoggerFactory;
44
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070045import java.util.ArrayList;
Jonathan Hart61e24e12017-11-30 18:23:42 -080046import java.util.Collection;
Pier Ventreb6a7f342016-11-26 21:05:22 -080047import java.util.Collections;
sangho80f11cb2015-04-01 13:05:26 -070048import java.util.HashMap;
Charles Chan9bec8a32015-12-01 10:00:51 -080049import java.util.HashSet;
sangho80f11cb2015-04-01 13:05:26 -070050import java.util.List;
51import java.util.Map;
Charles Chancf789822019-03-22 10:04:27 -070052import java.util.Objects;
Charles Chan72f556a2015-10-05 17:50:33 -070053import java.util.Set;
Saurav Das7c305372015-10-28 12:39:42 -070054import java.util.concurrent.ConcurrentHashMap;
Charles Chan46fdfaf2016-11-09 20:51:44 -080055import java.util.stream.Collectors;
sangho80f11cb2015-04-01 13:05:26 -070056
Charles Chanc22cef32016-04-29 14:38:22 -070057import static com.google.common.base.Preconditions.checkNotNull;
58
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070059/**
60 * Segment Routing configuration component that reads the
61 * segment routing related configuration from Network Configuration Manager
62 * component and organizes in more accessible formats.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070063 */
sangho80f11cb2015-04-01 13:05:26 -070064public class DeviceConfiguration implements DeviceProperties {
65
Charles Chan46fdfaf2016-11-09 20:51:44 -080066 private static final String NO_SUBNET = "No subnet configured on {}";
67
Charles Chan43547ca2016-02-10 20:46:58 -080068 private static final Logger log = LoggerFactory.getLogger(DeviceConfiguration.class);
Sho SHIMIZU47b8aa22015-09-11 11:19:11 -070069 private final List<Integer> allSegmentIds = new ArrayList<>();
Charles Chanb7f75ac2016-01-11 18:28:54 -080070 private final Map<DeviceId, SegmentRouterInfo> deviceConfigMap = new ConcurrentHashMap<>();
Charles Chan46fdfaf2016-11-09 20:51:44 -080071 private SegmentRoutingManager srManager;
sangho80f11cb2015-04-01 13:05:26 -070072
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070073 private class SegmentRouterInfo {
Charles Chan3d35a542018-10-02 12:52:29 -070074 int ipv4NodeSid = -1;
75 int ipv6NodeSid = -1;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070076 DeviceId deviceId;
Pier Ventreadb4ae62016-11-23 09:57:42 -080077 Ip4Address ipv4Loopback;
78 Ip6Address ipv6Loopback;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070079 MacAddress mac;
80 boolean isEdge;
Pier Ventreb6a7f342016-11-26 21:05:22 -080081 SetMultimap<PortNumber, IpAddress> gatewayIps;
82 SetMultimap<PortNumber, IpPrefix> subnets;
Charles Chan9bec8a32015-12-01 10:00:51 -080083 Map<Integer, Set<Integer>> adjacencySids;
Saurav Das261c3002017-06-13 15:35:54 -070084 DeviceId pairDeviceId;
85 PortNumber pairLocalPort;
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -070086 int pwRoutingLabel;
Charles Chan2b078ae2015-10-14 11:24:40 -070087
88 public SegmentRouterInfo() {
Charles Chandc7d6f92018-03-20 13:30:38 -070089 gatewayIps = Multimaps.synchronizedSetMultimap(HashMultimap.create());
90 subnets = Multimaps.synchronizedSetMultimap(HashMultimap.create());
Charles Chan2b078ae2015-10-14 11:24:40 -070091 }
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070092 }
sangho80f11cb2015-04-01 13:05:26 -070093
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070094 /**
Charles Chanb7f75ac2016-01-11 18:28:54 -080095 * Constructs device configuration for all Segment Router devices,
96 * organizing the data into various maps for easier access.
Brian O'Connor65eeb572015-10-09 17:03:44 -070097 *
Charles Chan46fdfaf2016-11-09 20:51:44 -080098 * @param srManager Segment Routing Manager
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070099 */
Charles Chan46fdfaf2016-11-09 20:51:44 -0800100 public DeviceConfiguration(SegmentRoutingManager srManager) {
101 this.srManager = srManager;
Saurav Das261c3002017-06-13 15:35:54 -0700102 updateConfig();
103 }
Charles Chan57bd98c2016-02-22 19:27:29 -0800104
Saurav Das261c3002017-06-13 15:35:54 -0700105 public void updateConfig() {
Charles Chane7c61022015-10-07 14:21:45 -0700106 // Read config from device subject, excluding gatewayIps and subnets.
107 Set<DeviceId> deviceSubjects =
Charles Chan46fdfaf2016-11-09 20:51:44 -0800108 srManager.cfgService.getSubjects(DeviceId.class, SegmentRoutingDeviceConfig.class);
Charles Chane7c61022015-10-07 14:21:45 -0700109 deviceSubjects.forEach(subject -> {
Charles Chan82ab1932016-01-30 23:22:37 -0800110 SegmentRoutingDeviceConfig config =
Charles Chan46fdfaf2016-11-09 20:51:44 -0800111 srManager.cfgService.getConfig(subject, SegmentRoutingDeviceConfig.class);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700112 SegmentRouterInfo info = new SegmentRouterInfo();
Charles Chan72f556a2015-10-05 17:50:33 -0700113 info.deviceId = subject;
Pier Ventreadb4ae62016-11-23 09:57:42 -0800114 info.ipv4NodeSid = config.nodeSidIPv4();
115 info.ipv6NodeSid = config.nodeSidIPv6();
116 info.ipv4Loopback = config.routerIpv4();
117 info.ipv6Loopback = config.routerIpv6();
Charles Chan9bec8a32015-12-01 10:00:51 -0800118 info.mac = config.routerMac();
Charles Chan72f556a2015-10-05 17:50:33 -0700119 info.isEdge = config.isEdgeRouter();
Charles Chan9bec8a32015-12-01 10:00:51 -0800120 info.adjacencySids = config.adjacencySids();
Saurav Das261c3002017-06-13 15:35:54 -0700121 info.pairDeviceId = config.pairDeviceId();
122 info.pairLocalPort = config.pairLocalPort();
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700123 info.pwRoutingLabel = info.ipv4NodeSid + 1000;
Charles Chanb7f75ac2016-01-11 18:28:54 -0800124 deviceConfigMap.put(info.deviceId, info);
Charles Chan68363b12017-06-26 15:25:09 -0700125 log.debug("Read device config for device: {}", info.deviceId);
Pier Ventreadb4ae62016-11-23 09:57:42 -0800126 /*
127 * IPv6 sid is not inserted. this part of the code is not used for now.
128 */
129 allSegmentIds.add(info.ipv4NodeSid);
Charles Chan72f556a2015-10-05 17:50:33 -0700130 });
Charles Chane7c61022015-10-07 14:21:45 -0700131
Charles Chan46fdfaf2016-11-09 20:51:44 -0800132 // Read gatewayIps and subnets from port subject. Ignore suppressed ports.
133 Set<ConnectPoint> portSubjects = srManager.cfgService
134 .getSubjects(ConnectPoint.class, InterfaceConfig.class);
Jonathan Hart61e24e12017-11-30 18:23:42 -0800135 portSubjects.stream()
136 .filter(subject -> deviceConfigMap.containsKey(subject.deviceId()))
137 .filter(subject -> !isSuppressedPort(subject)).forEach(subject -> {
Charles Chane7c61022015-10-07 14:21:45 -0700138 InterfaceConfig config =
Charles Chan46fdfaf2016-11-09 20:51:44 -0800139 srManager.cfgService.getConfig(subject, InterfaceConfig.class);
Charles Chane7c61022015-10-07 14:21:45 -0700140 Set<Interface> networkInterfaces;
141 try {
142 networkInterfaces = config.getInterfaces();
143 } catch (ConfigException e) {
144 log.error("Error loading port configuration");
145 return;
146 }
147 networkInterfaces.forEach(networkInterface -> {
Charles Chanb7f75ac2016-01-11 18:28:54 -0800148 VlanId vlanId = networkInterface.vlan();
149 ConnectPoint connectPoint = networkInterface.connectPoint();
150 DeviceId dpid = connectPoint.deviceId();
151 PortNumber port = connectPoint.port();
Charles Chan6191aca2017-09-12 12:09:22 -0700152 MacAddress mac = networkInterface.mac();
Charles Chanb7f75ac2016-01-11 18:28:54 -0800153 SegmentRouterInfo info = deviceConfigMap.get(dpid);
Charles Chane7c61022015-10-07 14:21:45 -0700154
Charles Chan2b078ae2015-10-14 11:24:40 -0700155 // skip if there is no corresponding device for this ConenctPoint
156 if (info != null) {
Charles Chanb7f75ac2016-01-11 18:28:54 -0800157 // Extract subnet information
Jonathan Hart8fa9ec52016-02-16 10:30:37 -0800158 List<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddressesList();
Charles Chan2b078ae2015-10-14 11:24:40 -0700159 interfaceAddresses.forEach(interfaceAddress -> {
Pier Ventreb6a7f342016-11-26 21:05:22 -0800160 // Do not add /0, /32 and /128 to gateway IP list
Charles Chan82ab1932016-01-30 23:22:37 -0800161 int prefixLength = interfaceAddress.subnetAddress().prefixLength();
Pier Ventreb6a7f342016-11-26 21:05:22 -0800162 IpPrefix ipPrefix = interfaceAddress.subnetAddress();
163 if (ipPrefix.isIp4()) {
164 if (prefixLength != 0 && prefixLength != IpPrefix.MAX_INET_MASK_LENGTH) {
165 info.gatewayIps.put(port, interfaceAddress.ipAddress());
166 }
167 info.subnets.put(port, interfaceAddress.subnetAddress());
168 } else {
169 if (prefixLength != 0 && prefixLength != IpPrefix.MAX_INET6_MASK_LENGTH) {
170 info.gatewayIps.put(port, interfaceAddress.ipAddress());
171 }
172 info.subnets.put(port, interfaceAddress.subnetAddress());
Charles Chan82ab1932016-01-30 23:22:37 -0800173 }
Charles Chan2b078ae2015-10-14 11:24:40 -0700174 });
Charles Chan6191aca2017-09-12 12:09:22 -0700175
176 // Override interface mac with router mac
177 if (!mac.equals(info.mac)) {
178 ArrayNode array = (ArrayNode) config.node();
179 for (JsonNode intfNode : array) {
180 ObjectNode objNode = (ObjectNode) intfNode;
181 objNode.put(InterfaceConfig.MAC, info.mac.toString());
182 }
183 srManager.cfgService.applyConfig(connectPoint, InterfaceConfig.class, array);
184 }
Charles Chan2b078ae2015-10-14 11:24:40 -0700185 }
Charles Chane7c61022015-10-07 14:21:45 -0700186 });
Pier Luigi6a2643a2017-01-31 09:35:05 -0800187 // We register the connect point with the NRS.
Pier Ventreb6a7f342016-11-26 21:05:22 -0800188 srManager.registerConnectPoint(subject);
Charles Chane7c61022015-10-07 14:21:45 -0700189 });
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700190 }
191
Jonathan Hart61e24e12017-11-30 18:23:42 -0800192 public Collection<DeviceId> getRouters() {
193 return deviceConfigMap.keySet();
194 }
Saurav Das261c3002017-06-13 15:35:54 -0700195
sangho80f11cb2015-04-01 13:05:26 -0700196 @Override
Charles Chan319d1a22015-11-03 10:42:14 -0800197 public boolean isConfigured(DeviceId deviceId) {
198 return deviceConfigMap.get(deviceId) != null;
199 }
200
201 @Override
Pier Ventreadb4ae62016-11-23 09:57:42 -0800202 public int getIPv4SegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException {
Saurav Das7c305372015-10-28 12:39:42 -0700203 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
204 if (srinfo != null) {
Pier Ventreadb4ae62016-11-23 09:57:42 -0800205 log.trace("getIPv4SegmentId for device{} is {}", deviceId, srinfo.ipv4NodeSid);
206 return srinfo.ipv4NodeSid;
sangho80f11cb2015-04-01 13:05:26 -0700207 } else {
Pier Ventreadb4ae62016-11-23 09:57:42 -0800208 String message = "getIPv4SegmentId fails for device: " + deviceId + ".";
209 throw new DeviceConfigNotFoundException(message);
210 }
211 }
212
213 @Override
214 public int getIPv6SegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException {
215 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
216 if (srinfo != null) {
217 log.trace("getIPv6SegmentId for device{} is {}", deviceId, srinfo.ipv6NodeSid);
218 return srinfo.ipv6NodeSid;
219 } else {
220 String message = "getIPv6SegmentId fails for device: " + deviceId + ".";
Charles Chan319d1a22015-11-03 10:42:14 -0800221 throw new DeviceConfigNotFoundException(message);
sangho80f11cb2015-04-01 13:05:26 -0700222 }
223 }
224
Andreas Pantelopoulos5e7be3d2017-10-23 12:18:25 -0700225 @Override
226 public int getPWRoutingLabel(DeviceId deviceId) throws DeviceConfigNotFoundException {
227 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
228 if (srinfo != null) {
229 log.trace("pwRoutingLabel for device{} is {}", deviceId, srinfo.pwRoutingLabel);
230 return srinfo.pwRoutingLabel;
231 } else {
232 String message = "getPWRoutingLabel fails for device: " + deviceId + ".";
233 throw new DeviceConfigNotFoundException(message);
234 }
235 }
236
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700237 /**
Pier Ventreadb4ae62016-11-23 09:57:42 -0800238 * Returns the IPv4 Node segment id of a segment router given its Router mac address.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700239 *
240 * @param routerMac router mac address
Saurav Das7c305372015-10-28 12:39:42 -0700241 * @return node segment id, or -1 if not found in config
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700242 */
Pier Ventreadb4ae62016-11-23 09:57:42 -0800243 public int getIPv4SegmentId(MacAddress routerMac) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700244 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
245 deviceConfigMap.entrySet()) {
246 if (entry.getValue().mac.equals(routerMac)) {
Pier Ventreadb4ae62016-11-23 09:57:42 -0800247 return entry.getValue().ipv4NodeSid;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700248 }
249 }
sangho80f11cb2015-04-01 13:05:26 -0700250
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700251 return -1;
252 }
253
254 /**
Pier Ventreadb4ae62016-11-23 09:57:42 -0800255 * Returns the IPv6 Node segment id of a segment router given its Router mac address.
256 *
257 * @param routerMac router mac address
258 * @return node segment id, or -1 if not found in config
259 */
260 public int getIPv6SegmentId(MacAddress routerMac) {
261 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
262 deviceConfigMap.entrySet()) {
263 if (entry.getValue().mac.equals(routerMac)) {
264 return entry.getValue().ipv6NodeSid;
265 }
266 }
267
268 return -1;
269 }
270
271 /**
272 * Returns the IPv4 Node segment id of a segment router given its Router ip address.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700273 *
274 * @param routerAddress router ip address
Saurav Das7c305372015-10-28 12:39:42 -0700275 * @return node segment id, or -1 if not found in config
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700276 */
Pier Ventreadb4ae62016-11-23 09:57:42 -0800277 public int getIPv4SegmentId(Ip4Address routerAddress) {
Charles Chan3d35a542018-10-02 12:52:29 -0700278 for (Map.Entry<DeviceId, SegmentRouterInfo> entry: deviceConfigMap.entrySet()) {
279 Ip4Address ipv4Loopback = entry.getValue().ipv4Loopback;
280 if (ipv4Loopback == null) {
281 continue;
282 }
Pier Ventreadb4ae62016-11-23 09:57:42 -0800283 if (entry.getValue().ipv4Loopback.equals(routerAddress)) {
Charles Chan3d35a542018-10-02 12:52:29 -0700284 if (entry.getValue().ipv4NodeSid == -1) {
285 continue;
286 }
Pier Ventreadb4ae62016-11-23 09:57:42 -0800287 return entry.getValue().ipv4NodeSid;
288 }
289 }
290
291 return -1;
292 }
293
294 /**
295 * Returns the IPv6 Node segment id of a segment router given its Router ip address.
296 *
297 * @param routerAddress router ip address
298 * @return node segment id, or -1 if not found in config
299 */
300 public int getIPv6SegmentId(Ip6Address routerAddress) {
Charles Chan3d35a542018-10-02 12:52:29 -0700301 for (Map.Entry<DeviceId, SegmentRouterInfo> entry: deviceConfigMap.entrySet()) {
302 Ip6Address ipv6Loopback = entry.getValue().ipv6Loopback;
303 if (ipv6Loopback == null) {
304 continue;
305 }
Pier Ventreadb4ae62016-11-23 09:57:42 -0800306 if (entry.getValue().ipv6Loopback.equals(routerAddress)) {
Charles Chan3d35a542018-10-02 12:52:29 -0700307 if (entry.getValue().ipv6NodeSid == -1) {
308 continue;
309 }
Pier Ventreadb4ae62016-11-23 09:57:42 -0800310 return entry.getValue().ipv6NodeSid;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700311 }
312 }
313
314 return -1;
315 }
316
sangho80f11cb2015-04-01 13:05:26 -0700317 @Override
Charles Chan319d1a22015-11-03 10:42:14 -0800318 public MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException {
Saurav Das7c305372015-10-28 12:39:42 -0700319 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
320 if (srinfo != null) {
Saurav Das7c305372015-10-28 12:39:42 -0700321 return srinfo.mac;
sangho80f11cb2015-04-01 13:05:26 -0700322 } else {
Charles Chan319d1a22015-11-03 10:42:14 -0800323 String message = "getDeviceMac fails for device: " + deviceId + ".";
324 throw new DeviceConfigNotFoundException(message);
sangho80f11cb2015-04-01 13:05:26 -0700325 }
326 }
327
Charles Chan319d1a22015-11-03 10:42:14 -0800328 @Override
Pier Ventreadb4ae62016-11-23 09:57:42 -0800329 public Ip4Address getRouterIpv4(DeviceId deviceId) throws DeviceConfigNotFoundException {
Saurav Das7c305372015-10-28 12:39:42 -0700330 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
331 if (srinfo != null) {
Pier Ventreadb4ae62016-11-23 09:57:42 -0800332 log.trace("getRouterIpv4 for device{} is {}", deviceId, srinfo.ipv4Loopback);
333 return srinfo.ipv4Loopback;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700334 } else {
Pier Ventreadb4ae62016-11-23 09:57:42 -0800335 String message = "getRouterIpv4 fails for device: " + deviceId + ".";
336 throw new DeviceConfigNotFoundException(message);
337 }
338 }
339
340 @Override
341 public Ip6Address getRouterIpv6(DeviceId deviceId) throws DeviceConfigNotFoundException {
342 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
343 if (srinfo != null) {
344 log.trace("getRouterIpv6 for device{} is {}", deviceId, srinfo.ipv6Loopback);
345 return srinfo.ipv6Loopback;
346 } else {
347 String message = "getRouterIpv6 fails for device: " + deviceId + ".";
Charles Chan319d1a22015-11-03 10:42:14 -0800348 throw new DeviceConfigNotFoundException(message);
sangho80f11cb2015-04-01 13:05:26 -0700349 }
sangho80f11cb2015-04-01 13:05:26 -0700350 }
351
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700352 @Override
Charles Chan319d1a22015-11-03 10:42:14 -0800353 public boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException {
Saurav Das7c305372015-10-28 12:39:42 -0700354 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
355 if (srinfo != null) {
356 log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge);
357 return srinfo.isEdge;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700358 } else {
Charles Chan319d1a22015-11-03 10:42:14 -0800359 String message = "isEdgeDevice fails for device: " + deviceId + ".";
360 throw new DeviceConfigNotFoundException(message);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700361 }
362 }
363
sangho80f11cb2015-04-01 13:05:26 -0700364 @Override
365 public List<Integer> getAllDeviceSegmentIds() {
366 return allSegmentIds;
367 }
368
Charles Chan77277672015-10-20 16:24:19 -0700369 @Override
Pier Ventreb6a7f342016-11-26 21:05:22 -0800370 public Map<IpPrefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId)
Saurav Das52d4ed72016-03-28 19:00:18 -0700371 throws DeviceConfigNotFoundException {
372 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
373 if (srinfo == null) {
374 String message = "getSubnetPortsMap fails for device: " + deviceId + ".";
375 throw new DeviceConfigNotFoundException(message);
376 }
Charles Chan77277672015-10-20 16:24:19 -0700377 // Construct subnet-port mapping from port-subnet mapping
Pier Ventreb6a7f342016-11-26 21:05:22 -0800378 SetMultimap<PortNumber, IpPrefix> portSubnetMap = srinfo.subnets;
379 Map<IpPrefix, List<PortNumber>> subnetPortMap = new HashMap<>();
Charles Chan82ab1932016-01-30 23:22:37 -0800380
381 portSubnetMap.entries().forEach(entry -> {
382 PortNumber port = entry.getKey();
Pier Ventreb6a7f342016-11-26 21:05:22 -0800383 IpPrefix subnet = entry.getValue();
Charles Chan82ab1932016-01-30 23:22:37 -0800384
Pier Ventreb6a7f342016-11-26 21:05:22 -0800385 if (subnet.prefixLength() == IpPrefix.MAX_INET_MASK_LENGTH ||
386 subnet.prefixLength() == IpPrefix.MAX_INET6_MASK_LENGTH) {
Charles Chanbbd004c2016-02-16 23:14:49 -0800387 return;
388 }
389
Charles Chan77277672015-10-20 16:24:19 -0700390 if (subnetPortMap.containsKey(subnet)) {
391 subnetPortMap.get(subnet).add(port);
392 } else {
393 ArrayList<PortNumber> ports = new ArrayList<>();
394 ports.add(port);
395 subnetPortMap.put(subnet, ports);
396 }
397 });
Charles Chan77277672015-10-20 16:24:19 -0700398 return subnetPortMap;
399 }
400
sangho80f11cb2015-04-01 13:05:26 -0700401 /**
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700402 * Returns the device identifier or data plane identifier (dpid)
403 * of a segment router given its segment id.
sangho80f11cb2015-04-01 13:05:26 -0700404 *
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700405 * @param sid segment id
406 * @return deviceId device identifier
sangho80f11cb2015-04-01 13:05:26 -0700407 */
408 public DeviceId getDeviceId(int sid) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700409 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
410 deviceConfigMap.entrySet()) {
Pier Ventreadb4ae62016-11-23 09:57:42 -0800411 if (entry.getValue().ipv4NodeSid == sid ||
412 entry.getValue().ipv6NodeSid == sid) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700413 return entry.getValue().deviceId;
sangho80f11cb2015-04-01 13:05:26 -0700414 }
415 }
416
417 return null;
418 }
419
420 /**
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700421 * Returns the device identifier or data plane identifier (dpid)
422 * of a segment router given its router ip address.
sangho80f11cb2015-04-01 13:05:26 -0700423 *
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700424 * @param ipAddress router ip address
425 * @return deviceId device identifier
sangho80f11cb2015-04-01 13:05:26 -0700426 */
427 public DeviceId getDeviceId(Ip4Address ipAddress) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700428 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
429 deviceConfigMap.entrySet()) {
Pier Ventreadb4ae62016-11-23 09:57:42 -0800430 if (entry.getValue().ipv4Loopback.equals(ipAddress)) {
431 return entry.getValue().deviceId;
432 }
433 }
434
435 return null;
436 }
437
438 /**
439 * Returns the device identifier or data plane identifier (dpid)
440 * of a segment router given its router ipv6 address.
441 *
442 * @param ipAddress router ipv6 address
443 * @return deviceId device identifier
444 */
445 public DeviceId getDeviceId(Ip6Address ipAddress) {
446 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
447 deviceConfigMap.entrySet()) {
448 if (entry.getValue().ipv6Loopback.equals(ipAddress)) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700449 return entry.getValue().deviceId;
sangho80f11cb2015-04-01 13:05:26 -0700450 }
451 }
452
453 return null;
454 }
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700455
456 /**
Saurav Das9f1c42e2015-10-23 10:51:11 -0700457 * Returns the configured port ip addresses for a segment router.
458 * These addresses serve as gateway IP addresses for the subnets configured
459 * on those ports.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700460 *
461 * @param deviceId device identifier
Saurav Dasc28b3432015-10-30 17:45:38 -0700462 * @return immutable set of ip addresses configured on the ports or null if not found
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700463 */
Pier Ventreb6a7f342016-11-26 21:05:22 -0800464 public Set<IpAddress> getPortIPs(DeviceId deviceId) {
Saurav Das7c305372015-10-28 12:39:42 -0700465 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
466 if (srinfo != null) {
467 log.trace("getSubnetGatewayIps for device{} is {}", deviceId,
468 srinfo.gatewayIps.values());
Saurav Dasc28b3432015-10-30 17:45:38 -0700469 return ImmutableSet.copyOf(srinfo.gatewayIps.values());
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700470 }
Saurav Das7c305372015-10-28 12:39:42 -0700471 return null;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700472 }
473
474 /**
Charles Chancf789822019-03-22 10:04:27 -0700475 * Returns configured subnets for a segment router.
476 *
477 * @param deviceId device identifier
478 * @return list of ip prefixes or null if not found
479 */
480 public Set<IpPrefix> getConfiguredSubnets(DeviceId deviceId) {
481 Set<IpPrefix> subnets = srManager.interfaceService.getInterfaces().stream()
482 .filter(intf -> Objects.equals(deviceId, intf.connectPoint().deviceId()))
483 .flatMap(intf -> intf.ipAddressesList().stream())
484 .map(InterfaceIpAddress::subnetAddress)
485 .collect(Collectors.toSet());
486
487 if (subnets.isEmpty()) {
488 log.debug(NO_SUBNET, deviceId);
489 return Collections.emptySet();
490 }
491 return subnets;
492 }
493
494 /**
495 * Returns all subnets for a segment router, including subnets learnt from route service.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700496 *
497 * @param deviceId device identifier
Charles Chan19b70032019-04-17 14:20:26 -0700498 * @return set of ip prefixes or null if not found
499 * @deprecated use getBatchedSubnets(DeviceId deviceId) instead
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700500 */
Charles Chan19b70032019-04-17 14:20:26 -0700501 @Deprecated
Pier Ventreb6a7f342016-11-26 21:05:22 -0800502 public Set<IpPrefix> getSubnets(DeviceId deviceId) {
Saurav Das7c305372015-10-28 12:39:42 -0700503 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
Charles Chan5eb66042018-06-18 14:42:17 -0700504 if (srinfo != null && srinfo.subnets != null) {
505 // Note: ImmutableSet.Builder.addAll calls the iterator of parameter internally,
506 // which is not protected by SynchronizedCollection mutex.
Pier Ventreb6a7f342016-11-26 21:05:22 -0800507 ImmutableSet.Builder<IpPrefix> builder = ImmutableSet.builder();
Charles Chan5eb66042018-06-18 14:42:17 -0700508 srinfo.subnets.forEach((k, v) -> builder.add(v));
509 return builder.build();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700510 }
Saurav Das7c305372015-10-28 12:39:42 -0700511 return null;
512 }
513
Charles Chan19b70032019-04-17 14:20:26 -0700514 /**
515 * Returns batches of all subnets reachable on the given device.
516 * <p>
517 * First batch includes configured subnets, FPM and STATIC routes
518 * Second batch includes all other type of routes obtained from routeService, including DHCP routes.
519 *
520 * @param deviceId device identifier
521 * @return list of subnet batches, each batch includes a set of prefixes.
522 */
523 // TODO Querying routeService directly may be expensive. Some kind of reverse lookup cache should be developed.
524 public List<Set<IpPrefix>> getBatchedSubnets(DeviceId deviceId) {
525 Set<IpPrefix> high = Sets.newHashSet();
526 Set<IpPrefix> low = Sets.newHashSet();
527
528 high.addAll(getConfiguredSubnets(deviceId));
529 srManager.routeService.getRouteTables().stream()
530 .map(tableId -> srManager.routeService.getResolvedRoutes(tableId))
531 .flatMap(Collection::stream)
532 .forEach(resolvedRoute -> {
533 // Continue to next resolved route if none of the next hop attaches to given device
534 if (srManager.nextHopLocations(resolvedRoute).stream()
535 .noneMatch(cp -> Objects.equals(deviceId, cp.deviceId()))) {
536 return;
537 }
538 // Prioritize STATIC and FPM among others
539 if (resolvedRoute.route().source() == Route.Source.STATIC ||
540 resolvedRoute.route().source() == Route.Source.FPM) {
541 high.add(resolvedRoute.prefix());
542 } else {
543 low.add(resolvedRoute.prefix());
544 }
545 });
546 return Lists.newArrayList(high, low);
547 }
Charles Chan46fdfaf2016-11-09 20:51:44 -0800548
Saurav Das7c305372015-10-28 12:39:42 -0700549 /**
Charles Chan46fdfaf2016-11-09 20:51:44 -0800550 * Returns the subnet configuration of given device and port.
Saurav Das7c305372015-10-28 12:39:42 -0700551 *
Charles Chan46fdfaf2016-11-09 20:51:44 -0800552 * @param deviceId Device ID
553 * @param port Port number
Pier Ventreb6a7f342016-11-26 21:05:22 -0800554 * @return The subnets configured on given port or empty set if
Charles Chan2f4d2bc2017-04-24 16:21:01 -0700555 * the port is unconfigured or suppressed.
Saurav Das7c305372015-10-28 12:39:42 -0700556 */
Pier Ventreb6a7f342016-11-26 21:05:22 -0800557 public Set<IpPrefix> getPortSubnets(DeviceId deviceId, PortNumber port) {
Charles Chan46fdfaf2016-11-09 20:51:44 -0800558 ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
559
560 if (isSuppressedPort(connectPoint)) {
Pier Ventreb6a7f342016-11-26 21:05:22 -0800561 return Collections.emptySet();
Saurav Das7c305372015-10-28 12:39:42 -0700562 }
Charles Chan46fdfaf2016-11-09 20:51:44 -0800563
Charles Chancf789822019-03-22 10:04:27 -0700564 Set<IpPrefix> subnets = srManager.interfaceService.getInterfacesByPort(connectPoint).stream()
565 .flatMap(intf -> intf.ipAddressesList().stream())
566 .map(InterfaceIpAddress::subnetAddress)
567 .collect(Collectors.toSet());
Charles Chan46fdfaf2016-11-09 20:51:44 -0800568
Jon Hall31d84782017-01-18 20:15:44 -0800569 if (subnets.isEmpty()) {
Saurav Dasf9332192017-02-18 14:05:44 -0800570 log.debug(NO_SUBNET, connectPoint);
Pier Ventreb6a7f342016-11-26 21:05:22 -0800571 return Collections.emptySet();
Charles Chan46fdfaf2016-11-09 20:51:44 -0800572 }
Charles Chan2f4d2bc2017-04-24 16:21:01 -0700573 return subnets;
Pier Ventreb6a7f342016-11-26 21:05:22 -0800574 }
575
576 /**
Charles Chan873661e2017-11-30 15:37:50 -0800577 * Returns all ports that has a subnet that contains any of the given IP addresses.
578 *
579 * @param ips a set of IP addresses
580 * @return a set of connect point that has a subnet that contains any of the given IP addresses
581 */
582 public Set<ConnectPoint> getPortByIps(Set<IpAddress> ips) {
583 return srManager.interfaceService.getInterfaces().stream()
584 .filter(intf -> intf.ipAddressesList().stream().anyMatch(intfAddress ->
585 ips.stream().anyMatch(ip -> intfAddress.subnetAddress().contains(ip))))
586 .map(Interface::connectPoint)
587 .collect(Collectors.toSet());
588 }
589
590 /**
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700591 * Returns the router ip address of segment router that has the
592 * specified ip address in its subnets.
593 *
594 * @param destIpAddress target ip address
595 * @return router ip address
596 */
597 public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) {
Charles Chan70661362016-12-09 12:54:49 -0800598 Interface matchIntf = srManager.interfaceService.getMatchingInterface(destIpAddress);
599
600 if (matchIntf == null) {
601 log.debug("No router was found for {}", destIpAddress);
602 return null;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700603 }
604
Charles Chan70661362016-12-09 12:54:49 -0800605 DeviceId routerDeviceId = matchIntf.connectPoint().deviceId();
606 SegmentRouterInfo srInfo = deviceConfigMap.get(routerDeviceId);
607 if (srInfo == null) {
608 log.debug("No device config was found for {}", routerDeviceId);
609 return null;
610 }
611
Pier Ventreadb4ae62016-11-23 09:57:42 -0800612 return srInfo.ipv4Loopback;
613 }
614
615 /**
616 * Returns the router ipv6 address of segment router that has the
617 * specified ip address in its subnets.
618 *
619 * @param destIpAddress target ip address
620 * @return router ip address
621 */
622 public Ip6Address getRouterIpAddressForASubnetHost(Ip6Address destIpAddress) {
623 Interface matchIntf = srManager.interfaceService.getMatchingInterface(destIpAddress);
624
625 if (matchIntf == null) {
626 log.debug("No router was found for {}", destIpAddress);
627 return null;
628 }
629
630 DeviceId routerDeviceId = matchIntf.connectPoint().deviceId();
631 SegmentRouterInfo srInfo = deviceConfigMap.get(routerDeviceId);
632 if (srInfo == null) {
633 log.debug("No device config was found for {}", routerDeviceId);
634 return null;
635 }
636
637 return srInfo.ipv6Loopback;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700638 }
639
640 /**
641 * Returns the router mac address of segment router that has the
642 * specified ip address as one of its subnet gateway ip address.
643 *
644 * @param gatewayIpAddress router gateway ip address
Saurav Das7c305372015-10-28 12:39:42 -0700645 * @return router mac address or null if not found
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700646 */
Pier Ventreb6a7f342016-11-26 21:05:22 -0800647 public MacAddress getRouterMacForAGatewayIp(IpAddress gatewayIpAddress) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700648 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
649 deviceConfigMap.entrySet()) {
650 if (entry.getValue().gatewayIps.
651 values().contains(gatewayIpAddress)) {
652 return entry.getValue().mac;
653 }
654 }
655
656 log.debug("Cannot find a router for {}", gatewayIpAddress);
657 return null;
658 }
sangho9b169e32015-04-14 16:27:13 -0700659
sangho9b169e32015-04-14 16:27:13 -0700660 /**
Charles Chan35f21e42017-06-26 18:30:18 -0700661 * Checks if the host IP is in any of the subnet defined in the router with the
sangho9b169e32015-04-14 16:27:13 -0700662 * device ID given.
663 *
664 * @param deviceId device identification of the router
665 * @param hostIp host IP address to check
Charles Chan35f21e42017-06-26 18:30:18 -0700666 * @return true if the given IP is within any of the subnet defined in the router,
667 * false if no subnet is defined in the router or if the host is not
668 * within any subnet defined in the router
sangho9b169e32015-04-14 16:27:13 -0700669 */
Pier Ventreb6a7f342016-11-26 21:05:22 -0800670 public boolean inSameSubnet(DeviceId deviceId, IpAddress hostIp) {
Charles Chancf789822019-03-22 10:04:27 -0700671 Set<IpPrefix> subnets = getConfiguredSubnets(deviceId);
sangho9b169e32015-04-14 16:27:13 -0700672 if (subnets == null) {
673 return false;
674 }
675
Pier Ventreb6a7f342016-11-26 21:05:22 -0800676 for (IpPrefix subnet: subnets) {
Charles Chan82ab1932016-01-30 23:22:37 -0800677 // Exclude /0 since it is a special case used for default route
678 if (subnet.prefixLength() != 0 && subnet.contains(hostIp)) {
sangho9b169e32015-04-14 16:27:13 -0700679 return true;
680 }
681 }
sangho9b169e32015-04-14 16:27:13 -0700682 return false;
683 }
sangho27462c62015-05-14 00:39:53 -0700684
685 /**
Charles Chandebfea32016-10-24 14:52:01 -0700686 * Checks if the IP is in the subnet defined on given connect point.
687 *
688 * @param connectPoint Connect point
689 * @param ip The IP address to check
690 * @return True if the IP belongs to the subnet.
691 * False if the IP does not belong to the subnet, or
692 * there is no subnet configuration on given connect point.
693 */
694 public boolean inSameSubnet(ConnectPoint connectPoint, IpAddress ip) {
Charles Chan35f21e42017-06-26 18:30:18 -0700695 return getPortSubnets(connectPoint.deviceId(), connectPoint.port()).stream()
696 .anyMatch(ipPrefix -> ipPrefix.contains(ip));
Charles Chandebfea32016-10-24 14:52:01 -0700697 }
698
699 /**
sangho27462c62015-05-14 00:39:53 -0700700 * Returns the ports corresponding to the adjacency Sid given.
701 *
702 * @param deviceId device identification of the router
703 * @param sid adjacency Sid
Charles Chan9bec8a32015-12-01 10:00:51 -0800704 * @return set of port numbers
sangho27462c62015-05-14 00:39:53 -0700705 */
Charles Chan9bec8a32015-12-01 10:00:51 -0800706 public Set<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
Saurav Das7c305372015-10-28 12:39:42 -0700707 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
Charles Chan9bec8a32015-12-01 10:00:51 -0800708 return srinfo != null ?
709 ImmutableSet.copyOf(srinfo.adjacencySids.get(sid)) :
710 ImmutableSet.copyOf(new HashSet<>());
sangho27462c62015-05-14 00:39:53 -0700711 }
712
713 /**
714 * Check if the Sid given is whether adjacency Sid of the router device or not.
715 *
716 * @param deviceId device identification of the router
717 * @param sid Sid to check
718 * @return true if the Sid given is the adjacency Sid of the device,
719 * otherwise false
720 */
721 public boolean isAdjacencySid(DeviceId deviceId, int sid) {
Saurav Das7c305372015-10-28 12:39:42 -0700722 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
Charles Chan9bec8a32015-12-01 10:00:51 -0800723 return srinfo != null && srinfo.adjacencySids.containsKey(sid);
sangho27462c62015-05-14 00:39:53 -0700724 }
Charles Chan43547ca2016-02-10 20:46:58 -0800725
Charles Chanc91c8782016-03-30 17:54:24 -0700726 /**
Charles Chanc22cef32016-04-29 14:38:22 -0700727 * Add subnet to specific connect point.
728 *
729 * @param cp connect point
Pier Ventreb6a7f342016-11-26 21:05:22 -0800730 * @param ipPrefix subnet being added to the device
Charles Chanc22cef32016-04-29 14:38:22 -0700731 */
Pier Ventreb6a7f342016-11-26 21:05:22 -0800732 public void addSubnet(ConnectPoint cp, IpPrefix ipPrefix) {
Charles Chanc22cef32016-04-29 14:38:22 -0700733 checkNotNull(cp);
Pier Ventreb6a7f342016-11-26 21:05:22 -0800734 checkNotNull(ipPrefix);
Charles Chanc22cef32016-04-29 14:38:22 -0700735 SegmentRouterInfo srinfo = deviceConfigMap.get(cp.deviceId());
736 if (srinfo == null) {
737 log.warn("Device {} is not configured. Abort.", cp.deviceId());
738 return;
739 }
Pier Ventreb6a7f342016-11-26 21:05:22 -0800740 srinfo.subnets.put(cp.port(), ipPrefix);
Charles Chanc22cef32016-04-29 14:38:22 -0700741 }
742
743 /**
744 * Remove subnet from specific connect point.
745 *
746 * @param cp connect point
Pier Ventreb6a7f342016-11-26 21:05:22 -0800747 * @param ipPrefix subnet being removed to the device
Charles Chanc22cef32016-04-29 14:38:22 -0700748 */
Pier Ventreb6a7f342016-11-26 21:05:22 -0800749 public void removeSubnet(ConnectPoint cp, IpPrefix ipPrefix) {
Charles Chanc22cef32016-04-29 14:38:22 -0700750 checkNotNull(cp);
Pier Ventreb6a7f342016-11-26 21:05:22 -0800751 checkNotNull(ipPrefix);
Charles Chanc22cef32016-04-29 14:38:22 -0700752 SegmentRouterInfo srinfo = deviceConfigMap.get(cp.deviceId());
753 if (srinfo == null) {
754 log.warn("Device {} is not configured. Abort.", cp.deviceId());
755 return;
756 }
Pier Ventreb6a7f342016-11-26 21:05:22 -0800757 srinfo.subnets.remove(cp.port(), ipPrefix);
Charles Chanc22cef32016-04-29 14:38:22 -0700758 }
Charles Chan46fdfaf2016-11-09 20:51:44 -0800759
760 private boolean isSuppressedPort(ConnectPoint connectPoint) {
761 SegmentRoutingAppConfig appConfig = srManager.cfgService
Ray Milkeyb85de082017-04-05 09:42:04 -0700762 .getConfig(srManager.appId(), SegmentRoutingAppConfig.class);
Charles Chan46fdfaf2016-11-09 20:51:44 -0800763 if (appConfig != null && appConfig.suppressSubnet().contains(connectPoint)) {
Charles Chandebfea32016-10-24 14:52:01 -0700764 log.info("Interface configuration on port {} is ignored", connectPoint);
Charles Chan46fdfaf2016-11-09 20:51:44 -0800765 return true;
766 }
767 return false;
768 }
Saurav Das261c3002017-06-13 15:35:54 -0700769
770 public boolean isPairedEdge(DeviceId deviceId) throws DeviceConfigNotFoundException {
771 if (!isEdgeDevice(deviceId)) {
772 return false;
773 }
774 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
775 return (srinfo.pairDeviceId == null) ? false : true;
776 }
777
778 public DeviceId getPairDeviceId(DeviceId deviceId) throws DeviceConfigNotFoundException {
779 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
780 if (srinfo != null) {
781 return srinfo.pairDeviceId;
782 } else {
783 String message = "getPairDeviceId fails for device: " + deviceId + ".";
784 throw new DeviceConfigNotFoundException(message);
785 }
786 }
787
788 public PortNumber getPairLocalPort(DeviceId deviceId)
789 throws DeviceConfigNotFoundException {
790 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
791 if (srinfo != null) {
792 return srinfo.pairLocalPort;
793 } else {
794 String message = "getPairLocalPort fails for device: " + deviceId + ".";
795 throw new DeviceConfigNotFoundException(message);
796 }
797 }
798
Saurav Dasec683dc2018-04-27 18:42:30 -0700799 public boolean isPairLocalPort(DeviceId devId, PortNumber pnum) {
800 return pnum.equals(srManager.getPairLocalPort(devId).orElse(null));
801 }
Jonathan Hart8fa9ec52016-02-16 10:30:37 -0800802}