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