aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java')
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java404
1 files changed, 404 insertions, 0 deletions
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
new file mode 100644
index 00000000..d82eb5ec
--- /dev/null
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
@@ -0,0 +1,404 @@
+package org.onosproject.segmentrouting;
+
+import com.google.common.collect.Lists;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.segmentrouting.grouphandler.DeviceProperties;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.config.NetworkConfig.SwitchConfig;
+import org.onosproject.segmentrouting.config.NetworkConfigManager;
+import org.onosproject.segmentrouting.config.SegmentRouterConfig;
+import org.onosproject.segmentrouting.config.SegmentRouterConfig.Subnet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Segment Routing configuration component that reads the
+ * segment routing related configuration from Network Configuration Manager
+ * component and organizes in more accessible formats.
+ *
+ * TODO: Merge multiple Segment Routing configuration wrapper classes into one.
+ */
+public class DeviceConfiguration implements DeviceProperties {
+
+ private static final Logger log = LoggerFactory
+ .getLogger(DeviceConfiguration.class);
+ private final List<Integer> allSegmentIds = new ArrayList<Integer>();
+ private final HashMap<DeviceId, SegmentRouterInfo> deviceConfigMap = new HashMap<>();
+ private final NetworkConfigManager configService;
+
+ private class SegmentRouterInfo {
+ int nodeSid;
+ DeviceId deviceId;
+ Ip4Address ip;
+ MacAddress mac;
+ boolean isEdge;
+ HashMap<PortNumber, Ip4Address> gatewayIps;
+ HashMap<PortNumber, Ip4Prefix> subnets;
+ List<SegmentRouterConfig.AdjacencySid> adjacencySids;
+ }
+
+ /**
+ * Constructor. Reads all the configuration for all devices of type
+ * Segment Router and organizes into various maps for easier access.
+ *
+ * @param configService handle to network configuration manager
+ * component from where the relevant configuration is retrieved.
+ */
+ public DeviceConfiguration(NetworkConfigManager configService) {
+ this.configService = checkNotNull(configService);
+ List<SwitchConfig> allSwitchCfg =
+ this.configService.getConfiguredAllowedSwitches();
+ for (SwitchConfig cfg : allSwitchCfg) {
+ if (!(cfg instanceof SegmentRouterConfig)) {
+ continue;
+ }
+ SegmentRouterInfo info = new SegmentRouterInfo();
+ info.nodeSid = ((SegmentRouterConfig) cfg).getNodeSid();
+ info.deviceId = ((SegmentRouterConfig) cfg).getDpid();
+ info.mac = MacAddress.valueOf(((
+ SegmentRouterConfig) cfg).getRouterMac());
+ String routerIp = ((SegmentRouterConfig) cfg).getRouterIp();
+ Ip4Prefix prefix = checkNotNull(IpPrefix.valueOf(routerIp).getIp4Prefix());
+ info.ip = prefix.address();
+ info.isEdge = ((SegmentRouterConfig) cfg).isEdgeRouter();
+ info.subnets = new HashMap<>();
+ info.gatewayIps = new HashMap<PortNumber, Ip4Address>();
+ for (Subnet s: ((SegmentRouterConfig) cfg).getSubnets()) {
+ info.subnets.put(PortNumber.portNumber(s.getPortNo()),
+ Ip4Prefix.valueOf(s.getSubnetIp()));
+ String gatewayIp = s.getSubnetIp().
+ substring(0, s.getSubnetIp().indexOf('/'));
+ info.gatewayIps.put(PortNumber.portNumber(s.getPortNo()),
+ Ip4Address.valueOf(gatewayIp));
+ }
+ info.adjacencySids = ((SegmentRouterConfig) cfg).getAdjacencySids();
+ this.deviceConfigMap.put(info.deviceId, info);
+ this.allSegmentIds.add(info.nodeSid);
+
+ }
+ }
+
+ /**
+ * Returns the segment id of a segment router.
+ *
+ * @param deviceId device identifier
+ * @return segment id
+ */
+ @Override
+ public int getSegmentId(DeviceId deviceId) {
+ if (deviceConfigMap.get(deviceId) != null) {
+ log.debug("getSegmentId for device{} is {}",
+ deviceId,
+ deviceConfigMap.get(deviceId).nodeSid);
+ return deviceConfigMap.get(deviceId).nodeSid;
+ } else {
+ log.warn("getSegmentId for device {} "
+ + "throwing IllegalStateException "
+ + "because device does not exist in config", deviceId);
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Returns the segment id of a segment router given its mac address.
+ *
+ * @param routerMac router mac address
+ * @return segment id
+ */
+ public int getSegmentId(MacAddress routerMac) {
+ for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+ deviceConfigMap.entrySet()) {
+ if (entry.getValue().mac.equals(routerMac)) {
+ return entry.getValue().nodeSid;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Returns the segment id of a segment router given its router ip address.
+ *
+ * @param routerAddress router ip address
+ * @return segment id
+ */
+ public int getSegmentId(Ip4Address routerAddress) {
+ for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+ deviceConfigMap.entrySet()) {
+ if (entry.getValue().ip.equals(routerAddress)) {
+ return entry.getValue().nodeSid;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Returns the router mac of a segment router.
+ *
+ * @param deviceId device identifier
+ * @return router mac address
+ */
+ @Override
+ public MacAddress getDeviceMac(DeviceId deviceId) {
+ if (deviceConfigMap.get(deviceId) != null) {
+ log.debug("getDeviceMac for device{} is {}",
+ deviceId,
+ deviceConfigMap.get(deviceId).mac);
+ return deviceConfigMap.get(deviceId).mac;
+ } else {
+ log.warn("getDeviceMac for device {} "
+ + "throwing IllegalStateException "
+ + "because device does not exist in config", deviceId);
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Returns the router ip address of a segment router.
+ *
+ * @param deviceId device identifier
+ * @return router ip address
+ */
+ public Ip4Address getRouterIp(DeviceId deviceId) {
+ if (deviceConfigMap.get(deviceId) != null) {
+ log.debug("getDeviceIp for device{} is {}",
+ deviceId,
+ deviceConfigMap.get(deviceId).ip);
+ return deviceConfigMap.get(deviceId).ip;
+ } else {
+ log.warn("getRouterIp for device {} "
+ + "throwing IllegalStateException "
+ + "because device does not exist in config", deviceId);
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Indicates if the segment router is a edge router or
+ * a transit/back bone router.
+ *
+ * @param deviceId device identifier
+ * @return boolean
+ */
+ @Override
+ public boolean isEdgeDevice(DeviceId deviceId) {
+ if (deviceConfigMap.get(deviceId) != null) {
+ log.debug("isEdgeDevice for device{} is {}",
+ deviceId,
+ deviceConfigMap.get(deviceId).isEdge);
+ return deviceConfigMap.get(deviceId).isEdge;
+ } else {
+ log.warn("isEdgeDevice for device {} "
+ + "throwing IllegalStateException "
+ + "because device does not exist in config", deviceId);
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Returns the segment ids of all configured segment routers.
+ *
+ * @return list of segment ids
+ */
+ @Override
+ public List<Integer> getAllDeviceSegmentIds() {
+ return allSegmentIds;
+ }
+
+ /**
+ * Returns the device identifier or data plane identifier (dpid)
+ * of a segment router given its segment id.
+ *
+ * @param sid segment id
+ * @return deviceId device identifier
+ */
+ public DeviceId getDeviceId(int sid) {
+ for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+ deviceConfigMap.entrySet()) {
+ if (entry.getValue().nodeSid == sid) {
+ return entry.getValue().deviceId;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the device identifier or data plane identifier (dpid)
+ * of a segment router given its router ip address.
+ *
+ * @param ipAddress router ip address
+ * @return deviceId device identifier
+ */
+ public DeviceId getDeviceId(Ip4Address ipAddress) {
+ for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+ deviceConfigMap.entrySet()) {
+ if (entry.getValue().ip.equals(ipAddress)) {
+ return entry.getValue().deviceId;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the configured subnet gateway ip addresses for a segment router.
+ *
+ * @param deviceId device identifier
+ * @return list of ip addresses
+ */
+ public List<Ip4Address> getSubnetGatewayIps(DeviceId deviceId) {
+ if (deviceConfigMap.get(deviceId) != null) {
+ log.debug("getSubnetGatewayIps for device{} is {}",
+ deviceId,
+ deviceConfigMap.get(deviceId).gatewayIps.values());
+ return new ArrayList<Ip4Address>(deviceConfigMap.
+ get(deviceId).gatewayIps.values());
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the configured subnet prefixes for a segment router.
+ *
+ * @param deviceId device identifier
+ * @return list of ip prefixes
+ */
+ public List<Ip4Prefix> getSubnets(DeviceId deviceId) {
+ if (deviceConfigMap.get(deviceId) != null) {
+ log.debug("getSubnets for device{} is {}",
+ deviceId,
+ deviceConfigMap.get(deviceId).subnets.values());
+ return new ArrayList<Ip4Prefix>(deviceConfigMap.
+ get(deviceId).subnets.values());
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the router ip address of segment router that has the
+ * specified ip address in its subnets.
+ *
+ * @param destIpAddress target ip address
+ * @return router ip address
+ */
+ public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) {
+ for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+ deviceConfigMap.entrySet()) {
+ for (Ip4Prefix prefix:entry.getValue().subnets.values()) {
+ if (prefix.contains(destIpAddress)) {
+ return entry.getValue().ip;
+ }
+ }
+ }
+
+ log.debug("No router was found for {}", destIpAddress);
+ return null;
+ }
+
+ /**
+ * Returns the router mac address of segment router that has the
+ * specified ip address as one of its subnet gateway ip address.
+ *
+ * @param gatewayIpAddress router gateway ip address
+ * @return router mac address
+ */
+ public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) {
+ for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
+ deviceConfigMap.entrySet()) {
+ if (entry.getValue().gatewayIps.
+ values().contains(gatewayIpAddress)) {
+ return entry.getValue().mac;
+ }
+ }
+
+ log.debug("Cannot find a router for {}", gatewayIpAddress);
+ return null;
+ }
+
+
+ /**
+ * Checks if the host is in the subnet defined in the router with the
+ * device ID given.
+ *
+ * @param deviceId device identification of the router
+ * @param hostIp host IP address to check
+ * @return true if the host is within the subnet of the router,
+ * false if no subnet is defined under the router or if the host is not
+ * within the subnet defined in the router
+ */
+ public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) {
+
+ List<Ip4Prefix> subnets = getSubnets(deviceId);
+ if (subnets == null) {
+ return false;
+ }
+
+ for (Ip4Prefix subnet: subnets) {
+ if (subnet.contains(hostIp)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the ports corresponding to the adjacency Sid given.
+ *
+ * @param deviceId device identification of the router
+ * @param sid adjacency Sid
+ * @return list of port numbers
+ */
+ public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
+ if (deviceConfigMap.get(deviceId) != null) {
+ for (SegmentRouterConfig.AdjacencySid asid : deviceConfigMap.get(deviceId).adjacencySids) {
+ if (asid.getAdjSid() == sid) {
+ return asid.getPorts();
+ }
+ }
+ }
+
+ return Lists.newArrayList();
+ }
+
+ /**
+ * Check if the Sid given is whether adjacency Sid of the router device or not.
+ *
+ * @param deviceId device identification of the router
+ * @param sid Sid to check
+ * @return true if the Sid given is the adjacency Sid of the device,
+ * otherwise false
+ */
+ public boolean isAdjacencySid(DeviceId deviceId, int sid) {
+ if (deviceConfigMap.get(deviceId) != null) {
+ if (deviceConfigMap.get(deviceId).adjacencySids.isEmpty()) {
+ return false;
+ } else {
+ for (SegmentRouterConfig.AdjacencySid asid:
+ deviceConfigMap.get(deviceId).adjacencySids) {
+ if (asid.getAdjSid() == sid) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ return false;
+ }
+}