blob: c4bb8c8c6a30c11c5d538b0265ebfcc9dbac11d7 [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 */
sanghob35a6192015-04-01 13:05:26 -070016package org.onosproject.segmentrouting;
17
sangho1e575652015-05-14 00:39:53 -070018import com.google.common.collect.Lists;
sanghob35a6192015-04-01 13:05:26 -070019import org.onlab.packet.Ip4Address;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070020import org.onlab.packet.Ip4Prefix;
sanghob35a6192015-04-01 13:05:26 -070021import org.onlab.packet.MacAddress;
Charles Chand6832882015-10-05 17:50:33 -070022import org.onosproject.net.config.NetworkConfigRegistry;
23import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
24import org.onosproject.segmentrouting.config.SegmentRoutingConfig.AdjacencySid;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070025import org.onosproject.segmentrouting.grouphandler.DeviceProperties;
sanghob35a6192015-04-01 13:05:26 -070026import org.onosproject.net.DeviceId;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070027import org.onosproject.net.PortNumber;
sanghob35a6192015-04-01 13:05:26 -070028import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070031import static com.google.common.base.Preconditions.checkNotNull;
32
33import java.util.ArrayList;
sanghob35a6192015-04-01 13:05:26 -070034import java.util.HashMap;
35import java.util.List;
36import java.util.Map;
Charles Chand6832882015-10-05 17:50:33 -070037import java.util.Set;
sanghob35a6192015-04-01 13:05:26 -070038
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070039/**
40 * Segment Routing configuration component that reads the
41 * segment routing related configuration from Network Configuration Manager
42 * component and organizes in more accessible formats.
43 *
44 * TODO: Merge multiple Segment Routing configuration wrapper classes into one.
45 */
sanghob35a6192015-04-01 13:05:26 -070046public class DeviceConfiguration implements DeviceProperties {
47
48 private static final Logger log = LoggerFactory
49 .getLogger(DeviceConfiguration.class);
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -070050 private final List<Integer> allSegmentIds = new ArrayList<>();
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070051 private final HashMap<DeviceId, SegmentRouterInfo> deviceConfigMap = new HashMap<>();
Charles Chand6832882015-10-05 17:50:33 -070052 private final NetworkConfigRegistry configService;
sanghob35a6192015-04-01 13:05:26 -070053
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070054 private class SegmentRouterInfo {
55 int nodeSid;
56 DeviceId deviceId;
57 Ip4Address ip;
58 MacAddress mac;
59 boolean isEdge;
60 HashMap<PortNumber, Ip4Address> gatewayIps;
61 HashMap<PortNumber, Ip4Prefix> subnets;
Charles Chand6832882015-10-05 17:50:33 -070062 List<AdjacencySid> adjacencySids;
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070063 }
sanghob35a6192015-04-01 13:05:26 -070064
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070065 /**
66 * Constructor. Reads all the configuration for all devices of type
67 * Segment Router and organizes into various maps for easier access.
68 *
Charles Chand6832882015-10-05 17:50:33 -070069 * @param cfgService handle to network configuration manager
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070070 * component from where the relevant configuration is retrieved.
71 */
Charles Chand6832882015-10-05 17:50:33 -070072 public DeviceConfiguration(NetworkConfigRegistry cfgService) {
73 this.configService = checkNotNull(cfgService);
74
75 Set<DeviceId> subjectSet =
76 cfgService.getSubjects(DeviceId.class, SegmentRoutingConfig.class);
77
78 subjectSet.forEach(subject -> {
79 SegmentRoutingConfig config =
80 cfgService.getConfig(subject, SegmentRoutingConfig.class);
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070081 SegmentRouterInfo info = new SegmentRouterInfo();
Charles Chand6832882015-10-05 17:50:33 -070082 info.nodeSid = config.getSid();
83 info.deviceId = subject;
84 info.ip = config.getIp();
85 info.mac = config.getMac();
86 info.isEdge = config.isEdgeRouter();
87 // TODO fecth subnet and gateway information via port subject
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -070088 info.gatewayIps = new HashMap<>();
Charles Chand6832882015-10-05 17:50:33 -070089 info.subnets = new HashMap<>();
90 info.adjacencySids = config.getAdjacencySids();
91
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070092 this.deviceConfigMap.put(info.deviceId, info);
93 this.allSegmentIds.add(info.nodeSid);
Charles Chand6832882015-10-05 17:50:33 -070094 });
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070095 }
96
97 /**
98 * Returns the segment id of a segment router.
99 *
100 * @param deviceId device identifier
101 * @return segment id
102 */
sanghob35a6192015-04-01 13:05:26 -0700103 @Override
104 public int getSegmentId(DeviceId deviceId) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700105 if (deviceConfigMap.get(deviceId) != null) {
sanghob35a6192015-04-01 13:05:26 -0700106 log.debug("getSegmentId for device{} is {}",
107 deviceId,
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700108 deviceConfigMap.get(deviceId).nodeSid);
109 return deviceConfigMap.get(deviceId).nodeSid;
sanghob35a6192015-04-01 13:05:26 -0700110 } else {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700111 log.warn("getSegmentId for device {} "
112 + "throwing IllegalStateException "
113 + "because device does not exist in config", deviceId);
sanghob35a6192015-04-01 13:05:26 -0700114 throw new IllegalStateException();
115 }
116 }
117
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700118 /**
119 * Returns the segment id of a segment router given its mac address.
120 *
121 * @param routerMac router mac address
122 * @return segment id
123 */
124 public int getSegmentId(MacAddress routerMac) {
125 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
126 deviceConfigMap.entrySet()) {
127 if (entry.getValue().mac.equals(routerMac)) {
128 return entry.getValue().nodeSid;
129 }
130 }
sanghob35a6192015-04-01 13:05:26 -0700131
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700132 return -1;
133 }
134
135 /**
136 * Returns the segment id of a segment router given its router ip address.
137 *
138 * @param routerAddress router ip address
139 * @return segment id
140 */
141 public int getSegmentId(Ip4Address routerAddress) {
142 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
143 deviceConfigMap.entrySet()) {
144 if (entry.getValue().ip.equals(routerAddress)) {
145 return entry.getValue().nodeSid;
146 }
147 }
148
149 return -1;
150 }
151
152 /**
153 * Returns the router mac of a segment router.
154 *
155 * @param deviceId device identifier
156 * @return router mac address
157 */
sanghob35a6192015-04-01 13:05:26 -0700158 @Override
159 public MacAddress getDeviceMac(DeviceId deviceId) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700160 if (deviceConfigMap.get(deviceId) != null) {
sanghob35a6192015-04-01 13:05:26 -0700161 log.debug("getDeviceMac for device{} is {}",
162 deviceId,
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700163 deviceConfigMap.get(deviceId).mac);
164 return deviceConfigMap.get(deviceId).mac;
sanghob35a6192015-04-01 13:05:26 -0700165 } else {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700166 log.warn("getDeviceMac for device {} "
167 + "throwing IllegalStateException "
168 + "because device does not exist in config", deviceId);
sanghob35a6192015-04-01 13:05:26 -0700169 throw new IllegalStateException();
170 }
171 }
172
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700173 /**
174 * Returns the router ip address of a segment router.
175 *
176 * @param deviceId device identifier
177 * @return router ip address
178 */
179 public Ip4Address getRouterIp(DeviceId deviceId) {
180 if (deviceConfigMap.get(deviceId) != null) {
181 log.debug("getDeviceIp for device{} is {}",
182 deviceId,
183 deviceConfigMap.get(deviceId).ip);
184 return deviceConfigMap.get(deviceId).ip;
185 } else {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700186 log.warn("getRouterIp for device {} "
187 + "throwing IllegalStateException "
188 + "because device does not exist in config", deviceId);
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700189 throw new IllegalStateException();
sanghob35a6192015-04-01 13:05:26 -0700190 }
sanghob35a6192015-04-01 13:05:26 -0700191 }
192
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700193 /**
194 * Indicates if the segment router is a edge router or
195 * a transit/back bone router.
196 *
197 * @param deviceId device identifier
198 * @return boolean
199 */
200 @Override
201 public boolean isEdgeDevice(DeviceId deviceId) {
202 if (deviceConfigMap.get(deviceId) != null) {
203 log.debug("isEdgeDevice for device{} is {}",
204 deviceId,
205 deviceConfigMap.get(deviceId).isEdge);
206 return deviceConfigMap.get(deviceId).isEdge;
207 } else {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700208 log.warn("isEdgeDevice for device {} "
209 + "throwing IllegalStateException "
210 + "because device does not exist in config", deviceId);
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700211 throw new IllegalStateException();
212 }
213 }
214
215 /**
216 * Returns the segment ids of all configured segment routers.
217 *
218 * @return list of segment ids
219 */
sanghob35a6192015-04-01 13:05:26 -0700220 @Override
221 public List<Integer> getAllDeviceSegmentIds() {
222 return allSegmentIds;
223 }
224
sanghob35a6192015-04-01 13:05:26 -0700225 /**
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700226 * Returns the device identifier or data plane identifier (dpid)
227 * of a segment router given its segment id.
sanghob35a6192015-04-01 13:05:26 -0700228 *
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700229 * @param sid segment id
230 * @return deviceId device identifier
sanghob35a6192015-04-01 13:05:26 -0700231 */
232 public DeviceId getDeviceId(int sid) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700233 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
234 deviceConfigMap.entrySet()) {
235 if (entry.getValue().nodeSid == sid) {
236 return entry.getValue().deviceId;
sanghob35a6192015-04-01 13:05:26 -0700237 }
238 }
239
240 return null;
241 }
242
243 /**
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700244 * Returns the device identifier or data plane identifier (dpid)
245 * of a segment router given its router ip address.
sanghob35a6192015-04-01 13:05:26 -0700246 *
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700247 * @param ipAddress router ip address
248 * @return deviceId device identifier
sanghob35a6192015-04-01 13:05:26 -0700249 */
250 public DeviceId getDeviceId(Ip4Address ipAddress) {
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700251 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
252 deviceConfigMap.entrySet()) {
253 if (entry.getValue().ip.equals(ipAddress)) {
254 return entry.getValue().deviceId;
sanghob35a6192015-04-01 13:05:26 -0700255 }
256 }
257
258 return null;
259 }
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700260
261 /**
262 * Returns the configured subnet gateway ip addresses for a segment router.
263 *
264 * @param deviceId device identifier
265 * @return list of ip addresses
266 */
267 public List<Ip4Address> getSubnetGatewayIps(DeviceId deviceId) {
268 if (deviceConfigMap.get(deviceId) != null) {
269 log.debug("getSubnetGatewayIps for device{} is {}",
270 deviceId,
271 deviceConfigMap.get(deviceId).gatewayIps.values());
Sho SHIMIZUa8dbad42015-09-11 14:22:25 -0700272 return new ArrayList<>(deviceConfigMap.get(deviceId).gatewayIps.values());
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700273 } else {
274 return null;
275 }
276 }
277
278 /**
279 * Returns the configured subnet prefixes for a segment router.
280 *
281 * @param deviceId device identifier
282 * @return list of ip prefixes
283 */
284 public List<Ip4Prefix> getSubnets(DeviceId deviceId) {
285 if (deviceConfigMap.get(deviceId) != null) {
286 log.debug("getSubnets for device{} is {}",
287 deviceId,
288 deviceConfigMap.get(deviceId).subnets.values());
Sho SHIMIZUa8dbad42015-09-11 14:22:25 -0700289 return new ArrayList<>(deviceConfigMap.get(deviceId).subnets.values());
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -0700290 } else {
291 return null;
292 }
293 }
294
295 /**
296 * Returns the router ip address of segment router that has the
297 * specified ip address in its subnets.
298 *
299 * @param destIpAddress target ip address
300 * @return router ip address
301 */
302 public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) {
303 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
304 deviceConfigMap.entrySet()) {
305 for (Ip4Prefix prefix:entry.getValue().subnets.values()) {
306 if (prefix.contains(destIpAddress)) {
307 return entry.getValue().ip;
308 }
309 }
310 }
311
312 log.debug("No router was found for {}", destIpAddress);
313 return null;
314 }
315
316 /**
317 * Returns the router mac address of segment router that has the
318 * specified ip address as one of its subnet gateway ip address.
319 *
320 * @param gatewayIpAddress router gateway ip address
321 * @return router mac address
322 */
323 public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) {
324 for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
325 deviceConfigMap.entrySet()) {
326 if (entry.getValue().gatewayIps.
327 values().contains(gatewayIpAddress)) {
328 return entry.getValue().mac;
329 }
330 }
331
332 log.debug("Cannot find a router for {}", gatewayIpAddress);
333 return null;
334 }
sangho666cd6d2015-04-14 16:27:13 -0700335
336
337 /**
338 * Checks if the host is in the subnet defined in the router with the
339 * device ID given.
340 *
341 * @param deviceId device identification of the router
342 * @param hostIp host IP address to check
343 * @return true if the host is within the subnet of the router,
344 * false if no subnet is defined under the router or if the host is not
345 * within the subnet defined in the router
346 */
347 public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) {
348
349 List<Ip4Prefix> subnets = getSubnets(deviceId);
350 if (subnets == null) {
351 return false;
352 }
353
354 for (Ip4Prefix subnet: subnets) {
355 if (subnet.contains(hostIp)) {
356 return true;
357 }
358 }
359
360 return false;
361 }
sangho1e575652015-05-14 00:39:53 -0700362
363 /**
364 * Returns the ports corresponding to the adjacency Sid given.
365 *
366 * @param deviceId device identification of the router
367 * @param sid adjacency Sid
368 * @return list of port numbers
369 */
370 public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
371 if (deviceConfigMap.get(deviceId) != null) {
Charles Chand6832882015-10-05 17:50:33 -0700372 for (AdjacencySid asid : deviceConfigMap.get(deviceId).adjacencySids) {
373 if (asid.getSid() == sid) {
sangho1e575652015-05-14 00:39:53 -0700374 return asid.getPorts();
375 }
376 }
377 }
378
379 return Lists.newArrayList();
380 }
381
382 /**
383 * Check if the Sid given is whether adjacency Sid of the router device or not.
384 *
385 * @param deviceId device identification of the router
386 * @param sid Sid to check
387 * @return true if the Sid given is the adjacency Sid of the device,
388 * otherwise false
389 */
390 public boolean isAdjacencySid(DeviceId deviceId, int sid) {
391 if (deviceConfigMap.get(deviceId) != null) {
392 if (deviceConfigMap.get(deviceId).adjacencySids.isEmpty()) {
393 return false;
394 } else {
Charles Chand6832882015-10-05 17:50:33 -0700395 for (AdjacencySid asid:
sangho1e575652015-05-14 00:39:53 -0700396 deviceConfigMap.get(deviceId).adjacencySids) {
Charles Chand6832882015-10-05 17:50:33 -0700397 if (asid.getSid() == sid) {
sangho1e575652015-05-14 00:39:53 -0700398 return true;
399 }
400 }
401 return false;
402 }
403 }
404
405 return false;
406 }
Charles Chand6832882015-10-05 17:50:33 -0700407}