blob: db4bc636478611657bdb0ab9c939eba226016d3f [file] [log] [blame]
Thomas Vachuska58de4162015-09-10 16:15:33 -07001/*
Charles Chand6832882015-10-05 17:50:33 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska58de4162015-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 Chan0b4e6182015-11-03 10:42:14 -080016package org.onosproject.segmentrouting.config;
sanghob35a6192015-04-01 13:05:26 -070017
Charles Chan5270ed02016-01-30 23:22:37 -080018import com.google.common.collect.HashMultimap;
Charles Chan9f676b62015-10-29 14:58:10 -070019import com.google.common.collect.ImmutableSet;
Charles Chan5270ed02016-01-30 23:22:37 -080020import com.google.common.collect.SetMultimap;
sanghob35a6192015-04-01 13:05:26 -070021import org.onlab.packet.Ip4Address;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070022import org.onlab.packet.Ip4Prefix;
Charles Chan5270ed02016-01-30 23:22:37 -080023import org.onlab.packet.IpPrefix;
sanghob35a6192015-04-01 13:05:26 -070024import org.onlab.packet.MacAddress;
Charles Chane849c192016-01-11 18:28:54 -080025import org.onlab.packet.VlanId;
Charles Chan4636be02015-10-07 14:21:45 -070026import org.onosproject.incubator.net.config.basics.ConfigException;
27import org.onosproject.incubator.net.config.basics.InterfaceConfig;
28import org.onosproject.incubator.net.intf.Interface;
29import org.onosproject.net.ConnectPoint;
Charles Chand6832882015-10-05 17:50:33 -070030import org.onosproject.net.config.NetworkConfigRegistry;
Charles Chan4636be02015-10-07 14:21:45 -070031import org.onosproject.net.host.InterfaceIpAddress;
sanghob35a6192015-04-01 13:05:26 -070032import org.onosproject.net.DeviceId;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070033import org.onosproject.net.PortNumber;
sanghob35a6192015-04-01 13:05:26 -070034import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
36
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070037import java.util.ArrayList;
sanghob35a6192015-04-01 13:05:26 -070038import java.util.HashMap;
Charles Chan531a78b2015-12-01 10:00:51 -080039import java.util.HashSet;
Charles Chane849c192016-01-11 18:28:54 -080040import java.util.LinkedList;
sanghob35a6192015-04-01 13:05:26 -070041import java.util.List;
42import java.util.Map;
Charles Chan5270ed02016-01-30 23:22:37 -080043import java.util.Optional;
Charles Chand6832882015-10-05 17:50:33 -070044import java.util.Set;
Saurav Das0e99e2b2015-10-28 12:39:42 -070045import java.util.concurrent.ConcurrentHashMap;
sanghob35a6192015-04-01 13:05:26 -070046
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070047/**
48 * Segment Routing configuration component that reads the
49 * segment routing related configuration from Network Configuration Manager
50 * component and organizes in more accessible formats.
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070051 */
sanghob35a6192015-04-01 13:05:26 -070052public class DeviceConfiguration implements DeviceProperties {
53
54 private static final Logger log = LoggerFactory
55 .getLogger(DeviceConfiguration.class);
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -070056 private final List<Integer> allSegmentIds = new ArrayList<>();
Charles Chane849c192016-01-11 18:28:54 -080057 private final Map<DeviceId, SegmentRouterInfo> deviceConfigMap = new ConcurrentHashMap<>();
58 private final Map<VlanId, List<ConnectPoint>> xConnects = new ConcurrentHashMap<>();
sanghob35a6192015-04-01 13:05:26 -070059
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070060 private class SegmentRouterInfo {
61 int nodeSid;
62 DeviceId deviceId;
63 Ip4Address ip;
64 MacAddress mac;
65 boolean isEdge;
Charles Chan5270ed02016-01-30 23:22:37 -080066 Map<PortNumber, Ip4Address> gatewayIps;
67 SetMultimap<PortNumber, Ip4Prefix> subnets;
Charles Chan531a78b2015-12-01 10:00:51 -080068 Map<Integer, Set<Integer>> adjacencySids;
Charles Chanb8e10c82015-10-14 11:24:40 -070069
70 public SegmentRouterInfo() {
Charles Chane849c192016-01-11 18:28:54 -080071 gatewayIps = new HashMap<>();
Charles Chan5270ed02016-01-30 23:22:37 -080072 subnets = HashMultimap.create();
Charles Chanb8e10c82015-10-14 11:24:40 -070073 }
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070074 }
sanghob35a6192015-04-01 13:05:26 -070075
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070076 /**
Charles Chane849c192016-01-11 18:28:54 -080077 * Constructs device configuration for all Segment Router devices,
78 * organizing the data into various maps for easier access.
Brian O'Connor52515622015-10-09 17:03:44 -070079 *
80 * @param cfgService config service
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070081 */
Charles Chand6832882015-10-05 17:50:33 -070082 public DeviceConfiguration(NetworkConfigRegistry cfgService) {
Charles Chan4636be02015-10-07 14:21:45 -070083 // Read config from device subject, excluding gatewayIps and subnets.
84 Set<DeviceId> deviceSubjects =
Charles Chan5270ed02016-01-30 23:22:37 -080085 cfgService.getSubjects(DeviceId.class, SegmentRoutingDeviceConfig.class);
Charles Chan4636be02015-10-07 14:21:45 -070086 deviceSubjects.forEach(subject -> {
Charles Chan5270ed02016-01-30 23:22:37 -080087 SegmentRoutingDeviceConfig config =
88 cfgService.getConfig(subject, SegmentRoutingDeviceConfig.class);
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070089 SegmentRouterInfo info = new SegmentRouterInfo();
Charles Chand6832882015-10-05 17:50:33 -070090 info.deviceId = subject;
Charles Chan531a78b2015-12-01 10:00:51 -080091 info.nodeSid = config.nodeSid();
92 info.ip = config.routerIp();
93 info.mac = config.routerMac();
Charles Chand6832882015-10-05 17:50:33 -070094 info.isEdge = config.isEdgeRouter();
Charles Chan531a78b2015-12-01 10:00:51 -080095 info.adjacencySids = config.adjacencySids();
Charles Chand6832882015-10-05 17:50:33 -070096
Charles Chane849c192016-01-11 18:28:54 -080097 deviceConfigMap.put(info.deviceId, info);
98 allSegmentIds.add(info.nodeSid);
Charles Chand6832882015-10-05 17:50:33 -070099 });
Charles Chan4636be02015-10-07 14:21:45 -0700100
101 // Read gatewayIps and subnets from port subject.
102 Set<ConnectPoint> portSubjects =
103 cfgService.getSubjects(ConnectPoint.class, InterfaceConfig.class);
104 portSubjects.forEach(subject -> {
105 InterfaceConfig config =
106 cfgService.getConfig(subject, InterfaceConfig.class);
107 Set<Interface> networkInterfaces;
108 try {
109 networkInterfaces = config.getInterfaces();
110 } catch (ConfigException e) {
111 log.error("Error loading port configuration");
112 return;
113 }
114 networkInterfaces.forEach(networkInterface -> {
Charles Chane849c192016-01-11 18:28:54 -0800115 VlanId vlanId = networkInterface.vlan();
116 ConnectPoint connectPoint = networkInterface.connectPoint();
117 DeviceId dpid = connectPoint.deviceId();
118 PortNumber port = connectPoint.port();
119 SegmentRouterInfo info = deviceConfigMap.get(dpid);
Charles Chan4636be02015-10-07 14:21:45 -0700120
Charles Chanb8e10c82015-10-14 11:24:40 -0700121 // skip if there is no corresponding device for this ConenctPoint
122 if (info != null) {
Charles Chane849c192016-01-11 18:28:54 -0800123 // Extract subnet information
Charles Chanb8e10c82015-10-14 11:24:40 -0700124 Set<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddresses();
125 interfaceAddresses.forEach(interfaceAddress -> {
Charles Chan5270ed02016-01-30 23:22:37 -0800126 // Do not add /0 and /32 to gateway IP list
127 int prefixLength = interfaceAddress.subnetAddress().prefixLength();
128 if (prefixLength != 0 && prefixLength != IpPrefix.MAX_INET_MASK_LENGTH) {
129 info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address());
130 }
Charles Chanb8e10c82015-10-14 11:24:40 -0700131 info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix());
132 });
Charles Chane849c192016-01-11 18:28:54 -0800133
134 // Extract VLAN cross-connect information
135 // Do not setup cross-connect if VLAN is NONE
136 if (vlanId.equals(VlanId.NONE)) {
137 return;
138 }
139 List<ConnectPoint> connectPoints = xConnects.get(vlanId);
140 if (connectPoints != null) {
141 if (connectPoints.size() != 1) {
142 log.warn("Cross-connect should only have two endpoints. Aborting.");
143 return;
144 }
145 if (!connectPoints.get(0).deviceId().equals(connectPoint.deviceId())) {
146 log.warn("Cross-connect endpoints must be on the same switch. Aborting.");
147 return;
148 }
149 connectPoints.add(connectPoint);
150 } else {
151 connectPoints = new LinkedList<>();
152 connectPoints.add(connectPoint);
153 xConnects.put(vlanId, connectPoints);
154 }
Charles Chanb8e10c82015-10-14 11:24:40 -0700155 }
Charles Chan4636be02015-10-07 14:21:45 -0700156 });
157
158 });
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700159 }
160
sanghob35a6192015-04-01 13:05:26 -0700161 @Override
Charles Chan0b4e6182015-11-03 10:42:14 -0800162 public boolean isConfigured(DeviceId deviceId) {
163 return deviceConfigMap.get(deviceId) != null;
164 }
165
166 @Override
167 public int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException {
Saurav Das0e99e2b2015-10-28 12:39:42 -0700168 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
169 if (srinfo != null) {
170 log.trace("getSegmentId for device{} is {}", deviceId, srinfo.nodeSid);
171 return srinfo.nodeSid;
sanghob35a6192015-04-01 13:05:26 -0700172 } else {
Charles Chan0b4e6182015-11-03 10:42:14 -0800173 String message = "getSegmentId fails for device: " + deviceId + ".";
174 throw new DeviceConfigNotFoundException(message);
sanghob35a6192015-04-01 13:05:26 -0700175 }
176 }
177
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700178 /**
Saurav Das822c4e22015-10-23 10:51:11 -0700179 * Returns the Node segment id of a segment router given its Router mac address.
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700180 *
181 * @param routerMac router mac address
Saurav Das0e99e2b2015-10-28 12:39:42 -0700182 * @return node segment id, or -1 if not found in config
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700183 */
184 public int getSegmentId(MacAddress routerMac) {
185 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
186 deviceConfigMap.entrySet()) {
187 if (entry.getValue().mac.equals(routerMac)) {
188 return entry.getValue().nodeSid;
189 }
190 }
sanghob35a6192015-04-01 13:05:26 -0700191
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700192 return -1;
193 }
194
195 /**
Saurav Das822c4e22015-10-23 10:51:11 -0700196 * Returns the Node segment id of a segment router given its Router ip address.
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700197 *
198 * @param routerAddress router ip address
Saurav Das0e99e2b2015-10-28 12:39:42 -0700199 * @return node segment id, or -1 if not found in config
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700200 */
201 public int getSegmentId(Ip4Address routerAddress) {
202 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
203 deviceConfigMap.entrySet()) {
204 if (entry.getValue().ip.equals(routerAddress)) {
205 return entry.getValue().nodeSid;
206 }
207 }
208
209 return -1;
210 }
211
sanghob35a6192015-04-01 13:05:26 -0700212 @Override
Charles Chan0b4e6182015-11-03 10:42:14 -0800213 public MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException {
Saurav Das0e99e2b2015-10-28 12:39:42 -0700214 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
215 if (srinfo != null) {
216 log.trace("getDeviceMac for device{} is {}", deviceId, srinfo.mac);
217 return srinfo.mac;
sanghob35a6192015-04-01 13:05:26 -0700218 } else {
Charles Chan0b4e6182015-11-03 10:42:14 -0800219 String message = "getDeviceMac fails for device: " + deviceId + ".";
220 throw new DeviceConfigNotFoundException(message);
sanghob35a6192015-04-01 13:05:26 -0700221 }
222 }
223
Charles Chan0b4e6182015-11-03 10:42:14 -0800224 @Override
225 public Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException {
Saurav Das0e99e2b2015-10-28 12:39:42 -0700226 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
227 if (srinfo != null) {
228 log.trace("getDeviceIp for device{} is {}", deviceId, srinfo.ip);
229 return srinfo.ip;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700230 } else {
Charles Chan0b4e6182015-11-03 10:42:14 -0800231 String message = "getRouterIp fails for device: " + deviceId + ".";
232 throw new DeviceConfigNotFoundException(message);
sanghob35a6192015-04-01 13:05:26 -0700233 }
sanghob35a6192015-04-01 13:05:26 -0700234 }
235
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700236 @Override
Charles Chan0b4e6182015-11-03 10:42:14 -0800237 public boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException {
Saurav Das0e99e2b2015-10-28 12:39:42 -0700238 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
239 if (srinfo != null) {
240 log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge);
241 return srinfo.isEdge;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700242 } else {
Charles Chan0b4e6182015-11-03 10:42:14 -0800243 String message = "isEdgeDevice fails for device: " + deviceId + ".";
244 throw new DeviceConfigNotFoundException(message);
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700245 }
246 }
247
sanghob35a6192015-04-01 13:05:26 -0700248 @Override
249 public List<Integer> getAllDeviceSegmentIds() {
250 return allSegmentIds;
251 }
252
Charles Chanc42e84e2015-10-20 16:24:19 -0700253 @Override
254 public Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId) {
255 Map<Ip4Prefix, List<PortNumber>> subnetPortMap = new HashMap<>();
256
257 // Construct subnet-port mapping from port-subnet mapping
Charles Chan5270ed02016-01-30 23:22:37 -0800258 SetMultimap<PortNumber, Ip4Prefix> portSubnetMap =
Charles Chanc42e84e2015-10-20 16:24:19 -0700259 this.deviceConfigMap.get(deviceId).subnets;
Charles Chan5270ed02016-01-30 23:22:37 -0800260
261 portSubnetMap.entries().forEach(entry -> {
262 PortNumber port = entry.getKey();
263 Ip4Prefix subnet = entry.getValue();
264
Charles Chanc42e84e2015-10-20 16:24:19 -0700265 if (subnetPortMap.containsKey(subnet)) {
266 subnetPortMap.get(subnet).add(port);
267 } else {
268 ArrayList<PortNumber> ports = new ArrayList<>();
269 ports.add(port);
270 subnetPortMap.put(subnet, ports);
271 }
272 });
Charles Chanc42e84e2015-10-20 16:24:19 -0700273 return subnetPortMap;
274 }
275
Charles Chane849c192016-01-11 18:28:54 -0800276 @Override
277 public Map<VlanId, List<ConnectPoint>> getXConnects() {
278 return xConnects;
279 }
280
sanghob35a6192015-04-01 13:05:26 -0700281 /**
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700282 * Returns the device identifier or data plane identifier (dpid)
283 * of a segment router given its segment id.
sanghob35a6192015-04-01 13:05:26 -0700284 *
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700285 * @param sid segment id
286 * @return deviceId device identifier
sanghob35a6192015-04-01 13:05:26 -0700287 */
288 public DeviceId getDeviceId(int sid) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700289 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
290 deviceConfigMap.entrySet()) {
291 if (entry.getValue().nodeSid == sid) {
292 return entry.getValue().deviceId;
sanghob35a6192015-04-01 13:05:26 -0700293 }
294 }
295
296 return null;
297 }
298
299 /**
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700300 * Returns the device identifier or data plane identifier (dpid)
301 * of a segment router given its router ip address.
sanghob35a6192015-04-01 13:05:26 -0700302 *
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700303 * @param ipAddress router ip address
304 * @return deviceId device identifier
sanghob35a6192015-04-01 13:05:26 -0700305 */
306 public DeviceId getDeviceId(Ip4Address ipAddress) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700307 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
308 deviceConfigMap.entrySet()) {
309 if (entry.getValue().ip.equals(ipAddress)) {
310 return entry.getValue().deviceId;
sanghob35a6192015-04-01 13:05:26 -0700311 }
312 }
313
314 return null;
315 }
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700316
317 /**
Saurav Das822c4e22015-10-23 10:51:11 -0700318 * Returns the configured port ip addresses for a segment router.
319 * These addresses serve as gateway IP addresses for the subnets configured
320 * on those ports.
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700321 *
322 * @param deviceId device identifier
Saurav Das837e0bb2015-10-30 17:45:38 -0700323 * @return immutable set of ip addresses configured on the ports or null if not found
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700324 */
Saurav Das837e0bb2015-10-30 17:45:38 -0700325 public Set<Ip4Address> getPortIPs(DeviceId deviceId) {
Saurav Das0e99e2b2015-10-28 12:39:42 -0700326 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
327 if (srinfo != null) {
328 log.trace("getSubnetGatewayIps for device{} is {}", deviceId,
329 srinfo.gatewayIps.values());
Saurav Das837e0bb2015-10-30 17:45:38 -0700330 return ImmutableSet.copyOf(srinfo.gatewayIps.values());
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700331 }
Saurav Das0e99e2b2015-10-28 12:39:42 -0700332 return null;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700333 }
334
335 /**
336 * Returns the configured subnet prefixes for a segment router.
337 *
338 * @param deviceId device identifier
Saurav Das0e99e2b2015-10-28 12:39:42 -0700339 * @return list of ip prefixes or null if not found
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700340 */
Charles Chan9f676b62015-10-29 14:58:10 -0700341 public Set<Ip4Prefix> getSubnets(DeviceId deviceId) {
Saurav Das0e99e2b2015-10-28 12:39:42 -0700342 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
343 if (srinfo != null) {
344 log.trace("getSubnets for device{} is {}", deviceId,
345 srinfo.subnets.values());
Charles Chan9f676b62015-10-29 14:58:10 -0700346 return ImmutableSet.copyOf(srinfo.subnets.values());
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700347 }
Saurav Das0e99e2b2015-10-28 12:39:42 -0700348 return null;
349 }
350
351 /**
Charles Chan5270ed02016-01-30 23:22:37 -0800352 * Returns the configured non-/32 and non-/0 subnet on the given port,
353 * or null if no subnet has been configured on the port.
Saurav Das0e99e2b2015-10-28 12:39:42 -0700354 *
355 * @param deviceId device identifier
356 * @param pnum port identifier
357 * @return configured subnet on port, or null
358 */
359 public Ip4Prefix getPortSubnet(DeviceId deviceId, PortNumber pnum) {
360 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
361 if (srinfo != null) {
Charles Chan5270ed02016-01-30 23:22:37 -0800362 Optional<Ip4Prefix> result = srinfo.subnets.get(pnum).stream()
363 .filter(subnet ->
364 subnet.getIp4Prefix().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH &&
365 subnet.getIp4Prefix().prefixLength() != 0)
366 .findFirst();
367 return (result.isPresent()) ? result.get() : null;
Saurav Das0e99e2b2015-10-28 12:39:42 -0700368 }
369 return null;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700370 }
371
372 /**
373 * Returns the router ip address of segment router that has the
374 * specified ip address in its subnets.
375 *
376 * @param destIpAddress target ip address
377 * @return router ip address
378 */
379 public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) {
380 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
381 deviceConfigMap.entrySet()) {
Charles Chan5270ed02016-01-30 23:22:37 -0800382 for (Ip4Prefix prefix : entry.getValue().subnets.values()) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700383 if (prefix.contains(destIpAddress)) {
384 return entry.getValue().ip;
385 }
386 }
387 }
388
389 log.debug("No router was found for {}", destIpAddress);
390 return null;
391 }
392
393 /**
394 * Returns the router mac address of segment router that has the
395 * specified ip address as one of its subnet gateway ip address.
396 *
397 * @param gatewayIpAddress router gateway ip address
Saurav Das0e99e2b2015-10-28 12:39:42 -0700398 * @return router mac address or null if not found
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700399 */
400 public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) {
401 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
402 deviceConfigMap.entrySet()) {
403 if (entry.getValue().gatewayIps.
404 values().contains(gatewayIpAddress)) {
405 return entry.getValue().mac;
406 }
407 }
408
409 log.debug("Cannot find a router for {}", gatewayIpAddress);
410 return null;
411 }
sangho666cd6d2015-04-14 16:27:13 -0700412
413
414 /**
415 * Checks if the host is in the subnet defined in the router with the
416 * device ID given.
417 *
418 * @param deviceId device identification of the router
419 * @param hostIp host IP address to check
420 * @return true if the host is within the subnet of the router,
421 * false if no subnet is defined under the router or if the host is not
422 * within the subnet defined in the router
423 */
424 public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) {
425
Charles Chan9f676b62015-10-29 14:58:10 -0700426 Set<Ip4Prefix> subnets = getSubnets(deviceId);
sangho666cd6d2015-04-14 16:27:13 -0700427 if (subnets == null) {
428 return false;
429 }
430
431 for (Ip4Prefix subnet: subnets) {
Charles Chan5270ed02016-01-30 23:22:37 -0800432 // Exclude /0 since it is a special case used for default route
433 if (subnet.prefixLength() != 0 && subnet.contains(hostIp)) {
sangho666cd6d2015-04-14 16:27:13 -0700434 return true;
435 }
436 }
437
438 return false;
439 }
sangho1e575652015-05-14 00:39:53 -0700440
441 /**
442 * Returns the ports corresponding to the adjacency Sid given.
443 *
444 * @param deviceId device identification of the router
445 * @param sid adjacency Sid
Charles Chan531a78b2015-12-01 10:00:51 -0800446 * @return set of port numbers
sangho1e575652015-05-14 00:39:53 -0700447 */
Charles Chan531a78b2015-12-01 10:00:51 -0800448 public Set<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
Saurav Das0e99e2b2015-10-28 12:39:42 -0700449 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
Charles Chan531a78b2015-12-01 10:00:51 -0800450 return srinfo != null ?
451 ImmutableSet.copyOf(srinfo.adjacencySids.get(sid)) :
452 ImmutableSet.copyOf(new HashSet<>());
sangho1e575652015-05-14 00:39:53 -0700453 }
454
455 /**
456 * Check if the Sid given is whether adjacency Sid of the router device or not.
457 *
458 * @param deviceId device identification of the router
459 * @param sid Sid to check
460 * @return true if the Sid given is the adjacency Sid of the device,
461 * otherwise false
462 */
463 public boolean isAdjacencySid(DeviceId deviceId, int sid) {
Saurav Das0e99e2b2015-10-28 12:39:42 -0700464 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
Charles Chan531a78b2015-12-01 10:00:51 -0800465 return srinfo != null && srinfo.adjacencySids.containsKey(sid);
sangho1e575652015-05-14 00:39:53 -0700466 }
Charles Chand6832882015-10-05 17:50:33 -0700467}