2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.segmentrouting;
18 import com.google.common.collect.Lists;
19 import org.onlab.packet.Ip4Address;
20 import org.onlab.packet.Ip4Prefix;
21 import org.onlab.packet.IpPrefix;
22 import org.onlab.packet.MacAddress;
23 import org.onosproject.segmentrouting.grouphandler.DeviceProperties;
24 import org.onosproject.net.DeviceId;
25 import org.onosproject.net.PortNumber;
26 import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig;
27 import org.onosproject.segmentrouting.config.NetworkConfigManager;
28 import org.onosproject.segmentrouting.config.SegmentRouterConfig;
29 import org.onosproject.segmentrouting.config.SegmentRouterConfig.Subnet;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 import static com.google.common.base.Preconditions.checkNotNull;
35 import java.util.ArrayList;
36 import java.util.HashMap;
37 import java.util.List;
41 * Segment Routing configuration component that reads the
42 * segment routing related configuration from Network Configuration Manager
43 * component and organizes in more accessible formats.
45 * TODO: Merge multiple Segment Routing configuration wrapper classes into one.
47 public class DeviceConfiguration implements DeviceProperties {
49 private static final Logger log = LoggerFactory
50 .getLogger(DeviceConfiguration.class);
51 private final List<Integer> allSegmentIds = new ArrayList<>();
52 private final HashMap<DeviceId, SegmentRouterInfo> deviceConfigMap = new HashMap<>();
53 private final NetworkConfigManager configService;
55 private class SegmentRouterInfo {
61 HashMap<PortNumber, Ip4Address> gatewayIps;
62 HashMap<PortNumber, Ip4Prefix> subnets;
63 List<SegmentRouterConfig.AdjacencySid> adjacencySids;
67 * Constructor. Reads all the configuration for all devices of type
68 * Segment Router and organizes into various maps for easier access.
70 * @param configService handle to network configuration manager
71 * component from where the relevant configuration is retrieved.
73 public DeviceConfiguration(NetworkConfigManager configService) {
74 this.configService = checkNotNull(configService);
75 List<SwitchConfig> allSwitchCfg =
76 this.configService.getConfiguredAllowedSwitches();
77 for (SwitchConfig cfg : allSwitchCfg) {
78 if (!(cfg instanceof SegmentRouterConfig)) {
81 SegmentRouterInfo info = new SegmentRouterInfo();
82 info.nodeSid = ((SegmentRouterConfig) cfg).getNodeSid();
83 info.deviceId = ((SegmentRouterConfig) cfg).getDpid();
84 info.mac = MacAddress.valueOf(((
85 SegmentRouterConfig) cfg).getRouterMac());
86 String routerIp = ((SegmentRouterConfig) cfg).getRouterIp();
87 Ip4Prefix prefix = checkNotNull(IpPrefix.valueOf(routerIp).getIp4Prefix());
88 info.ip = prefix.address();
89 info.isEdge = ((SegmentRouterConfig) cfg).isEdgeRouter();
90 info.subnets = new HashMap<>();
91 info.gatewayIps = new HashMap<>();
92 for (Subnet s: ((SegmentRouterConfig) cfg).getSubnets()) {
93 info.subnets.put(PortNumber.portNumber(s.getPortNo()),
94 Ip4Prefix.valueOf(s.getSubnetIp()));
95 String gatewayIp = s.getSubnetIp().
96 substring(0, s.getSubnetIp().indexOf('/'));
97 info.gatewayIps.put(PortNumber.portNumber(s.getPortNo()),
98 Ip4Address.valueOf(gatewayIp));
100 info.adjacencySids = ((SegmentRouterConfig) cfg).getAdjacencySids();
101 this.deviceConfigMap.put(info.deviceId, info);
102 this.allSegmentIds.add(info.nodeSid);
108 * Returns the segment id of a segment router.
110 * @param deviceId device identifier
114 public int getSegmentId(DeviceId deviceId) {
115 if (deviceConfigMap.get(deviceId) != null) {
116 log.debug("getSegmentId for device{} is {}",
118 deviceConfigMap.get(deviceId).nodeSid);
119 return deviceConfigMap.get(deviceId).nodeSid;
121 log.warn("getSegmentId for device {} "
122 + "throwing IllegalStateException "
123 + "because device does not exist in config", deviceId);
124 throw new IllegalStateException();
129 * Returns the segment id of a segment router given its mac address.
131 * @param routerMac router mac address
134 public int getSegmentId(MacAddress routerMac) {
135 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
136 deviceConfigMap.entrySet()) {
137 if (entry.getValue().mac.equals(routerMac)) {
138 return entry.getValue().nodeSid;
146 * Returns the segment id of a segment router given its router ip address.
148 * @param routerAddress router ip address
151 public int getSegmentId(Ip4Address routerAddress) {
152 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
153 deviceConfigMap.entrySet()) {
154 if (entry.getValue().ip.equals(routerAddress)) {
155 return entry.getValue().nodeSid;
163 * Returns the router mac of a segment router.
165 * @param deviceId device identifier
166 * @return router mac address
169 public MacAddress getDeviceMac(DeviceId deviceId) {
170 if (deviceConfigMap.get(deviceId) != null) {
171 log.debug("getDeviceMac for device{} is {}",
173 deviceConfigMap.get(deviceId).mac);
174 return deviceConfigMap.get(deviceId).mac;
176 log.warn("getDeviceMac for device {} "
177 + "throwing IllegalStateException "
178 + "because device does not exist in config", deviceId);
179 throw new IllegalStateException();
184 * Returns the router ip address of a segment router.
186 * @param deviceId device identifier
187 * @return router ip address
189 public Ip4Address getRouterIp(DeviceId deviceId) {
190 if (deviceConfigMap.get(deviceId) != null) {
191 log.debug("getDeviceIp for device{} is {}",
193 deviceConfigMap.get(deviceId).ip);
194 return deviceConfigMap.get(deviceId).ip;
196 log.warn("getRouterIp for device {} "
197 + "throwing IllegalStateException "
198 + "because device does not exist in config", deviceId);
199 throw new IllegalStateException();
204 * Indicates if the segment router is a edge router or
205 * a transit/back bone router.
207 * @param deviceId device identifier
211 public boolean isEdgeDevice(DeviceId deviceId) {
212 if (deviceConfigMap.get(deviceId) != null) {
213 log.debug("isEdgeDevice for device{} is {}",
215 deviceConfigMap.get(deviceId).isEdge);
216 return deviceConfigMap.get(deviceId).isEdge;
218 log.warn("isEdgeDevice for device {} "
219 + "throwing IllegalStateException "
220 + "because device does not exist in config", deviceId);
221 throw new IllegalStateException();
226 * Returns the segment ids of all configured segment routers.
228 * @return list of segment ids
231 public List<Integer> getAllDeviceSegmentIds() {
232 return allSegmentIds;
236 * Returns the device identifier or data plane identifier (dpid)
237 * of a segment router given its segment id.
239 * @param sid segment id
240 * @return deviceId device identifier
242 public DeviceId getDeviceId(int sid) {
243 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
244 deviceConfigMap.entrySet()) {
245 if (entry.getValue().nodeSid == sid) {
246 return entry.getValue().deviceId;
254 * Returns the device identifier or data plane identifier (dpid)
255 * of a segment router given its router ip address.
257 * @param ipAddress router ip address
258 * @return deviceId device identifier
260 public DeviceId getDeviceId(Ip4Address ipAddress) {
261 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
262 deviceConfigMap.entrySet()) {
263 if (entry.getValue().ip.equals(ipAddress)) {
264 return entry.getValue().deviceId;
272 * Returns the configured subnet gateway ip addresses for a segment router.
274 * @param deviceId device identifier
275 * @return list of ip addresses
277 public List<Ip4Address> getSubnetGatewayIps(DeviceId deviceId) {
278 if (deviceConfigMap.get(deviceId) != null) {
279 log.debug("getSubnetGatewayIps for device{} is {}",
281 deviceConfigMap.get(deviceId).gatewayIps.values());
282 return new ArrayList<>(deviceConfigMap.get(deviceId).gatewayIps.values());
289 * Returns the configured subnet prefixes for a segment router.
291 * @param deviceId device identifier
292 * @return list of ip prefixes
294 public List<Ip4Prefix> getSubnets(DeviceId deviceId) {
295 if (deviceConfigMap.get(deviceId) != null) {
296 log.debug("getSubnets for device{} is {}",
298 deviceConfigMap.get(deviceId).subnets.values());
299 return new ArrayList<>(deviceConfigMap.get(deviceId).subnets.values());
306 * Returns the router ip address of segment router that has the
307 * specified ip address in its subnets.
309 * @param destIpAddress target ip address
310 * @return router ip address
312 public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) {
313 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
314 deviceConfigMap.entrySet()) {
315 for (Ip4Prefix prefix:entry.getValue().subnets.values()) {
316 if (prefix.contains(destIpAddress)) {
317 return entry.getValue().ip;
322 log.debug("No router was found for {}", destIpAddress);
327 * Returns the router mac address of segment router that has the
328 * specified ip address as one of its subnet gateway ip address.
330 * @param gatewayIpAddress router gateway ip address
331 * @return router mac address
333 public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) {
334 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
335 deviceConfigMap.entrySet()) {
336 if (entry.getValue().gatewayIps.
337 values().contains(gatewayIpAddress)) {
338 return entry.getValue().mac;
342 log.debug("Cannot find a router for {}", gatewayIpAddress);
348 * Checks if the host is in the subnet defined in the router with the
351 * @param deviceId device identification of the router
352 * @param hostIp host IP address to check
353 * @return true if the host is within the subnet of the router,
354 * false if no subnet is defined under the router or if the host is not
355 * within the subnet defined in the router
357 public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) {
359 List<Ip4Prefix> subnets = getSubnets(deviceId);
360 if (subnets == null) {
364 for (Ip4Prefix subnet: subnets) {
365 if (subnet.contains(hostIp)) {
374 * Returns the ports corresponding to the adjacency Sid given.
376 * @param deviceId device identification of the router
377 * @param sid adjacency Sid
378 * @return list of port numbers
380 public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
381 if (deviceConfigMap.get(deviceId) != null) {
382 for (SegmentRouterConfig.AdjacencySid asid : deviceConfigMap.get(deviceId).adjacencySids) {
383 if (asid.getAdjSid() == sid) {
384 return asid.getPorts();
389 return Lists.newArrayList();
393 * Check if the Sid given is whether adjacency Sid of the router device or not.
395 * @param deviceId device identification of the router
396 * @param sid Sid to check
397 * @return true if the Sid given is the adjacency Sid of the device,
400 public boolean isAdjacencySid(DeviceId deviceId, int sid) {
401 if (deviceConfigMap.get(deviceId) != null) {
402 if (deviceConfigMap.get(deviceId).adjacencySids.isEmpty()) {
405 for (SegmentRouterConfig.AdjacencySid asid:
406 deviceConfigMap.get(deviceId).adjacencySids) {
407 if (asid.getAdjSid() == sid) {