CORD-417 Update group buckets when a VM is created or terminated
Change-Id: Ib1aba443708a13499f21c08b39b777c876595fac
Showing
2 changed files
with
110 additions
and
47 deletions
| ... | @@ -103,7 +103,6 @@ public class CordVtn implements CordVtnService { | ... | @@ -103,7 +103,6 @@ public class CordVtn implements CordVtnService { |
| 103 | .register(NodeState.class); | 103 | .register(NodeState.class); |
| 104 | private static final String DEFAULT_BRIDGE = "br-int"; | 104 | private static final String DEFAULT_BRIDGE = "br-int"; |
| 105 | private static final String VPORT_PREFIX = "tap"; | 105 | private static final String VPORT_PREFIX = "tap"; |
| 106 | - private static final String GWPORT_PREFIX = "qr-"; | ||
| 107 | private static final String DEFAULT_TUNNEL = "vxlan"; | 106 | private static final String DEFAULT_TUNNEL = "vxlan"; |
| 108 | private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() { | 107 | private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() { |
| 109 | { | 108 | { |
| ... | @@ -379,13 +378,14 @@ public class CordVtn implements CordVtnService { | ... | @@ -379,13 +378,14 @@ public class CordVtn implements CordVtnService { |
| 379 | * @param node cordvtn node | 378 | * @param node cordvtn node |
| 380 | */ | 379 | */ |
| 381 | private void postInit(CordVtnNode node) { | 380 | private void postInit(CordVtnNode node) { |
| 382 | - log.info("Initializing {}", node.hostname()); | ||
| 383 | disconnect(node); | 381 | disconnect(node); |
| 384 | 382 | ||
| 385 | ruleInstaller.init(node.intBrId(), getTunnelPort(node.intBrId())); | 383 | ruleInstaller.init(node.intBrId(), getTunnelPort(node.intBrId())); |
| 386 | hostService.getConnectedHosts(node.intBrId()) | 384 | hostService.getConnectedHosts(node.intBrId()) |
| 387 | .stream() | 385 | .stream() |
| 388 | .forEach(vmHandler::connected); | 386 | .forEach(vmHandler::connected); |
| 387 | + | ||
| 388 | + log.info("Finished initializing {}", node.hostname()); | ||
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | /** | 391 | /** |
| ... | @@ -646,13 +646,16 @@ public class CordVtn implements CordVtnService { | ... | @@ -646,13 +646,16 @@ public class CordVtn implements CordVtnService { |
| 646 | private Set<Host> getHostsWithOpenstackNetwork(OpenstackNetwork vNet) { | 646 | private Set<Host> getHostsWithOpenstackNetwork(OpenstackNetwork vNet) { |
| 647 | checkNotNull(vNet); | 647 | checkNotNull(vNet); |
| 648 | 648 | ||
| 649 | - return openstackService.ports(vNet.id()).stream() | 649 | + Set<Host> hosts = openstackService.ports(vNet.id()).stream() |
| 650 | .filter(port -> port.deviceOwner().contains("compute")) | 650 | .filter(port -> port.deviceOwner().contains("compute")) |
| 651 | .map(port -> hostService.getHostsByMac(port.macAddress()) | 651 | .map(port -> hostService.getHostsByMac(port.macAddress()) |
| 652 | .stream() | 652 | .stream() |
| 653 | .findFirst() | 653 | .findFirst() |
| 654 | .orElse(null)) | 654 | .orElse(null)) |
| 655 | .collect(Collectors.toSet()); | 655 | .collect(Collectors.toSet()); |
| 656 | + | ||
| 657 | + hosts.remove(null); | ||
| 658 | + return hosts; | ||
| 656 | } | 659 | } |
| 657 | 660 | ||
| 658 | /** | 661 | /** |
| ... | @@ -687,16 +690,15 @@ public class CordVtn implements CordVtnService { | ... | @@ -687,16 +690,15 @@ public class CordVtn implements CordVtnService { |
| 687 | } | 690 | } |
| 688 | 691 | ||
| 689 | /** | 692 | /** |
| 690 | - * Returns if the host is gateway interface. | 693 | + * Returns if the host is VM or not. |
| 691 | - * This codes should be removed after adding proxy arp for the gateway. | ||
| 692 | * | 694 | * |
| 693 | * @param host host | 695 | * @param host host |
| 694 | - * @return true if the host is gateway | 696 | + * @return true if the host is a VM. |
| 695 | */ | 697 | */ |
| 696 | - private boolean isGateway(Host host) { | 698 | + private boolean isVm(Host host) { |
| 697 | Port port = deviceService.getPort(host.location().deviceId(), | 699 | Port port = deviceService.getPort(host.location().deviceId(), |
| 698 | host.location().port()); | 700 | host.location().port()); |
| 699 | - return port.annotations().value("portName").contains(GWPORT_PREFIX); | 701 | + return port.annotations().value("portName").contains(VPORT_PREFIX); |
| 700 | } | 702 | } |
| 701 | 703 | ||
| 702 | /** | 704 | /** |
| ... | @@ -892,8 +894,8 @@ public class CordVtn implements CordVtnService { | ... | @@ -892,8 +894,8 @@ public class CordVtn implements CordVtnService { |
| 892 | 894 | ||
| 893 | @Override | 895 | @Override |
| 894 | public void connected(Host host) { | 896 | public void connected(Host host) { |
| 895 | - // TODO remove check gateway here after applying network config host provider | 897 | + // TODO remove check VM here after applying network config host provider |
| 896 | - if (isGateway(host)) { | 898 | + if (!isVm(host)) { |
| 897 | return; | 899 | return; |
| 898 | } | 900 | } |
| 899 | 901 | ||
| ... | @@ -924,7 +926,11 @@ public class CordVtn implements CordVtnService { | ... | @@ -924,7 +926,11 @@ public class CordVtn implements CordVtnService { |
| 924 | checkNotNull(getRemoteIp(host.location().deviceId())).getIp4Address(), | 926 | checkNotNull(getRemoteIp(host.location().deviceId())).getIp4Address(), |
| 925 | vNet); | 927 | vNet); |
| 926 | 928 | ||
| 927 | - // TODO add new VM to related service group if exists | 929 | + CordService service = getCordService(vNet); |
| 930 | + // TODO check if the service needs an update on its group buckets after done CORD-433 | ||
| 931 | + if (service != null) { | ||
| 932 | + ruleInstaller.updateServiceGroup(service); | ||
| 933 | + } | ||
| 928 | } | 934 | } |
| 929 | 935 | ||
| 930 | @Override | 936 | @Override |
| ... | @@ -943,7 +949,12 @@ public class CordVtn implements CordVtnService { | ... | @@ -943,7 +949,12 @@ public class CordVtn implements CordVtnService { |
| 943 | log.info("VM {} is vanished", host.id()); | 949 | log.info("VM {} is vanished", host.id()); |
| 944 | ruleInstaller.removeBasicConnectionRules(host); | 950 | ruleInstaller.removeBasicConnectionRules(host); |
| 945 | 951 | ||
| 946 | - // TODO remove the VM from related service group if exists | 952 | + CordService service = getCordService(vNet); |
| 953 | + // TODO check if the service needs an update on its group buckets after done CORD-433 | ||
| 954 | + if (service != null) { | ||
| 955 | + ruleInstaller.updateServiceGroup(service); | ||
| 956 | + } | ||
| 957 | + | ||
| 947 | hostNetMap.remove(host.id()); | 958 | hostNetMap.remove(host.id()); |
| 948 | } | 959 | } |
| 949 | } | 960 | } | ... | ... |
| ... | @@ -70,6 +70,7 @@ import org.onosproject.openstackswitching.OpenstackNetwork; | ... | @@ -70,6 +70,7 @@ import org.onosproject.openstackswitching.OpenstackNetwork; |
| 70 | import org.onosproject.openstackswitching.OpenstackSubnet; | 70 | import org.onosproject.openstackswitching.OpenstackSubnet; |
| 71 | import org.slf4j.Logger; | 71 | import org.slf4j.Logger; |
| 72 | 72 | ||
| 73 | +import java.util.ArrayList; | ||
| 73 | import java.util.List; | 74 | import java.util.List; |
| 74 | import java.util.Map; | 75 | import java.util.Map; |
| 75 | import java.util.NoSuchElementException; | 76 | import java.util.NoSuchElementException; |
| ... | @@ -188,40 +189,6 @@ public class CordVtnRuleInstaller { | ... | @@ -188,40 +189,6 @@ public class CordVtnRuleInstaller { |
| 188 | } | 189 | } |
| 189 | 190 | ||
| 190 | /** | 191 | /** |
| 191 | - * Populates service dependency rules. | ||
| 192 | - * | ||
| 193 | - * @param tService tenant cord service | ||
| 194 | - * @param pService provider cord service | ||
| 195 | - */ | ||
| 196 | - public void populateServiceDependencyRules(CordService tService, CordService pService) { | ||
| 197 | - checkNotNull(tService); | ||
| 198 | - checkNotNull(pService); | ||
| 199 | - | ||
| 200 | - Ip4Prefix srcRange = tService.serviceIpRange().getIp4Prefix(); | ||
| 201 | - Ip4Prefix dstRange = pService.serviceIpRange().getIp4Prefix(); | ||
| 202 | - Ip4Address serviceIp = pService.serviceIp().getIp4Address(); | ||
| 203 | - | ||
| 204 | - Map<DeviceId, GroupId> outGroups = Maps.newHashMap(); | ||
| 205 | - Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap(); | ||
| 206 | - | ||
| 207 | - for (Device device : deviceService.getAvailableDevices(SWITCH)) { | ||
| 208 | - GroupId groupId = createServiceGroup(device.id(), pService); | ||
| 209 | - outGroups.put(device.id(), groupId); | ||
| 210 | - | ||
| 211 | - Set<PortNumber> vms = tService.hosts().keySet() | ||
| 212 | - .stream() | ||
| 213 | - .filter(host -> host.location().deviceId().equals(device.id())) | ||
| 214 | - .map(host -> host.location().port()) | ||
| 215 | - .collect(Collectors.toSet()); | ||
| 216 | - inPorts.put(device.id(), vms); | ||
| 217 | - } | ||
| 218 | - | ||
| 219 | - populateIndirectAccessRule(srcRange, serviceIp, outGroups); | ||
| 220 | - populateDirectAccessRule(srcRange, dstRange); | ||
| 221 | - populateInServiceRule(inPorts, outGroups); | ||
| 222 | - } | ||
| 223 | - | ||
| 224 | - /** | ||
| 225 | * Removes basic rules related to a given flow information. | 192 | * Removes basic rules related to a given flow information. |
| 226 | * | 193 | * |
| 227 | * @param host host to be removed | 194 | * @param host host to be removed |
| ... | @@ -263,13 +230,46 @@ public class CordVtnRuleInstaller { | ... | @@ -263,13 +230,46 @@ public class CordVtnRuleInstaller { |
| 263 | if (dstIp != null && dstIp.equals(ip.toIpPrefix())) { | 230 | if (dstIp != null && dstIp.equals(ip.toIpPrefix())) { |
| 264 | processFlowRule(false, flowRule); | 231 | processFlowRule(false, flowRule); |
| 265 | } | 232 | } |
| 266 | - | ||
| 267 | } | 233 | } |
| 268 | 234 | ||
| 269 | // TODO uninstall same network access rule in access table if no vm exists in the network | 235 | // TODO uninstall same network access rule in access table if no vm exists in the network |
| 270 | } | 236 | } |
| 271 | 237 | ||
| 272 | /** | 238 | /** |
| 239 | + * Populates service dependency rules. | ||
| 240 | + * | ||
| 241 | + * @param tService tenant cord service | ||
| 242 | + * @param pService provider cord service | ||
| 243 | + */ | ||
| 244 | + public void populateServiceDependencyRules(CordService tService, CordService pService) { | ||
| 245 | + checkNotNull(tService); | ||
| 246 | + checkNotNull(pService); | ||
| 247 | + | ||
| 248 | + Ip4Prefix srcRange = tService.serviceIpRange().getIp4Prefix(); | ||
| 249 | + Ip4Prefix dstRange = pService.serviceIpRange().getIp4Prefix(); | ||
| 250 | + Ip4Address serviceIp = pService.serviceIp().getIp4Address(); | ||
| 251 | + | ||
| 252 | + Map<DeviceId, GroupId> outGroups = Maps.newHashMap(); | ||
| 253 | + Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap(); | ||
| 254 | + | ||
| 255 | + for (Device device : deviceService.getAvailableDevices(SWITCH)) { | ||
| 256 | + GroupId groupId = createServiceGroup(device.id(), pService); | ||
| 257 | + outGroups.put(device.id(), groupId); | ||
| 258 | + | ||
| 259 | + Set<PortNumber> vms = tService.hosts().keySet() | ||
| 260 | + .stream() | ||
| 261 | + .filter(host -> host.location().deviceId().equals(device.id())) | ||
| 262 | + .map(host -> host.location().port()) | ||
| 263 | + .collect(Collectors.toSet()); | ||
| 264 | + inPorts.put(device.id(), vms); | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + populateIndirectAccessRule(srcRange, serviceIp, outGroups); | ||
| 268 | + populateDirectAccessRule(srcRange, dstRange); | ||
| 269 | + populateInServiceRule(inPorts, outGroups); | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + /** | ||
| 273 | * Removes service dependency rules. | 273 | * Removes service dependency rules. |
| 274 | * | 274 | * |
| 275 | * @param tService tenant cord service | 275 | * @param tService tenant cord service |
| ... | @@ -324,6 +324,58 @@ public class CordVtnRuleInstaller { | ... | @@ -324,6 +324,58 @@ public class CordVtnRuleInstaller { |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | /** | 326 | /** |
| 327 | + * Updates group buckets for a given service to all devices. | ||
| 328 | + * | ||
| 329 | + * @param service cord service | ||
| 330 | + */ | ||
| 331 | + public void updateServiceGroup(CordService service) { | ||
| 332 | + checkNotNull(service); | ||
| 333 | + | ||
| 334 | + GroupKey groupKey = getGroupKey(service.id()); | ||
| 335 | + | ||
| 336 | + for (Device device : deviceService.getAvailableDevices(SWITCH)) { | ||
| 337 | + DeviceId deviceId = device.id(); | ||
| 338 | + if (!mastershipService.isLocalMaster(deviceId)) { | ||
| 339 | + continue; | ||
| 340 | + } | ||
| 341 | + | ||
| 342 | + Group group = groupService.getGroup(deviceId, groupKey); | ||
| 343 | + if (group == null) { | ||
| 344 | + log.debug("No group exists for service {} in {}", service.id(), deviceId); | ||
| 345 | + continue; | ||
| 346 | + } | ||
| 347 | + | ||
| 348 | + List<GroupBucket> oldBuckets = group.buckets().buckets(); | ||
| 349 | + List<GroupBucket> newBuckets = getServiceGroupBuckets( | ||
| 350 | + deviceId, service.segmentationId(), service.hosts()).buckets(); | ||
| 351 | + | ||
| 352 | + if (oldBuckets.equals(newBuckets)) { | ||
| 353 | + continue; | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + List<GroupBucket> bucketsToRemove = new ArrayList<>(oldBuckets); | ||
| 357 | + bucketsToRemove.removeAll(newBuckets); | ||
| 358 | + if (!bucketsToRemove.isEmpty()) { | ||
| 359 | + groupService.removeBucketsFromGroup( | ||
| 360 | + deviceId, | ||
| 361 | + groupKey, | ||
| 362 | + new GroupBuckets(bucketsToRemove), | ||
| 363 | + groupKey, appId); | ||
| 364 | + } | ||
| 365 | + | ||
| 366 | + List<GroupBucket> bucketsToAdd = new ArrayList<>(newBuckets); | ||
| 367 | + bucketsToAdd.removeAll(oldBuckets); | ||
| 368 | + if (!bucketsToAdd.isEmpty()) { | ||
| 369 | + groupService.addBucketsToGroup( | ||
| 370 | + deviceId, | ||
| 371 | + groupKey, | ||
| 372 | + new GroupBuckets(bucketsToAdd), | ||
| 373 | + groupKey, appId); | ||
| 374 | + } | ||
| 375 | + } | ||
| 376 | + } | ||
| 377 | + | ||
| 378 | + /** | ||
| 327 | * Creates a new group for a given service. | 379 | * Creates a new group for a given service. |
| 328 | * | 380 | * |
| 329 | * @param deviceId device id to create a group | 381 | * @param deviceId device id to create a group | ... | ... |
-
Please register or login to post a comment