blob: 0dfb3fda8c599f32f65474d2af1aa602d44a33e1 [file] [log] [blame]
sanghob35a6192015-04-01 13:05:26 -07001package org.onosproject.segmentrouting;
2
3import org.onlab.packet.Ip4Address;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -07004import org.onlab.packet.Ip4Prefix;
5import org.onlab.packet.IpPrefix;
sanghob35a6192015-04-01 13:05:26 -07006import org.onlab.packet.MacAddress;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -07007import org.onosproject.segmentrouting.grouphandler.DeviceProperties;
sanghob35a6192015-04-01 13:05:26 -07008import org.onosproject.net.DeviceId;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -07009import org.onosproject.net.PortNumber;
10import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig;
11import org.onosproject.segmentrouting.config.NetworkConfigManager;
12import org.onosproject.segmentrouting.config.SegmentRouterConfig;
13import org.onosproject.segmentrouting.config.SegmentRouterConfig.Subnet;
sanghob35a6192015-04-01 13:05:26 -070014import org.slf4j.Logger;
15import org.slf4j.LoggerFactory;
16
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070017import static com.google.common.base.Preconditions.checkNotNull;
18
19import java.util.ArrayList;
sanghob35a6192015-04-01 13:05:26 -070020import java.util.HashMap;
21import java.util.List;
22import java.util.Map;
23
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070024/**
25 * Segment Routing configuration component that reads the
26 * segment routing related configuration from Network Configuration Manager
27 * component and organizes in more accessible formats.
28 *
29 * TODO: Merge multiple Segment Routing configuration wrapper classes into one.
30 */
sanghob35a6192015-04-01 13:05:26 -070031public class DeviceConfiguration implements DeviceProperties {
32
33 private static final Logger log = LoggerFactory
34 .getLogger(DeviceConfiguration.class);
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070035 private final List<Integer> allSegmentIds = new ArrayList<Integer>();
36 private final HashMap<DeviceId, SegmentRouterInfo> deviceConfigMap = new HashMap<>();
37 private final NetworkConfigManager configService;
sanghob35a6192015-04-01 13:05:26 -070038
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070039 private class SegmentRouterInfo {
40 int nodeSid;
41 DeviceId deviceId;
42 Ip4Address ip;
43 MacAddress mac;
44 boolean isEdge;
45 HashMap<PortNumber, Ip4Address> gatewayIps;
46 HashMap<PortNumber, Ip4Prefix> subnets;
47 }
sanghob35a6192015-04-01 13:05:26 -070048
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070049 /**
50 * Constructor. Reads all the configuration for all devices of type
51 * Segment Router and organizes into various maps for easier access.
52 *
53 * @param configService handle to network configuration manager
54 * component from where the relevant configuration is retrieved.
55 */
56 public DeviceConfiguration(NetworkConfigManager configService) {
57 this.configService = checkNotNull(configService);
58 List<SwitchConfig> allSwitchCfg =
59 this.configService.getConfiguredAllowedSwitches();
60 for (SwitchConfig cfg : allSwitchCfg) {
61 if (!(cfg instanceof SegmentRouterConfig)) {
62 continue;
63 }
64 SegmentRouterInfo info = new SegmentRouterInfo();
65 info.nodeSid = ((SegmentRouterConfig) cfg).getNodeSid();
66 info.deviceId = ((SegmentRouterConfig) cfg).getDpid();
67 info.mac = MacAddress.valueOf(((
68 SegmentRouterConfig) cfg).getRouterMac());
69 String routerIp = ((SegmentRouterConfig) cfg).getRouterIp();
70 Ip4Prefix prefix = checkNotNull(IpPrefix.valueOf(routerIp).getIp4Prefix());
71 info.ip = prefix.address();
72 info.isEdge = ((SegmentRouterConfig) cfg).isEdgeRouter();
73 info.subnets = new HashMap<>();
74 info.gatewayIps = new HashMap<PortNumber, Ip4Address>();
75 for (Subnet s: ((SegmentRouterConfig) cfg).getSubnets()) {
76 info.subnets.put(PortNumber.portNumber(s.getPortNo()),
77 Ip4Prefix.valueOf(s.getSubnetIp()));
78 String gatewayIp = s.getSubnetIp().
79 substring(0, s.getSubnetIp().indexOf('/'));
80 info.gatewayIps.put(PortNumber.portNumber(s.getPortNo()),
81 Ip4Address.valueOf(gatewayIp));
82 }
83 this.deviceConfigMap.put(info.deviceId, info);
84 this.allSegmentIds.add(info.nodeSid);
85 }
86 }
87
88 /**
89 * Returns the segment id of a segment router.
90 *
91 * @param deviceId device identifier
92 * @return segment id
93 */
sanghob35a6192015-04-01 13:05:26 -070094 @Override
95 public int getSegmentId(DeviceId deviceId) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070096 if (deviceConfigMap.get(deviceId) != null) {
sanghob35a6192015-04-01 13:05:26 -070097 log.debug("getSegmentId for device{} is {}",
98 deviceId,
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070099 deviceConfigMap.get(deviceId).nodeSid);
100 return deviceConfigMap.get(deviceId).nodeSid;
sanghob35a6192015-04-01 13:05:26 -0700101 } else {
102 throw new IllegalStateException();
103 }
104 }
105
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700106 /**
107 * Returns the segment id of a segment router given its mac address.
108 *
109 * @param routerMac router mac address
110 * @return segment id
111 */
112 public int getSegmentId(MacAddress routerMac) {
113 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
114 deviceConfigMap.entrySet()) {
115 if (entry.getValue().mac.equals(routerMac)) {
116 return entry.getValue().nodeSid;
117 }
118 }
sanghob35a6192015-04-01 13:05:26 -0700119
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700120 return -1;
121 }
122
123 /**
124 * Returns the segment id of a segment router given its router ip address.
125 *
126 * @param routerAddress router ip address
127 * @return segment id
128 */
129 public int getSegmentId(Ip4Address routerAddress) {
130 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
131 deviceConfigMap.entrySet()) {
132 if (entry.getValue().ip.equals(routerAddress)) {
133 return entry.getValue().nodeSid;
134 }
135 }
136
137 return -1;
138 }
139
140 /**
141 * Returns the router mac of a segment router.
142 *
143 * @param deviceId device identifier
144 * @return router mac address
145 */
sanghob35a6192015-04-01 13:05:26 -0700146 @Override
147 public MacAddress getDeviceMac(DeviceId deviceId) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700148 if (deviceConfigMap.get(deviceId) != null) {
sanghob35a6192015-04-01 13:05:26 -0700149 log.debug("getDeviceMac for device{} is {}",
150 deviceId,
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700151 deviceConfigMap.get(deviceId).mac);
152 return deviceConfigMap.get(deviceId).mac;
sanghob35a6192015-04-01 13:05:26 -0700153 } else {
154 throw new IllegalStateException();
155 }
156 }
157
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700158 /**
159 * Returns the router ip address of a segment router.
160 *
161 * @param deviceId device identifier
162 * @return router ip address
163 */
164 public Ip4Address getRouterIp(DeviceId deviceId) {
165 if (deviceConfigMap.get(deviceId) != null) {
166 log.debug("getDeviceIp for device{} is {}",
167 deviceId,
168 deviceConfigMap.get(deviceId).ip);
169 return deviceConfigMap.get(deviceId).ip;
170 } else {
171 throw new IllegalStateException();
sanghob35a6192015-04-01 13:05:26 -0700172 }
sanghob35a6192015-04-01 13:05:26 -0700173 }
174
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700175 /**
176 * Indicates if the segment router is a edge router or
177 * a transit/back bone router.
178 *
179 * @param deviceId device identifier
180 * @return boolean
181 */
182 @Override
183 public boolean isEdgeDevice(DeviceId deviceId) {
184 if (deviceConfigMap.get(deviceId) != null) {
185 log.debug("isEdgeDevice for device{} is {}",
186 deviceId,
187 deviceConfigMap.get(deviceId).isEdge);
188 return deviceConfigMap.get(deviceId).isEdge;
189 } else {
190 throw new IllegalStateException();
191 }
192 }
193
194 /**
195 * Returns the segment ids of all configured segment routers.
196 *
197 * @return list of segment ids
198 */
sanghob35a6192015-04-01 13:05:26 -0700199 @Override
200 public List<Integer> getAllDeviceSegmentIds() {
201 return allSegmentIds;
202 }
203
sanghob35a6192015-04-01 13:05:26 -0700204 /**
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700205 * Returns the device identifier or data plane identifier (dpid)
206 * of a segment router given its segment id.
sanghob35a6192015-04-01 13:05:26 -0700207 *
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700208 * @param sid segment id
209 * @return deviceId device identifier
sanghob35a6192015-04-01 13:05:26 -0700210 */
211 public DeviceId getDeviceId(int sid) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700212 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
213 deviceConfigMap.entrySet()) {
214 if (entry.getValue().nodeSid == sid) {
215 return entry.getValue().deviceId;
sanghob35a6192015-04-01 13:05:26 -0700216 }
217 }
218
219 return null;
220 }
221
222 /**
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700223 * Returns the device identifier or data plane identifier (dpid)
224 * of a segment router given its router ip address.
sanghob35a6192015-04-01 13:05:26 -0700225 *
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700226 * @param ipAddress router ip address
227 * @return deviceId device identifier
sanghob35a6192015-04-01 13:05:26 -0700228 */
229 public DeviceId getDeviceId(Ip4Address ipAddress) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700230 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
231 deviceConfigMap.entrySet()) {
232 if (entry.getValue().ip.equals(ipAddress)) {
233 return entry.getValue().deviceId;
sanghob35a6192015-04-01 13:05:26 -0700234 }
235 }
236
237 return null;
238 }
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700239
240 /**
241 * Returns the configured subnet gateway ip addresses for a segment router.
242 *
243 * @param deviceId device identifier
244 * @return list of ip addresses
245 */
246 public List<Ip4Address> getSubnetGatewayIps(DeviceId deviceId) {
247 if (deviceConfigMap.get(deviceId) != null) {
248 log.debug("getSubnetGatewayIps for device{} is {}",
249 deviceId,
250 deviceConfigMap.get(deviceId).gatewayIps.values());
251 return new ArrayList<Ip4Address>(deviceConfigMap.
252 get(deviceId).gatewayIps.values());
253 } else {
254 return null;
255 }
256 }
257
258 /**
259 * Returns the configured subnet prefixes for a segment router.
260 *
261 * @param deviceId device identifier
262 * @return list of ip prefixes
263 */
264 public List<Ip4Prefix> getSubnets(DeviceId deviceId) {
265 if (deviceConfigMap.get(deviceId) != null) {
266 log.debug("getSubnets for device{} is {}",
267 deviceId,
268 deviceConfigMap.get(deviceId).subnets.values());
269 return new ArrayList<Ip4Prefix>(deviceConfigMap.
270 get(deviceId).subnets.values());
271 } else {
272 return null;
273 }
274 }
275
276 /**
277 * Returns the router ip address of segment router that has the
278 * specified ip address in its subnets.
279 *
280 * @param destIpAddress target ip address
281 * @return router ip address
282 */
283 public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) {
284 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
285 deviceConfigMap.entrySet()) {
286 for (Ip4Prefix prefix:entry.getValue().subnets.values()) {
287 if (prefix.contains(destIpAddress)) {
288 return entry.getValue().ip;
289 }
290 }
291 }
292
293 log.debug("No router was found for {}", destIpAddress);
294 return null;
295 }
296
297 /**
298 * Returns the router mac address of segment router that has the
299 * specified ip address as one of its subnet gateway ip address.
300 *
301 * @param gatewayIpAddress router gateway ip address
302 * @return router mac address
303 */
304 public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) {
305 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
306 deviceConfigMap.entrySet()) {
307 if (entry.getValue().gatewayIps.
308 values().contains(gatewayIpAddress)) {
309 return entry.getValue().mac;
310 }
311 }
312
313 log.debug("Cannot find a router for {}", gatewayIpAddress);
314 return null;
315 }
sanghob35a6192015-04-01 13:05:26 -0700316}