Committed by
Jonathan Hart
CORD-508 SegmentRouting / vRouter integration
- Added excludePorts config to SegmentRouting
SR does not push VLAN filtering rule to excluded ports
SR ignores hosts learned from excluded ports
- Use separate default route config
Don't need to config 0/0 on the interface anymore
Change-Id: Iea75d60c2d5f5368e79652b1bf192a6ced49030d
Showing
6 changed files
with
324 additions
and
102 deletions
| ... | @@ -471,8 +471,9 @@ public class RoutingRulePopulator { | ... | @@ -471,8 +471,9 @@ public class RoutingRulePopulator { |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | for (Port port : srManager.deviceService.getPorts(deviceId)) { | 473 | for (Port port : srManager.deviceService.getPorts(deviceId)) { |
| 474 | - if (port.number().toLong() > 0 && | 474 | + ConnectPoint cp = new ConnectPoint(deviceId, port.number()); |
| 475 | - port.number().toLong() < SegmentRoutingService.OFPP_MAX && | 475 | + // TODO: Handles dynamic port events when we are ready for dynamic config |
| 476 | + if (!srManager.deviceConfiguration.excludedPorts().contains(cp) && | ||
| 476 | port.isEnabled()) { | 477 | port.isEnabled()) { |
| 477 | Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number()); | 478 | Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number()); |
| 478 | VlanId assignedVlan = (portSubnet == null) | 479 | VlanId assignedVlan = (portSubnet == null) | ... | ... |
| ... | @@ -814,7 +814,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -814,7 +814,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 814 | * Reads network config and initializes related data structure accordingly. | 814 | * Reads network config and initializes related data structure accordingly. |
| 815 | */ | 815 | */ |
| 816 | public void configureNetwork() { | 816 | public void configureNetwork() { |
| 817 | - deviceConfiguration = new DeviceConfiguration(segmentRoutingManager.cfgService); | 817 | + deviceConfiguration = new DeviceConfiguration(appId, |
| 818 | + segmentRoutingManager.cfgService); | ||
| 818 | 819 | ||
| 819 | arpHandler = new ArpHandler(segmentRoutingManager); | 820 | arpHandler = new ArpHandler(segmentRoutingManager); |
| 820 | icmpHandler = new IcmpHandler(segmentRoutingManager); | 821 | icmpHandler = new IcmpHandler(segmentRoutingManager); |
| ... | @@ -987,22 +988,25 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -987,22 +988,25 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 987 | Set<IpAddress> ips = event.subject().ipAddresses(); | 988 | Set<IpAddress> ips = event.subject().ipAddresses(); |
| 988 | log.info("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); | 989 | log.info("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); |
| 989 | 990 | ||
| 990 | - // Populate bridging table entry | 991 | + if (!deviceConfiguration.excludedPorts() |
| 991 | - log.debug("Populate L2 table entry for host {} at {}:{}", | 992 | + .contains(new ConnectPoint(deviceId, port))) { |
| 992 | - mac, deviceId, port); | 993 | + // Populate bridging table entry |
| 993 | - ForwardingObjective.Builder fob = | 994 | + log.debug("Populate L2 table entry for host {} at {}:{}", |
| 994 | - getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); | 995 | + mac, deviceId, port); |
| 995 | - flowObjectiveService.forward(deviceId, fob.add( | 996 | + ForwardingObjective.Builder fob = |
| 996 | - new BridgingTableObjectiveContext(mac, vlanId) | 997 | + getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); |
| 997 | - )); | 998 | + flowObjectiveService.forward(deviceId, fob.add( |
| 998 | - | 999 | + new BridgingTableObjectiveContext(mac, vlanId) |
| 999 | - // Populate IP table entry | 1000 | + )); |
| 1000 | - ips.forEach(ip -> { | 1001 | + |
| 1001 | - if (ip.isIp4()) { | 1002 | + // Populate IP table entry |
| 1002 | - routingRulePopulator.populateIpRuleForHost( | 1003 | + ips.forEach(ip -> { |
| 1003 | - deviceId, ip.getIp4Address(), mac, port); | 1004 | + if (ip.isIp4()) { |
| 1004 | - } | 1005 | + routingRulePopulator.populateIpRuleForHost( |
| 1005 | - }); | 1006 | + deviceId, ip.getIp4Address(), mac, port); |
| 1007 | + } | ||
| 1008 | + }); | ||
| 1009 | + } | ||
| 1006 | } | 1010 | } |
| 1007 | 1011 | ||
| 1008 | private void processHostRemoveEvent(HostEvent event) { | 1012 | private void processHostRemoveEvent(HostEvent event) { |
| ... | @@ -1013,20 +1017,23 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -1013,20 +1017,23 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 1013 | Set<IpAddress> ips = event.subject().ipAddresses(); | 1017 | Set<IpAddress> ips = event.subject().ipAddresses(); |
| 1014 | log.debug("Host {}/{} is removed from {}:{}", mac, vlanId, deviceId, port); | 1018 | log.debug("Host {}/{} is removed from {}:{}", mac, vlanId, deviceId, port); |
| 1015 | 1019 | ||
| 1016 | - // Revoke bridging table entry | 1020 | + if (!deviceConfiguration.excludedPorts() |
| 1017 | - ForwardingObjective.Builder fob = | 1021 | + .contains(new ConnectPoint(deviceId, port))) { |
| 1018 | - getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); | 1022 | + // Revoke bridging table entry |
| 1019 | - flowObjectiveService.forward(deviceId, fob.remove( | 1023 | + ForwardingObjective.Builder fob = |
| 1020 | - new BridgingTableObjectiveContext(mac, vlanId) | 1024 | + getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); |
| 1021 | - )); | 1025 | + flowObjectiveService.forward(deviceId, fob.remove( |
| 1022 | - | 1026 | + new BridgingTableObjectiveContext(mac, vlanId) |
| 1023 | - // Revoke IP table entry | 1027 | + )); |
| 1024 | - ips.forEach(ip -> { | 1028 | + |
| 1025 | - if (ip.isIp4()) { | 1029 | + // Revoke IP table entry |
| 1026 | - routingRulePopulator.revokeIpRuleForHost( | 1030 | + ips.forEach(ip -> { |
| 1027 | - deviceId, ip.getIp4Address(), mac, port); | 1031 | + if (ip.isIp4()) { |
| 1028 | - } | 1032 | + routingRulePopulator.revokeIpRuleForHost( |
| 1029 | - }); | 1033 | + deviceId, ip.getIp4Address(), mac, port); |
| 1034 | + } | ||
| 1035 | + }); | ||
| 1036 | + } | ||
| 1030 | } | 1037 | } |
| 1031 | 1038 | ||
| 1032 | private void processHostMovedEvent(HostEvent event) { | 1039 | private void processHostMovedEvent(HostEvent event) { |
| ... | @@ -1041,35 +1048,41 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -1041,35 +1048,41 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 1041 | log.debug("Host {}/{} is moved from {}:{} to {}:{}", | 1048 | log.debug("Host {}/{} is moved from {}:{} to {}:{}", |
| 1042 | mac, vlanId, prevDeviceId, prevPort, newDeviceId, newPort); | 1049 | mac, vlanId, prevDeviceId, prevPort, newDeviceId, newPort); |
| 1043 | 1050 | ||
| 1044 | - // Revoke previous bridging table entry | 1051 | + if (!deviceConfiguration.excludedPorts() |
| 1045 | - ForwardingObjective.Builder prevFob = | 1052 | + .contains(new ConnectPoint(prevDeviceId, prevPort))) { |
| 1046 | - getForwardingObjectiveBuilder(prevDeviceId, mac, vlanId, prevPort); | 1053 | + // Revoke previous bridging table entry |
| 1047 | - flowObjectiveService.forward(prevDeviceId, prevFob.remove( | 1054 | + ForwardingObjective.Builder prevFob = |
| 1048 | - new BridgingTableObjectiveContext(mac, vlanId) | 1055 | + getForwardingObjectiveBuilder(prevDeviceId, mac, vlanId, prevPort); |
| 1049 | - )); | 1056 | + flowObjectiveService.forward(prevDeviceId, prevFob.remove( |
| 1050 | - | 1057 | + new BridgingTableObjectiveContext(mac, vlanId) |
| 1051 | - // Revoke previous IP table entry | 1058 | + )); |
| 1052 | - prevIps.forEach(ip -> { | ||
| 1053 | - if (ip.isIp4()) { | ||
| 1054 | - routingRulePopulator.revokeIpRuleForHost( | ||
| 1055 | - prevDeviceId, ip.getIp4Address(), mac, prevPort); | ||
| 1056 | - } | ||
| 1057 | - }); | ||
| 1058 | 1059 | ||
| 1059 | - // Populate new bridging table entry | 1060 | + // Revoke previous IP table entry |
| 1060 | - ForwardingObjective.Builder newFob = | 1061 | + prevIps.forEach(ip -> { |
| 1061 | - getForwardingObjectiveBuilder(newDeviceId, mac, vlanId, newPort); | 1062 | + if (ip.isIp4()) { |
| 1062 | - flowObjectiveService.forward(newDeviceId, newFob.add( | 1063 | + routingRulePopulator.revokeIpRuleForHost( |
| 1063 | - new BridgingTableObjectiveContext(mac, vlanId) | 1064 | + prevDeviceId, ip.getIp4Address(), mac, prevPort); |
| 1064 | - )); | 1065 | + } |
| 1065 | - | 1066 | + }); |
| 1066 | - // Populate new IP table entry | 1067 | + } |
| 1067 | - newIps.forEach(ip -> { | 1068 | + |
| 1068 | - if (ip.isIp4()) { | 1069 | + if (!deviceConfiguration.excludedPorts() |
| 1069 | - routingRulePopulator.populateIpRuleForHost( | 1070 | + .contains(new ConnectPoint(newDeviceId, newPort))) { |
| 1070 | - newDeviceId, ip.getIp4Address(), mac, newPort); | 1071 | + // Populate new bridging table entry |
| 1071 | - } | 1072 | + ForwardingObjective.Builder newFob = |
| 1072 | - }); | 1073 | + getForwardingObjectiveBuilder(newDeviceId, mac, vlanId, newPort); |
| 1074 | + flowObjectiveService.forward(newDeviceId, newFob.add( | ||
| 1075 | + new BridgingTableObjectiveContext(mac, vlanId) | ||
| 1076 | + )); | ||
| 1077 | + | ||
| 1078 | + // Populate new IP table entry | ||
| 1079 | + newIps.forEach(ip -> { | ||
| 1080 | + if (ip.isIp4()) { | ||
| 1081 | + routingRulePopulator.populateIpRuleForHost( | ||
| 1082 | + newDeviceId, ip.getIp4Address(), mac, newPort); | ||
| 1083 | + } | ||
| 1084 | + }); | ||
| 1085 | + } | ||
| 1073 | } | 1086 | } |
| 1074 | 1087 | ||
| 1075 | private void processHostUpdatedEvent(HostEvent event) { | 1088 | private void processHostUpdatedEvent(HostEvent event) { |
| ... | @@ -1083,21 +1096,27 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -1083,21 +1096,27 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 1083 | Set<IpAddress> newIps = event.subject().ipAddresses(); | 1096 | Set<IpAddress> newIps = event.subject().ipAddresses(); |
| 1084 | log.debug("Host {}/{} is updated", mac, vlanId); | 1097 | log.debug("Host {}/{} is updated", mac, vlanId); |
| 1085 | 1098 | ||
| 1086 | - // Revoke previous IP table entry | 1099 | + if (!deviceConfiguration.excludedPorts() |
| 1087 | - prevIps.forEach(ip -> { | 1100 | + .contains(new ConnectPoint(prevDeviceId, prevPort))) { |
| 1088 | - if (ip.isIp4()) { | 1101 | + // Revoke previous IP table entry |
| 1089 | - routingRulePopulator.revokeIpRuleForHost( | 1102 | + prevIps.forEach(ip -> { |
| 1090 | - prevDeviceId, ip.getIp4Address(), mac, prevPort); | 1103 | + if (ip.isIp4()) { |
| 1091 | - } | 1104 | + routingRulePopulator.revokeIpRuleForHost( |
| 1092 | - }); | 1105 | + prevDeviceId, ip.getIp4Address(), mac, prevPort); |
| 1106 | + } | ||
| 1107 | + }); | ||
| 1108 | + } | ||
| 1093 | 1109 | ||
| 1094 | - // Populate new IP table entry | 1110 | + if (!deviceConfiguration.excludedPorts() |
| 1095 | - newIps.forEach(ip -> { | 1111 | + .contains(new ConnectPoint(newDeviceId, newPort))) { |
| 1096 | - if (ip.isIp4()) { | 1112 | + // Populate new IP table entry |
| 1097 | - routingRulePopulator.populateIpRuleForHost( | 1113 | + newIps.forEach(ip -> { |
| 1098 | - newDeviceId, ip.getIp4Address(), mac, newPort); | 1114 | + if (ip.isIp4()) { |
| 1099 | - } | 1115 | + routingRulePopulator.populateIpRuleForHost( |
| 1100 | - }); | 1116 | + newDeviceId, ip.getIp4Address(), mac, newPort); |
| 1117 | + } | ||
| 1118 | + }); | ||
| 1119 | + } | ||
| 1101 | } | 1120 | } |
| 1102 | 1121 | ||
| 1103 | @Override | 1122 | @Override | ... | ... |
| ... | @@ -18,11 +18,13 @@ package org.onosproject.segmentrouting.config; | ... | @@ -18,11 +18,13 @@ package org.onosproject.segmentrouting.config; |
| 18 | import com.google.common.collect.HashMultimap; | 18 | import com.google.common.collect.HashMultimap; |
| 19 | import com.google.common.collect.ImmutableSet; | 19 | import com.google.common.collect.ImmutableSet; |
| 20 | import com.google.common.collect.SetMultimap; | 20 | import com.google.common.collect.SetMultimap; |
| 21 | +import com.google.common.collect.Sets; | ||
| 21 | import org.onlab.packet.Ip4Address; | 22 | import org.onlab.packet.Ip4Address; |
| 22 | import org.onlab.packet.Ip4Prefix; | 23 | import org.onlab.packet.Ip4Prefix; |
| 23 | import org.onlab.packet.IpPrefix; | 24 | import org.onlab.packet.IpPrefix; |
| 24 | import org.onlab.packet.MacAddress; | 25 | import org.onlab.packet.MacAddress; |
| 25 | import org.onlab.packet.VlanId; | 26 | import org.onlab.packet.VlanId; |
| 27 | +import org.onosproject.core.ApplicationId; | ||
| 26 | import org.onosproject.incubator.net.config.basics.ConfigException; | 28 | import org.onosproject.incubator.net.config.basics.ConfigException; |
| 27 | import org.onosproject.incubator.net.config.basics.InterfaceConfig; | 29 | import org.onosproject.incubator.net.config.basics.InterfaceConfig; |
| 28 | import org.onosproject.incubator.net.intf.Interface; | 30 | import org.onosproject.incubator.net.intf.Interface; |
| ... | @@ -51,11 +53,12 @@ import java.util.concurrent.ConcurrentHashMap; | ... | @@ -51,11 +53,12 @@ import java.util.concurrent.ConcurrentHashMap; |
| 51 | */ | 53 | */ |
| 52 | public class DeviceConfiguration implements DeviceProperties { | 54 | public class DeviceConfiguration implements DeviceProperties { |
| 53 | 55 | ||
| 54 | - private static final Logger log = LoggerFactory | 56 | + private static final Logger log = LoggerFactory.getLogger(DeviceConfiguration.class); |
| 55 | - .getLogger(DeviceConfiguration.class); | ||
| 56 | private final List<Integer> allSegmentIds = new ArrayList<>(); | 57 | private final List<Integer> allSegmentIds = new ArrayList<>(); |
| 57 | private final Map<DeviceId, SegmentRouterInfo> deviceConfigMap = new ConcurrentHashMap<>(); | 58 | private final Map<DeviceId, SegmentRouterInfo> deviceConfigMap = new ConcurrentHashMap<>(); |
| 58 | private final Map<VlanId, List<ConnectPoint>> xConnects = new ConcurrentHashMap<>(); | 59 | private final Map<VlanId, List<ConnectPoint>> xConnects = new ConcurrentHashMap<>(); |
| 60 | + private final Set<ConnectPoint> excludedPorts = Sets.newConcurrentHashSet(); | ||
| 61 | + private SegmentRoutingAppConfig appConfig; | ||
| 59 | 62 | ||
| 60 | private class SegmentRouterInfo { | 63 | private class SegmentRouterInfo { |
| 61 | int nodeSid; | 64 | int nodeSid; |
| ... | @@ -77,9 +80,11 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -77,9 +80,11 @@ public class DeviceConfiguration implements DeviceProperties { |
| 77 | * Constructs device configuration for all Segment Router devices, | 80 | * Constructs device configuration for all Segment Router devices, |
| 78 | * organizing the data into various maps for easier access. | 81 | * organizing the data into various maps for easier access. |
| 79 | * | 82 | * |
| 83 | + * @param appId application id | ||
| 80 | * @param cfgService config service | 84 | * @param cfgService config service |
| 81 | */ | 85 | */ |
| 82 | - public DeviceConfiguration(NetworkConfigRegistry cfgService) { | 86 | + public DeviceConfiguration(ApplicationId appId, |
| 87 | + NetworkConfigRegistry cfgService) { | ||
| 83 | // Read config from device subject, excluding gatewayIps and subnets. | 88 | // Read config from device subject, excluding gatewayIps and subnets. |
| 84 | Set<DeviceId> deviceSubjects = | 89 | Set<DeviceId> deviceSubjects = |
| 85 | cfgService.getSubjects(DeviceId.class, SegmentRoutingDeviceConfig.class); | 90 | cfgService.getSubjects(DeviceId.class, SegmentRoutingDeviceConfig.class); |
| ... | @@ -98,6 +103,11 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -98,6 +103,11 @@ public class DeviceConfiguration implements DeviceProperties { |
| 98 | allSegmentIds.add(info.nodeSid); | 103 | allSegmentIds.add(info.nodeSid); |
| 99 | }); | 104 | }); |
| 100 | 105 | ||
| 106 | + // Read excluded port names from config | ||
| 107 | + appConfig = cfgService.getConfig(appId, SegmentRoutingAppConfig.class); | ||
| 108 | + Set<String> excludePorts = (appConfig != null) ? | ||
| 109 | + appConfig.excludePorts() : ImmutableSet.of(); | ||
| 110 | + | ||
| 101 | // Read gatewayIps and subnets from port subject. | 111 | // Read gatewayIps and subnets from port subject. |
| 102 | Set<ConnectPoint> portSubjects = | 112 | Set<ConnectPoint> portSubjects = |
| 103 | cfgService.getSubjects(ConnectPoint.class, InterfaceConfig.class); | 113 | cfgService.getSubjects(ConnectPoint.class, InterfaceConfig.class); |
| ... | @@ -112,6 +122,12 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -112,6 +122,12 @@ public class DeviceConfiguration implements DeviceProperties { |
| 112 | return; | 122 | return; |
| 113 | } | 123 | } |
| 114 | networkInterfaces.forEach(networkInterface -> { | 124 | networkInterfaces.forEach(networkInterface -> { |
| 125 | + // Do not process excluded ports | ||
| 126 | + if (excludePorts.contains(networkInterface.name())) { | ||
| 127 | + excludedPorts.add(subject); | ||
| 128 | + return; | ||
| 129 | + } | ||
| 130 | + | ||
| 115 | VlanId vlanId = networkInterface.vlan(); | 131 | VlanId vlanId = networkInterface.vlan(); |
| 116 | ConnectPoint connectPoint = networkInterface.connectPoint(); | 132 | ConnectPoint connectPoint = networkInterface.connectPoint(); |
| 117 | DeviceId dpid = connectPoint.deviceId(); | 133 | DeviceId dpid = connectPoint.deviceId(); |
| ... | @@ -343,7 +359,13 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -343,7 +359,13 @@ public class DeviceConfiguration implements DeviceProperties { |
| 343 | if (srinfo != null) { | 359 | if (srinfo != null) { |
| 344 | log.trace("getSubnets for device{} is {}", deviceId, | 360 | log.trace("getSubnets for device{} is {}", deviceId, |
| 345 | srinfo.subnets.values()); | 361 | srinfo.subnets.values()); |
| 346 | - return ImmutableSet.copyOf(srinfo.subnets.values()); | 362 | + |
| 363 | + ImmutableSet.Builder<Ip4Prefix> builder = ImmutableSet.builder(); | ||
| 364 | + builder.addAll(srinfo.subnets.values()); | ||
| 365 | + if (deviceId.equals(appConfig.vRouterId())) { | ||
| 366 | + builder.add(Ip4Prefix.valueOf("0.0.0.0/0")); | ||
| 367 | + } | ||
| 368 | + return builder.build(); | ||
| 347 | } | 369 | } |
| 348 | return null; | 370 | return null; |
| 349 | } | 371 | } |
| ... | @@ -464,4 +486,13 @@ public class DeviceConfiguration implements DeviceProperties { | ... | @@ -464,4 +486,13 @@ public class DeviceConfiguration implements DeviceProperties { |
| 464 | SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); | 486 | SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); |
| 465 | return srinfo != null && srinfo.adjacencySids.containsKey(sid); | 487 | return srinfo != null && srinfo.adjacencySids.containsKey(sid); |
| 466 | } | 488 | } |
| 489 | + | ||
| 490 | + /** | ||
| 491 | + * Returns a set of excluded ports. | ||
| 492 | + * | ||
| 493 | + * @return excluded ports | ||
| 494 | + */ | ||
| 495 | + public Set<ConnectPoint> excludedPorts() { | ||
| 496 | + return excludedPorts; | ||
| 497 | + } | ||
| 467 | } | 498 | } |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java
| ... | @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode; | ... | @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode; |
| 21 | import com.google.common.collect.ImmutableSet; | 21 | import com.google.common.collect.ImmutableSet; |
| 22 | import org.onlab.packet.MacAddress; | 22 | import org.onlab.packet.MacAddress; |
| 23 | import org.onosproject.core.ApplicationId; | 23 | import org.onosproject.core.ApplicationId; |
| 24 | +import org.onosproject.net.DeviceId; | ||
| 24 | import org.onosproject.net.config.Config; | 25 | import org.onosproject.net.config.Config; |
| 25 | import java.util.Set; | 26 | import java.util.Set; |
| 26 | 27 | ||
| ... | @@ -31,10 +32,14 @@ import static com.google.common.base.MoreObjects.toStringHelper; | ... | @@ -31,10 +32,14 @@ import static com.google.common.base.MoreObjects.toStringHelper; |
| 31 | */ | 32 | */ |
| 32 | public class SegmentRoutingAppConfig extends Config<ApplicationId> { | 33 | public class SegmentRoutingAppConfig extends Config<ApplicationId> { |
| 33 | private static final String VROUTER_MACS = "vRouterMacs"; | 34 | private static final String VROUTER_MACS = "vRouterMacs"; |
| 35 | + private static final String VROUTER_ID = "vRouterId"; | ||
| 36 | + private static final String EXCLUDE_PORTS = "excludePorts"; | ||
| 34 | 37 | ||
| 35 | @Override | 38 | @Override |
| 36 | public boolean isValid() { | 39 | public boolean isValid() { |
| 37 | - return hasOnlyFields(VROUTER_MACS) && vRouterMacs() != null; | 40 | + return hasOnlyFields(VROUTER_MACS, VROUTER_ID, EXCLUDE_PORTS) && |
| 41 | + vRouterMacs() != null && vRouterId() != null && | ||
| 42 | + excludePorts() != null; | ||
| 38 | } | 43 | } |
| 39 | 44 | ||
| 40 | /** | 45 | /** |
| ... | @@ -88,10 +93,84 @@ public class SegmentRoutingAppConfig extends Config<ApplicationId> { | ... | @@ -88,10 +93,84 @@ public class SegmentRoutingAppConfig extends Config<ApplicationId> { |
| 88 | return this; | 93 | return this; |
| 89 | } | 94 | } |
| 90 | 95 | ||
| 96 | + /** | ||
| 97 | + * Gets vRouter device ID. | ||
| 98 | + * | ||
| 99 | + * @return vRouter device ID, or null if not valid | ||
| 100 | + */ | ||
| 101 | + public DeviceId vRouterId() { | ||
| 102 | + if (!object.has(VROUTER_ID)) { | ||
| 103 | + return null; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + try { | ||
| 107 | + return DeviceId.deviceId(object.path(VROUTER_ID).asText()); | ||
| 108 | + } catch (IllegalArgumentException e) { | ||
| 109 | + return null; | ||
| 110 | + } | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + /** | ||
| 114 | + * Sets vRouter device ID. | ||
| 115 | + * | ||
| 116 | + * @param vRouterId vRouter device ID | ||
| 117 | + * @return this {@link SegmentRoutingAppConfig} | ||
| 118 | + */ | ||
| 119 | + public SegmentRoutingAppConfig setVRouterId(DeviceId vRouterId) { | ||
| 120 | + if (vRouterId == null) { | ||
| 121 | + object.remove(VROUTER_ID); | ||
| 122 | + } else { | ||
| 123 | + object.put(VROUTER_ID, vRouterId.toString()); | ||
| 124 | + } | ||
| 125 | + return this; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + /** | ||
| 129 | + * Gets names of ports that are ignored by SegmentRouting. | ||
| 130 | + * | ||
| 131 | + * @return set of port names | ||
| 132 | + */ | ||
| 133 | + public Set<String> excludePorts() { | ||
| 134 | + if (!object.has(EXCLUDE_PORTS)) { | ||
| 135 | + return null; | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + ImmutableSet.Builder<String> builder = ImmutableSet.builder(); | ||
| 139 | + ArrayNode arrayNode = (ArrayNode) object.path(EXCLUDE_PORTS); | ||
| 140 | + for (JsonNode jsonNode : arrayNode) { | ||
| 141 | + String portName = jsonNode.asText(null); | ||
| 142 | + if (portName == null) { | ||
| 143 | + return null; | ||
| 144 | + } | ||
| 145 | + builder.add(portName); | ||
| 146 | + } | ||
| 147 | + return builder.build(); | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + /** | ||
| 151 | + * Sets names of ports that are ignored by SegmentRouting. | ||
| 152 | + * | ||
| 153 | + * @paran excludePorts names of ports that are ignored by SegmentRouting | ||
| 154 | + * @return this {@link SegmentRoutingAppConfig} | ||
| 155 | + */ | ||
| 156 | + public SegmentRoutingAppConfig setExcludePorts(Set<String> excludePorts) { | ||
| 157 | + if (excludePorts == null) { | ||
| 158 | + object.remove(EXCLUDE_PORTS); | ||
| 159 | + } else { | ||
| 160 | + ArrayNode arrayNode = mapper.createArrayNode(); | ||
| 161 | + excludePorts.forEach(portName -> { | ||
| 162 | + arrayNode.add(portName); | ||
| 163 | + }); | ||
| 164 | + object.set(EXCLUDE_PORTS, arrayNode); | ||
| 165 | + } | ||
| 166 | + return this; | ||
| 167 | + } | ||
| 168 | + | ||
| 91 | @Override | 169 | @Override |
| 92 | public String toString() { | 170 | public String toString() { |
| 93 | return toStringHelper(this) | 171 | return toStringHelper(this) |
| 94 | .add("vRouterMacs", vRouterMacs()) | 172 | .add("vRouterMacs", vRouterMacs()) |
| 173 | + .add("excludePorts", excludePorts()) | ||
| 95 | .toString(); | 174 | .toString(); |
| 96 | } | 175 | } |
| 97 | } | 176 | } | ... | ... |
| ... | @@ -24,6 +24,7 @@ import org.junit.Test; | ... | @@ -24,6 +24,7 @@ import org.junit.Test; |
| 24 | import org.onlab.packet.MacAddress; | 24 | import org.onlab.packet.MacAddress; |
| 25 | import org.onosproject.core.ApplicationId; | 25 | import org.onosproject.core.ApplicationId; |
| 26 | import org.onosproject.TestApplicationId; | 26 | import org.onosproject.TestApplicationId; |
| 27 | +import org.onosproject.net.DeviceId; | ||
| 27 | import org.onosproject.net.config.Config; | 28 | import org.onosproject.net.config.Config; |
| 28 | import org.onosproject.net.config.ConfigApplyDelegate; | 29 | import org.onosproject.net.config.ConfigApplyDelegate; |
| 29 | import org.onosproject.segmentrouting.SegmentRoutingService; | 30 | import org.onosproject.segmentrouting.SegmentRoutingService; |
| ... | @@ -32,6 +33,7 @@ import java.util.Set; | ... | @@ -32,6 +33,7 @@ import java.util.Set; |
| 32 | import static org.hamcrest.Matchers.is; | 33 | import static org.hamcrest.Matchers.is; |
| 33 | import static org.junit.Assert.assertThat; | 34 | import static org.junit.Assert.assertThat; |
| 34 | import static org.junit.Assert.assertTrue; | 35 | import static org.junit.Assert.assertTrue; |
| 36 | +import static org.junit.Assert.assertFalse; | ||
| 35 | 37 | ||
| 36 | /** | 38 | /** |
| 37 | * Tests for class {@link SegmentRoutingAppConfig}. | 39 | * Tests for class {@link SegmentRoutingAppConfig}. |
| ... | @@ -41,9 +43,34 @@ public class SegmentRoutingAppConfigTest { | ... | @@ -41,9 +43,34 @@ public class SegmentRoutingAppConfigTest { |
| 41 | new TestApplicationId(SegmentRoutingService.SR_APP_ID); | 43 | new TestApplicationId(SegmentRoutingService.SR_APP_ID); |
| 42 | 44 | ||
| 43 | private SegmentRoutingAppConfig config; | 45 | private SegmentRoutingAppConfig config; |
| 44 | - private MacAddress routerMac1; | 46 | + private SegmentRoutingAppConfig invalidConfig; |
| 45 | - private MacAddress routerMac2; | 47 | + private static final String JSON_STRING = "{" + |
| 46 | - private MacAddress routerMac3; | 48 | + "\"vRouterMacs\" : [" + |
| 49 | + " \"00:00:00:00:00:01\"," + | ||
| 50 | + " \"00:00:00:00:00:02\"" + | ||
| 51 | + "]," + | ||
| 52 | + "\"vRouterId\" : \"of:1\"," + | ||
| 53 | + "\"excludePorts\" : [" + | ||
| 54 | + " \"port1\"," + | ||
| 55 | + " \"port2\"" + | ||
| 56 | + "]}"; | ||
| 57 | + private static final String INVALID_JSON_STRING = "{" + | ||
| 58 | + "\"vRouterMacs\" : [" + | ||
| 59 | + " \"00:00:00:00:00:01\"," + | ||
| 60 | + " \"00:00:00:00:00:02\"" + | ||
| 61 | + "]," + | ||
| 62 | + "\"excludePorts\" : [" + | ||
| 63 | + " \"port1\"," + | ||
| 64 | + " \"port2\"" + | ||
| 65 | + "]}"; | ||
| 66 | + private static final MacAddress ROUTER_MAC_1 = MacAddress.valueOf("00:00:00:00:00:01"); | ||
| 67 | + private static final MacAddress ROUTER_MAC_2 = MacAddress.valueOf("00:00:00:00:00:02"); | ||
| 68 | + private static final MacAddress ROUTER_MAC_3 = MacAddress.valueOf("00:00:00:00:00:03"); | ||
| 69 | + private static final String PORT_NAME_1 = "port1"; | ||
| 70 | + private static final String PORT_NAME_2 = "port2"; | ||
| 71 | + private static final String PORT_NAME_3 = "port3"; | ||
| 72 | + private static final DeviceId VROUTER_ID_1 = DeviceId.deviceId("of:1"); | ||
| 73 | + private static final DeviceId VROUTER_ID_2 = DeviceId.deviceId("of:2"); | ||
| 47 | 74 | ||
| 48 | /** | 75 | /** |
| 49 | * Initialize test related variables. | 76 | * Initialize test related variables. |
| ... | @@ -52,55 +79,107 @@ public class SegmentRoutingAppConfigTest { | ... | @@ -52,55 +79,107 @@ public class SegmentRoutingAppConfigTest { |
| 52 | */ | 79 | */ |
| 53 | @Before | 80 | @Before |
| 54 | public void setUp() throws Exception { | 81 | public void setUp() throws Exception { |
| 55 | - String jsonString = "{" + | ||
| 56 | - "\"vRouterMacs\" : [" + | ||
| 57 | - " \"00:00:00:00:00:01\"," + | ||
| 58 | - " \"00:00:00:00:00:02\"" + | ||
| 59 | - "]}"; | ||
| 60 | - | ||
| 61 | - routerMac1 = MacAddress.valueOf("00:00:00:00:00:01"); | ||
| 62 | - routerMac2 = MacAddress.valueOf("00:00:00:00:00:02"); | ||
| 63 | - routerMac3 = MacAddress.valueOf("00:00:00:00:00:03"); | ||
| 64 | - | ||
| 65 | ApplicationId subject = APP_ID; | 82 | ApplicationId subject = APP_ID; |
| 66 | String key = SegmentRoutingService.SR_APP_ID; | 83 | String key = SegmentRoutingService.SR_APP_ID; |
| 67 | ObjectMapper mapper = new ObjectMapper(); | 84 | ObjectMapper mapper = new ObjectMapper(); |
| 68 | - JsonNode jsonNode = mapper.readTree(jsonString); | 85 | + JsonNode jsonNode = mapper.readTree(JSON_STRING); |
| 86 | + JsonNode invalidJsonNode = mapper.readTree(INVALID_JSON_STRING); | ||
| 69 | ConfigApplyDelegate delegate = new MockDelegate(); | 87 | ConfigApplyDelegate delegate = new MockDelegate(); |
| 70 | 88 | ||
| 71 | config = new SegmentRoutingAppConfig(); | 89 | config = new SegmentRoutingAppConfig(); |
| 72 | config.init(subject, key, jsonNode, mapper, delegate); | 90 | config.init(subject, key, jsonNode, mapper, delegate); |
| 91 | + invalidConfig = new SegmentRoutingAppConfig(); | ||
| 92 | + invalidConfig.init(subject, key, invalidJsonNode, mapper, delegate); | ||
| 73 | } | 93 | } |
| 74 | 94 | ||
| 75 | /** | 95 | /** |
| 76 | - * Tests vRouters getter. | 96 | + * Tests config validity. |
| 77 | * | 97 | * |
| 78 | * @throws Exception | 98 | * @throws Exception |
| 79 | */ | 99 | */ |
| 80 | @Test | 100 | @Test |
| 81 | - public void testVRouters() throws Exception { | 101 | + public void testIsValid() throws Exception { |
| 82 | assertTrue(config.isValid()); | 102 | assertTrue(config.isValid()); |
| 103 | + assertFalse(invalidConfig.isValid()); | ||
| 104 | + } | ||
| 83 | 105 | ||
| 106 | + /** | ||
| 107 | + * Tests vRouterMacs getter. | ||
| 108 | + * | ||
| 109 | + * @throws Exception | ||
| 110 | + */ | ||
| 111 | + @Test | ||
| 112 | + public void testVRouters() throws Exception { | ||
| 84 | Set<MacAddress> vRouters = config.vRouterMacs(); | 113 | Set<MacAddress> vRouters = config.vRouterMacs(); |
| 85 | assertThat(vRouters.size(), is(2)); | 114 | assertThat(vRouters.size(), is(2)); |
| 86 | - assertTrue(vRouters.contains(routerMac1)); | 115 | + assertTrue(vRouters.contains(ROUTER_MAC_1)); |
| 87 | - assertTrue(vRouters.contains(routerMac2)); | 116 | + assertTrue(vRouters.contains(ROUTER_MAC_2)); |
| 88 | } | 117 | } |
| 89 | 118 | ||
| 90 | /** | 119 | /** |
| 91 | - * Tests vRouters setter. | 120 | + * Tests vRouterMacs setter. |
| 92 | * | 121 | * |
| 93 | * @throws Exception | 122 | * @throws Exception |
| 94 | */ | 123 | */ |
| 95 | @Test | 124 | @Test |
| 96 | public void testSetVRouters() throws Exception { | 125 | public void testSetVRouters() throws Exception { |
| 97 | ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder(); | 126 | ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder(); |
| 98 | - builder.add(routerMac3); | 127 | + builder.add(ROUTER_MAC_3); |
| 99 | config.setVRouterMacs(builder.build()); | 128 | config.setVRouterMacs(builder.build()); |
| 100 | 129 | ||
| 101 | Set<MacAddress> macs = config.vRouterMacs(); | 130 | Set<MacAddress> macs = config.vRouterMacs(); |
| 102 | assertThat(macs.size(), is(1)); | 131 | assertThat(macs.size(), is(1)); |
| 103 | - assertTrue(macs.contains(routerMac3)); | 132 | + assertTrue(macs.contains(ROUTER_MAC_3)); |
| 133 | + } | ||
| 134 | + | ||
| 135 | + /** | ||
| 136 | + * Tests vRouterId getter. | ||
| 137 | + * | ||
| 138 | + * @throws Exception | ||
| 139 | + */ | ||
| 140 | + @Test | ||
| 141 | + public void testVRouterId() throws Exception { | ||
| 142 | + assertThat(config.vRouterId(), is(VROUTER_ID_1)); | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + /** | ||
| 146 | + * Tests vRouterId setter. | ||
| 147 | + * | ||
| 148 | + * @throws Exception | ||
| 149 | + */ | ||
| 150 | + @Test | ||
| 151 | + public void testSetVRouterId() throws Exception { | ||
| 152 | + config.setVRouterId(VROUTER_ID_2); | ||
| 153 | + assertThat(config.vRouterId(), is(VROUTER_ID_2)); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + /** | ||
| 157 | + * Tests excludePort getter. | ||
| 158 | + * | ||
| 159 | + * @throws Exception | ||
| 160 | + */ | ||
| 161 | + @Test | ||
| 162 | + public void testExcludePorts() throws Exception { | ||
| 163 | + Set<String> excludePorts = config.excludePorts(); | ||
| 164 | + assertThat(excludePorts.size(), is(2)); | ||
| 165 | + assertTrue(excludePorts.contains(PORT_NAME_1)); | ||
| 166 | + assertTrue(excludePorts.contains(PORT_NAME_2)); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + /** | ||
| 170 | + * Tests excludePort setter. | ||
| 171 | + * | ||
| 172 | + * @throws Exception | ||
| 173 | + */ | ||
| 174 | + @Test | ||
| 175 | + public void testSetExcludePorts() throws Exception { | ||
| 176 | + ImmutableSet.Builder<String> builder = ImmutableSet.builder(); | ||
| 177 | + builder.add(PORT_NAME_3); | ||
| 178 | + config.setExcludePorts(builder.build()); | ||
| 179 | + | ||
| 180 | + Set<String> excludePorts = config.excludePorts(); | ||
| 181 | + assertThat(excludePorts.size(), is(1)); | ||
| 182 | + assertTrue(excludePorts.contains(PORT_NAME_3)); | ||
| 104 | } | 183 | } |
| 105 | 184 | ||
| 106 | private class MockDelegate implements ConfigApplyDelegate { | 185 | private class MockDelegate implements ConfigApplyDelegate { | ... | ... |
| ... | @@ -27,10 +27,19 @@ | ... | @@ -27,10 +27,19 @@ |
| 27 | "of:0000000000000002/4" : { | 27 | "of:0000000000000002/4" : { |
| 28 | "interfaces" : [ | 28 | "interfaces" : [ |
| 29 | { | 29 | { |
| 30 | - "ips" : [ "10.0.2.254/24", "0.0.0.0/0" ], | 30 | + "ips" : [ "10.0.2.254/24" ], |
| 31 | "vlan" : "-1" | 31 | "vlan" : "-1" |
| 32 | } | 32 | } |
| 33 | ] | 33 | ] |
| 34 | + }, | ||
| 35 | + "of:0000000000000002/5" : { | ||
| 36 | + "interfaces" : [ | ||
| 37 | + { | ||
| 38 | + "name" : "2/5/1", | ||
| 39 | + "ips" : [ "100.0.0.0/24" ], | ||
| 40 | + "vlan" : "-1" | ||
| 41 | + } | ||
| 42 | + ] | ||
| 34 | } | 43 | } |
| 35 | }, | 44 | }, |
| 36 | "devices" : { | 45 | "devices" : { |
| ... | @@ -112,6 +121,10 @@ | ... | @@ -112,6 +121,10 @@ |
| 112 | "segmentrouting" : { | 121 | "segmentrouting" : { |
| 113 | "vRouterMacs" : [ | 122 | "vRouterMacs" : [ |
| 114 | "00:00:00:aa:00:02" | 123 | "00:00:00:aa:00:02" |
| 124 | + ], | ||
| 125 | + "vRouterId" : "of:0000000000000002", | ||
| 126 | + "excludePorts" : [ | ||
| 127 | + "2/5/1" | ||
| 115 | ] | 128 | ] |
| 116 | } | 129 | } |
| 117 | } | 130 | } | ... | ... |
-
Please register or login to post a comment