Hyunsun Moon
Committed by Gerrit Code Review

CORD-564 Remove flow rules completely when a VM or dependency removed

Change-Id: I5d1956992c9353c9a9080bf6f59a8ff73cce32c0
...@@ -176,7 +176,7 @@ public final class CordService { ...@@ -176,7 +176,7 @@ public final class CordService {
176 * @param netName network name 176 * @param netName network name
177 * @return network type, or PRIVATE if it doesn't match any type 177 * @return network type, or PRIVATE if it doesn't match any type
178 */ 178 */
179 - public static ServiceType getServiceType(String netName) { 179 + private ServiceType getServiceType(String netName) {
180 checkNotNull(netName); 180 checkNotNull(netName);
181 181
182 String name = netName.toUpperCase(); 182 String name = netName.toUpperCase();
......
...@@ -30,7 +30,6 @@ import org.onlab.packet.IpAddress; ...@@ -30,7 +30,6 @@ import org.onlab.packet.IpAddress;
30 import org.onlab.packet.MacAddress; 30 import org.onlab.packet.MacAddress;
31 import org.onlab.packet.VlanId; 31 import org.onlab.packet.VlanId;
32 import org.onosproject.cordvtn.api.CordService; 32 import org.onosproject.cordvtn.api.CordService;
33 -import org.onosproject.cordvtn.api.CordService.ServiceType;
34 import org.onosproject.cordvtn.api.CordServiceId; 33 import org.onosproject.cordvtn.api.CordServiceId;
35 import org.onosproject.cordvtn.api.CordVtnConfig; 34 import org.onosproject.cordvtn.api.CordVtnConfig;
36 import org.onosproject.cordvtn.api.CordVtnNode; 35 import org.onosproject.cordvtn.api.CordVtnNode;
...@@ -88,7 +87,6 @@ import java.util.stream.StreamSupport; ...@@ -88,7 +87,6 @@ import java.util.stream.StreamSupport;
88 import static com.google.common.base.Preconditions.checkNotNull; 87 import static com.google.common.base.Preconditions.checkNotNull;
89 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; 88 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
90 import static org.onlab.util.Tools.groupedThreads; 89 import static org.onlab.util.Tools.groupedThreads;
91 -import static org.onosproject.cordvtn.api.CordService.getServiceType;
92 import static org.slf4j.LoggerFactory.getLogger; 90 import static org.slf4j.LoggerFactory.getLogger;
93 91
94 /** 92 /**
...@@ -234,7 +232,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -234,7 +232,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
234 } 232 }
235 233
236 log.info("Service dependency from {} to {} created.", tService.id().id(), pService.id().id()); 234 log.info("Service dependency from {} to {} created.", tService.id().id(), pService.id().id());
237 - ruleInstaller.populateServiceDependencyRules(tService, pService, isBidirectional); 235 + ruleInstaller.populateServiceDependencyRules(tService, pService, isBidirectional, true);
238 } 236 }
239 237
240 @Override 238 @Override
...@@ -248,7 +246,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -248,7 +246,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
248 } 246 }
249 247
250 log.info("Service dependency from {} to {} removed.", tService.id().id(), pService.id().id()); 248 log.info("Service dependency from {} to {} removed.", tService.id().id(), pService.id().id());
251 - ruleInstaller.removeServiceDependencyRules(tService, pService); 249 + ruleInstaller.populateServiceDependencyRules(tService, pService, true, false);
252 } 250 }
253 251
254 @Override 252 @Override
...@@ -434,10 +432,9 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -434,10 +432,9 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
434 CordServiceId serviceId = CordServiceId.of(osNet.getId()); 432 CordServiceId serviceId = CordServiceId.of(osNet.getId());
435 // here it assumes all cord service networks has only one subnet 433 // here it assumes all cord service networks has only one subnet
436 Subnet osSubnet = osNet.getNeutronSubnets().stream() 434 Subnet osSubnet = osNet.getNeutronSubnets().stream()
437 - .findFirst() 435 + .findFirst().orElse(null);
438 - .orElse(null);
439 if (osSubnet == null) { 436 if (osSubnet == null) {
440 - log.warn("Couldn't find OpenStack subnet for service {}", serviceId.id()); 437 + log.warn("Couldn't find OpenStack subnet for network {}", serviceId.id());
441 return null; 438 return null;
442 } 439 }
443 440
...@@ -445,12 +442,11 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -445,12 +442,11 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
445 .stream() 442 .stream()
446 .collect(Collectors.toMap(host -> host, this::getTunnelIp)); 443 .collect(Collectors.toMap(host -> host, this::getTunnelIp));
447 444
448 - ServiceType serviceType = getServiceType(osNet.getName());
449 // allows working without XOS for now 445 // allows working without XOS for now
450 Set<CordServiceId> tServices = Sets.newHashSet(); 446 Set<CordServiceId> tServices = Sets.newHashSet();
451 Set<CordServiceId> pServices = Sets.newHashSet(); 447 Set<CordServiceId> pServices = Sets.newHashSet();
452 448
453 - if (xosClient.access() != null && serviceType != ServiceType.MANAGEMENT) { 449 + if (xosClient.access() != null) {
454 tServices = xosClient.vtnServiceApi().getTenantServices(serviceId.id()) 450 tServices = xosClient.vtnServiceApi().getTenantServices(serviceId.id())
455 .stream() 451 .stream()
456 .map(CordServiceId::of) 452 .map(CordServiceId::of)
...@@ -561,27 +557,17 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -561,27 +557,17 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
561 virtualSubscriberGatewayAdded(host, serviceVlan); 557 virtualSubscriberGatewayAdded(host, serviceVlan);
562 } 558 }
563 559
564 - String osNetId = host.annotations().value(SERVICE_ID); 560 + String serviceId = host.annotations().value(SERVICE_ID);
565 - if (osNetId == null) { 561 + if (serviceId == null) {
566 - // ignore this host, it is not the service VM, or it's a vSG 562 + // ignore this host, it is not a service VM
567 return; 563 return;
568 } 564 }
569 565
570 - OSClient osClient = OSFactory.clientFromAccess(osAccess); 566 + log.info("VM is detected, MAC: {} IP: {}", host.mac(), host.ipAddresses());
571 - Network osNet = osClient.networking().network().get(osNetId);
572 - if (osNet == null) {
573 - log.warn("Failed to get OpenStack network {} for VM {}.",
574 - osNetId, host.id());
575 - return;
576 - }
577 567
578 - log.info("VM is detected, MAC: {} IP: {}", 568 + CordService service = getCordService(CordServiceId.of(serviceId));
579 - host.mac(),
580 - host.ipAddresses().stream().findFirst().get());
581 -
582 - CordService service = getCordService(osNet);
583 if (service == null) { 569 if (service == null) {
584 - log.warn("Failed to get CordService for {}", osNet.getName()); 570 + log.warn("Failed to get CordService for {}", serviceId);
585 return; 571 return;
586 } 572 }
587 573
...@@ -599,7 +585,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -599,7 +585,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
599 service.providerServices().stream().forEach( 585 service.providerServices().stream().forEach(
600 pServiceId -> createServiceDependency(service.id(), pServiceId, true)); 586 pServiceId -> createServiceDependency(service.id(), pServiceId, true));
601 587
602 - ruleInstaller.updateServiceGroup(service); 588 + ruleInstaller.updateProviderServiceGroup(service);
603 // sends gratuitous ARP here for the case of adding existing VMs 589 // sends gratuitous ARP here for the case of adding existing VMs
604 // when ONOS or cordvtn app is restarted 590 // when ONOS or cordvtn app is restarted
605 arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(host)); 591 arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(host));
...@@ -607,7 +593,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -607,7 +593,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
607 } 593 }
608 594
609 registerDhcpLease(host, service); 595 registerDhcpLease(host, service);
610 - ruleInstaller.populateBasicConnectionRules(host, getTunnelIp(host), osNet); 596 + ruleInstaller.populateBasicConnectionRules(host, service, true);
611 } 597 }
612 598
613 /** 599 /**
...@@ -618,52 +604,45 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -618,52 +604,45 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
618 private void serviceVmRemoved(Host host) { 604 private void serviceVmRemoved(Host host) {
619 checkNotNull(osAccess, "OpenStack access is not set"); 605 checkNotNull(osAccess, "OpenStack access is not set");
620 606
621 - String serviceVlan = host.annotations().value(S_TAG); 607 + if (host.annotations().value(S_TAG) != null) {
622 - if (serviceVlan != null) {
623 virtualSubscriberGatewayRemoved(host); 608 virtualSubscriberGatewayRemoved(host);
624 } 609 }
625 610
626 - String osNetId = host.annotations().value(SERVICE_ID); 611 + String serviceId = host.annotations().value(SERVICE_ID);
627 - if (osNetId == null) { 612 + if (serviceId == null) {
628 - // ignore it, it's not the service VM or it's a vSG 613 + // ignore it, it's not a service VM
629 - return;
630 - }
631 -
632 - OSClient osClient = OSFactory.clientFromAccess(osAccess);
633 - Network osNet = osClient.networking().network().get(osNetId);
634 - if (osNet == null) {
635 - log.warn("Failed to get OpenStack network {} for VM {}",
636 - osNetId, host.id());
637 return; 614 return;
638 } 615 }
639 616
640 - log.info("VM is vanished, MAC: {} IP: {}", 617 + log.info("VM is vanished, MAC: {} IP: {}", host.mac(), host.ipAddresses());
641 - host.mac(),
642 - host.ipAddresses().stream().findFirst().get());
643 618
644 - ruleInstaller.removeBasicConnectionRules(host); 619 + CordService service = getCordService(CordServiceId.of(serviceId));
645 - dhcpService.removeStaticMapping(host.mac());
646 -
647 - CordService service = getCordService(osNet);
648 if (service == null) { 620 if (service == null) {
621 + log.warn("Failed to get CORD service for {}", serviceId);
649 return; 622 return;
650 } 623 }
624 + // TODO need to consider the case that the network is removed also
651 625
652 switch (service.serviceType()) { 626 switch (service.serviceType()) {
653 case MANAGEMENT: 627 case MANAGEMENT:
654 - ruleInstaller.removeManagementNetworkRules(host, service);
655 break; 628 break;
656 case PRIVATE: 629 case PRIVATE:
657 - if (getHostsWithOpenstackNetwork(osNet).isEmpty()) { 630 + if (service.hosts().isEmpty()) {
658 arpProxy.removeGateway(service.serviceIp()); 631 arpProxy.removeGateway(service.serviceIp());
659 } 632 }
660 case PUBLIC: 633 case PUBLIC:
661 default: 634 default:
662 if (!service.tenantServices().isEmpty()) { 635 if (!service.tenantServices().isEmpty()) {
663 - ruleInstaller.updateServiceGroup(service); 636 + ruleInstaller.updateProviderServiceGroup(service);
637 + }
638 + if (!service.providerServices().isEmpty()) {
639 + ruleInstaller.updateTenantServiceVm(host, service);
664 } 640 }
665 break; 641 break;
666 } 642 }
643 +
644 + dhcpService.removeStaticMapping(host.mac());
645 + ruleInstaller.populateBasicConnectionRules(host, service, false);
667 } 646 }
668 647
669 648
......
...@@ -53,15 +53,12 @@ import org.onosproject.net.flow.FlowRuleService; ...@@ -53,15 +53,12 @@ import org.onosproject.net.flow.FlowRuleService;
53 import org.onosproject.net.flow.TrafficSelector; 53 import org.onosproject.net.flow.TrafficSelector;
54 import org.onosproject.net.flow.TrafficTreatment; 54 import org.onosproject.net.flow.TrafficTreatment;
55 import org.onosproject.net.flow.criteria.Criterion; 55 import org.onosproject.net.flow.criteria.Criterion;
56 -import org.onosproject.net.flow.criteria.EthCriterion;
57 import org.onosproject.net.flow.criteria.IPCriterion; 56 import org.onosproject.net.flow.criteria.IPCriterion;
58 -import org.onosproject.net.flow.criteria.PortCriterion;
59 import org.onosproject.net.flow.instructions.ExtensionPropertyException; 57 import org.onosproject.net.flow.instructions.ExtensionPropertyException;
60 import org.onosproject.net.flow.instructions.ExtensionTreatment; 58 import org.onosproject.net.flow.instructions.ExtensionTreatment;
61 import org.onosproject.net.flow.instructions.Instruction; 59 import org.onosproject.net.flow.instructions.Instruction;
62 import org.onosproject.net.flow.instructions.Instructions; 60 import org.onosproject.net.flow.instructions.Instructions;
63 import org.onosproject.net.flow.instructions.L2ModificationInstruction; 61 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
64 -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
65 import org.onosproject.net.group.DefaultGroupBucket; 62 import org.onosproject.net.group.DefaultGroupBucket;
66 import org.onosproject.net.group.DefaultGroupDescription; 63 import org.onosproject.net.group.DefaultGroupDescription;
67 import org.onosproject.net.group.DefaultGroupKey; 64 import org.onosproject.net.group.DefaultGroupKey;
...@@ -71,8 +68,6 @@ import org.onosproject.net.group.GroupBuckets; ...@@ -71,8 +68,6 @@ import org.onosproject.net.group.GroupBuckets;
71 import org.onosproject.net.group.GroupDescription; 68 import org.onosproject.net.group.GroupDescription;
72 import org.onosproject.net.group.GroupKey; 69 import org.onosproject.net.group.GroupKey;
73 import org.onosproject.net.group.GroupService; 70 import org.onosproject.net.group.GroupService;
74 -import org.openstack4j.model.network.Network;
75 -import org.openstack4j.model.network.Subnet;
76 import org.slf4j.Logger; 71 import org.slf4j.Logger;
77 72
78 import java.util.ArrayList; 73 import java.util.ArrayList;
...@@ -83,11 +78,8 @@ import java.util.Set; ...@@ -83,11 +78,8 @@ import java.util.Set;
83 import java.util.stream.Collectors; 78 import java.util.stream.Collectors;
84 79
85 import static com.google.common.base.Preconditions.checkNotNull; 80 import static com.google.common.base.Preconditions.checkNotNull;
86 -import static org.onosproject.net.flow.criteria.Criterion.Type.IN_PORT;
87 import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST; 81 import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST;
88 -import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_SRC;
89 import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; 82 import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
90 -import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.ETH_DST;
91 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_PUSH; 83 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_PUSH;
92 import static org.slf4j.LoggerFactory.getLogger; 84 import static org.slf4j.LoggerFactory.getLogger;
93 85
...@@ -118,6 +110,7 @@ public class CordVtnRuleInstaller { ...@@ -118,6 +110,7 @@ public class CordVtnRuleInstaller {
118 110
119 private static final String PORT_NAME = "portName"; 111 private static final String PORT_NAME = "portName";
120 private static final String DATA_PLANE_INTF = "dataPlaneIntf"; 112 private static final String DATA_PLANE_INTF = "dataPlaneIntf";
113 + private static final String DATA_PLANE_IP = "dataPlaneIp";
121 private static final String S_TAG = "stag"; 114 private static final String S_TAG = "stag";
122 115
123 private final ApplicationId appId; 116 private final ApplicationId appId;
...@@ -181,93 +174,45 @@ public class CordVtnRuleInstaller { ...@@ -181,93 +174,45 @@ public class CordVtnRuleInstaller {
181 * Populates basic rules that connect a VM to the other VMs in the system. 174 * Populates basic rules that connect a VM to the other VMs in the system.
182 * 175 *
183 * @param host host 176 * @param host host
184 - * @param tunnelIp tunnel ip 177 + * @param service cord service
185 - * @param osNet openstack network 178 + * @param install true to install or false to remove
186 */ 179 */
187 - public void populateBasicConnectionRules(Host host, IpAddress tunnelIp, Network osNet) { 180 + public void populateBasicConnectionRules(Host host, CordService service, boolean install) {
188 checkNotNull(host); 181 checkNotNull(host);
189 - checkNotNull(osNet); 182 + checkNotNull(service);
190 183
191 DeviceId deviceId = host.location().deviceId(); 184 DeviceId deviceId = host.location().deviceId();
192 PortNumber inPort = host.location().port(); 185 PortNumber inPort = host.location().port();
193 MacAddress dstMac = host.mac(); 186 MacAddress dstMac = host.mac();
194 IpAddress hostIp = host.ipAddresses().stream().findFirst().get(); 187 IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
195 - long tunnelId = Long.parseLong(osNet.getProviderSegID());
196 188
197 - Subnet osSubnet = osNet.getNeutronSubnets().stream() 189 + long tunnelId = service.segmentationId();
198 - .findFirst() 190 + Ip4Prefix serviceIpRange = service.serviceIpRange().getIp4Prefix();
199 - .orElse(null);
200 191
201 - if (osSubnet == null) { 192 + populateLocalInPortRule(deviceId, inPort, hostIp, install);
202 - log.error("Failed to get subnet for {}", host.id()); 193 + populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, getTunnelIp(host), install);
203 - return; 194 + populateTunnelInRule(deviceId, inPort, dstMac, tunnelId, install);
204 - }
205 - Ip4Prefix cidr = Ip4Prefix.valueOf(osSubnet.getCidr());
206 195
207 - populateLocalInPortRule(deviceId, inPort, hostIp); 196 + if (install) {
208 - populateDirectAccessRule(cidr, cidr); 197 + populateDirectAccessRule(serviceIpRange, serviceIpRange, true);
209 - populateServiceIsolationRule(cidr); 198 + populateServiceIsolationRule(serviceIpRange, true);
210 - populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, tunnelIp); 199 + } else if (service.hosts().isEmpty()) {
211 - populateTunnelInRule(deviceId, inPort, dstMac, tunnelId); 200 + // removes network related rules only if there's no hosts left in this network
201 + populateDirectAccessRule(serviceIpRange, serviceIpRange, false);
202 + populateServiceIsolationRule(serviceIpRange, false);
212 } 203 }
213 -
214 - /**
215 - * Removes all rules related to a given service VM host.
216 - *
217 - * @param host host to be removed
218 - */
219 - public void removeBasicConnectionRules(Host host) {
220 - checkNotNull(host);
221 -
222 - DeviceId deviceId = host.location().deviceId();
223 - MacAddress mac = host.mac();
224 - PortNumber port = host.location().port();
225 - IpAddress ip = host.ipAddresses().stream().findFirst().orElse(null);
226 -
227 - for (FlowRule flowRule : flowRuleService.getFlowRulesById(appId)) {
228 - if (flowRule.deviceId().equals(deviceId)) {
229 - PortNumber inPort = getInPort(flowRule);
230 - if (inPort != null && inPort.equals(port)) {
231 - processFlowRule(false, flowRule);
232 - continue;
233 - }
234 -
235 - PortNumber output = getOutputFromTreatment(flowRule);
236 - if (output != null && output.equals(host.location().port())) {
237 - processFlowRule(false, flowRule);
238 - }
239 - }
240 -
241 - MacAddress dstMac = getDstMacFromTreatment(flowRule);
242 - if (dstMac != null && dstMac.equals(mac)) {
243 - processFlowRule(false, flowRule);
244 - continue;
245 - }
246 -
247 - dstMac = getDstMacFromSelector(flowRule);
248 - if (dstMac != null && dstMac.equals(mac)) {
249 - processFlowRule(false, flowRule);
250 - continue;
251 - }
252 -
253 - IpPrefix dstIp = getDstIpFromSelector(flowRule);
254 - if (dstIp != null && dstIp.equals(ip.toIpPrefix())) {
255 - processFlowRule(false, flowRule);
256 - }
257 - }
258 -
259 - // TODO uninstall same network access rule in access table if no vm exists in the network
260 } 204 }
261 205
262 /** 206 /**
263 - * Populates service dependency rules. 207 + * Creates provider service group and populates service dependency rules.
264 * 208 *
265 * @param tService tenant cord service 209 * @param tService tenant cord service
266 * @param pService provider cord service 210 * @param pService provider cord service
267 * @param isBidirectional true to enable bidirectional connection between two services 211 * @param isBidirectional true to enable bidirectional connection between two services
212 + * @param install true to install or false to remove
268 */ 213 */
269 public void populateServiceDependencyRules(CordService tService, CordService pService, 214 public void populateServiceDependencyRules(CordService tService, CordService pService,
270 - boolean isBidirectional) { 215 + boolean isBidirectional, boolean install) {
271 checkNotNull(tService); 216 checkNotNull(tService);
272 checkNotNull(pService); 217 checkNotNull(pService);
273 218
...@@ -290,66 +235,12 @@ public class CordVtnRuleInstaller { ...@@ -290,66 +235,12 @@ public class CordVtnRuleInstaller {
290 inPorts.put(deviceId, tServiceVms); 235 inPorts.put(deviceId, tServiceVms);
291 }); 236 });
292 237
293 - populateIndirectAccessRule(srcRange, serviceIp, outGroups); 238 + populateIndirectAccessRule(srcRange, serviceIp, outGroups, install);
294 - populateDirectAccessRule(srcRange, dstRange); 239 + populateDirectAccessRule(srcRange, dstRange, install);
295 if (isBidirectional) { 240 if (isBidirectional) {
296 - populateDirectAccessRule(dstRange, srcRange); 241 + populateDirectAccessRule(dstRange, srcRange, install);
297 - }
298 - populateInServiceRule(inPorts, outGroups);
299 - }
300 -
301 - /**
302 - * Removes service dependency rules.
303 - *
304 - * @param tService tenant cord service
305 - * @param pService provider cord service
306 - */
307 - public void removeServiceDependencyRules(CordService tService, CordService pService) {
308 - checkNotNull(tService);
309 - checkNotNull(pService);
310 -
311 - Ip4Prefix srcRange = tService.serviceIpRange().getIp4Prefix();
312 - Ip4Prefix dstRange = pService.serviceIpRange().getIp4Prefix();
313 - IpPrefix serviceIp = pService.serviceIp().toIpPrefix();
314 -
315 - Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
316 - GroupKey groupKey = new DefaultGroupKey(pService.id().id().getBytes());
317 -
318 - getVirtualSwitches().stream().forEach(deviceId -> {
319 - Group group = groupService.getGroup(deviceId, groupKey);
320 - if (group != null) {
321 - outGroups.put(deviceId, group.id());
322 } 242 }
323 - }); 243 + populateInServiceRule(inPorts, outGroups, install);
324 -
325 - for (FlowRule flowRule : flowRuleService.getFlowRulesById(appId)) {
326 - IpPrefix dstIp = getDstIpFromSelector(flowRule);
327 - IpPrefix srcIp = getSrcIpFromSelector(flowRule);
328 -
329 - if (dstIp != null && dstIp.equals(serviceIp)) {
330 - processFlowRule(false, flowRule);
331 - continue;
332 - }
333 -
334 - if (dstIp != null && srcIp != null) {
335 - if (dstIp.equals(dstRange) && srcIp.equals(srcRange)) {
336 - processFlowRule(false, flowRule);
337 - continue;
338 - }
339 -
340 - if (dstIp.equals(srcRange) && srcIp.equals(dstRange)) {
341 - processFlowRule(false, flowRule);
342 - continue;
343 - }
344 - }
345 -
346 - GroupId groupId = getGroupIdFromTreatment(flowRule);
347 - if (groupId != null && groupId.equals(outGroups.get(flowRule.deviceId()))) {
348 - processFlowRule(false, flowRule);
349 - }
350 - }
351 -
352 - // TODO remove the group if it is not in use
353 } 244 }
354 245
355 /** 246 /**
...@@ -357,7 +248,7 @@ public class CordVtnRuleInstaller { ...@@ -357,7 +248,7 @@ public class CordVtnRuleInstaller {
357 * 248 *
358 * @param service cord service 249 * @param service cord service
359 */ 250 */
360 - public void updateServiceGroup(CordService service) { 251 + public void updateProviderServiceGroup(CordService service) {
361 checkNotNull(service); 252 checkNotNull(service);
362 253
363 GroupKey groupKey = getGroupKey(service.id()); 254 GroupKey groupKey = getGroupKey(service.id());
...@@ -400,6 +291,30 @@ public class CordVtnRuleInstaller { ...@@ -400,6 +291,30 @@ public class CordVtnRuleInstaller {
400 } 291 }
401 292
402 /** 293 /**
294 + * Updates tenant service indirect access rules when VM is created or removed.
295 + *
296 + * @param host removed vm
297 + * @param service tenant service
298 + */
299 + public void updateTenantServiceVm(Host host, CordService service) {
300 + checkNotNull(host);
301 + checkNotNull(service);
302 +
303 + DeviceId deviceId = host.location().deviceId();
304 + PortNumber inPort = host.location().port();
305 +
306 + service.providerServices().stream().forEach(pServiceId -> {
307 + Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap();
308 + Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
309 +
310 + inPorts.put(deviceId, Sets.newHashSet(inPort));
311 + outGroups.put(deviceId, getGroupId(pServiceId, deviceId));
312 +
313 + populateInServiceRule(inPorts, outGroups, false);
314 + });
315 + }
316 +
317 + /**
403 * Populates flow rules for management network access. 318 * Populates flow rules for management network access.
404 * 319 *
405 * @param host host which has management network interface 320 * @param host host which has management network interface
...@@ -499,17 +414,6 @@ public class CordVtnRuleInstaller { ...@@ -499,17 +414,6 @@ public class CordVtnRuleInstaller {
499 } 414 }
500 415
501 /** 416 /**
502 - * Removes management network access rules.
503 - *
504 - * @param host host to be removed
505 - * @param mService service for management network
506 - */
507 - public void removeManagementNetworkRules(Host host, CordService mService) {
508 - checkNotNull(mService);
509 - // TODO remove management network specific rules
510 - }
511 -
512 - /**
513 * Populates rules for vSG VM. 417 * Populates rules for vSG VM.
514 * 418 *
515 * @param vSgHost vSG host 419 * @param vSgHost vSG host
...@@ -897,8 +801,10 @@ public class CordVtnRuleInstaller { ...@@ -897,8 +801,10 @@ public class CordVtnRuleInstaller {
897 * @param deviceId device id to install the rules 801 * @param deviceId device id to install the rules
898 * @param inPort in port 802 * @param inPort in port
899 * @param srcIp source ip 803 * @param srcIp source ip
804 + * @param install true to install or false to remove
900 */ 805 */
901 - private void populateLocalInPortRule(DeviceId deviceId, PortNumber inPort, IpAddress srcIp) { 806 + private void populateLocalInPortRule(DeviceId deviceId, PortNumber inPort, IpAddress srcIp,
807 + boolean install) {
902 TrafficSelector selector = DefaultTrafficSelector.builder() 808 TrafficSelector selector = DefaultTrafficSelector.builder()
903 .matchInPort(inPort) 809 .matchInPort(inPort)
904 .matchEthType(Ethernet.TYPE_IPV4) 810 .matchEthType(Ethernet.TYPE_IPV4)
...@@ -920,7 +826,7 @@ public class CordVtnRuleInstaller { ...@@ -920,7 +826,7 @@ public class CordVtnRuleInstaller {
920 .makePermanent() 826 .makePermanent()
921 .build(); 827 .build();
922 828
923 - processFlowRule(true, flowRule); 829 + processFlowRule(install, flowRule);
924 830
925 selector = DefaultTrafficSelector.builder() 831 selector = DefaultTrafficSelector.builder()
926 .matchInPort(inPort) 832 .matchInPort(inPort)
...@@ -940,7 +846,7 @@ public class CordVtnRuleInstaller { ...@@ -940,7 +846,7 @@ public class CordVtnRuleInstaller {
940 .makePermanent() 846 .makePermanent()
941 .build(); 847 .build();
942 848
943 - processFlowRule(true, flowRule); 849 + processFlowRule(install, flowRule);
944 } 850 }
945 851
946 /** 852 /**
...@@ -949,8 +855,9 @@ public class CordVtnRuleInstaller { ...@@ -949,8 +855,9 @@ public class CordVtnRuleInstaller {
949 * 855 *
950 * @param srcRange source ip range 856 * @param srcRange source ip range
951 * @param dstRange destination ip range 857 * @param dstRange destination ip range
858 + * @param install true to install or false to remove
952 */ 859 */
953 - private void populateDirectAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange) { 860 + private void populateDirectAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange, boolean install) {
954 TrafficSelector selector = DefaultTrafficSelector.builder() 861 TrafficSelector selector = DefaultTrafficSelector.builder()
955 .matchEthType(Ethernet.TYPE_IPV4) 862 .matchEthType(Ethernet.TYPE_IPV4)
956 .matchIPSrc(srcRange) 863 .matchIPSrc(srcRange)
...@@ -973,7 +880,7 @@ public class CordVtnRuleInstaller { ...@@ -973,7 +880,7 @@ public class CordVtnRuleInstaller {
973 .makePermanent() 880 .makePermanent()
974 .build(); 881 .build();
975 882
976 - processFlowRule(true, flowRuleDirect); 883 + processFlowRule(install, flowRuleDirect);
977 }); 884 });
978 } 885 }
979 886
...@@ -982,8 +889,9 @@ public class CordVtnRuleInstaller { ...@@ -982,8 +889,9 @@ public class CordVtnRuleInstaller {
982 * destination to a different service network in ACCESS_TYPE table. 889 * destination to a different service network in ACCESS_TYPE table.
983 * 890 *
984 * @param dstRange destination ip range 891 * @param dstRange destination ip range
892 + * @param install true to install or false to remove
985 */ 893 */
986 - private void populateServiceIsolationRule(Ip4Prefix dstRange) { 894 + private void populateServiceIsolationRule(Ip4Prefix dstRange, boolean install) {
987 TrafficSelector selector = DefaultTrafficSelector.builder() 895 TrafficSelector selector = DefaultTrafficSelector.builder()
988 .matchEthType(Ethernet.TYPE_IPV4) 896 .matchEthType(Ethernet.TYPE_IPV4)
989 .matchIPDst(dstRange) 897 .matchIPDst(dstRange)
...@@ -1004,7 +912,7 @@ public class CordVtnRuleInstaller { ...@@ -1004,7 +912,7 @@ public class CordVtnRuleInstaller {
1004 .makePermanent() 912 .makePermanent()
1005 .build(); 913 .build();
1006 914
1007 - processFlowRule(true, flowRuleDirect); 915 + processFlowRule(install, flowRuleDirect);
1008 }); 916 });
1009 } 917 }
1010 918
...@@ -1015,9 +923,10 @@ public class CordVtnRuleInstaller { ...@@ -1015,9 +923,10 @@ public class CordVtnRuleInstaller {
1015 * @param srcRange source range 923 * @param srcRange source range
1016 * @param serviceIp service ip 924 * @param serviceIp service ip
1017 * @param outGroups list of output group 925 * @param outGroups list of output group
926 + * @param install true to install or false to remove
1018 */ 927 */
1019 private void populateIndirectAccessRule(Ip4Prefix srcRange, Ip4Address serviceIp, 928 private void populateIndirectAccessRule(Ip4Prefix srcRange, Ip4Address serviceIp,
1020 - Map<DeviceId, GroupId> outGroups) { 929 + Map<DeviceId, GroupId> outGroups, boolean install) {
1021 TrafficSelector selector = DefaultTrafficSelector.builder() 930 TrafficSelector selector = DefaultTrafficSelector.builder()
1022 .matchEthType(Ethernet.TYPE_IPV4) 931 .matchEthType(Ethernet.TYPE_IPV4)
1023 .matchIPSrc(srcRange) 932 .matchIPSrc(srcRange)
...@@ -1039,7 +948,7 @@ public class CordVtnRuleInstaller { ...@@ -1039,7 +948,7 @@ public class CordVtnRuleInstaller {
1039 .makePermanent() 948 .makePermanent()
1040 .build(); 949 .build();
1041 950
1042 - processFlowRule(true, flowRule); 951 + processFlowRule(install, flowRule);
1043 } 952 }
1044 } 953 }
1045 954
...@@ -1048,8 +957,10 @@ public class CordVtnRuleInstaller { ...@@ -1048,8 +957,10 @@ public class CordVtnRuleInstaller {
1048 * 957 *
1049 * @param inPorts list of inports related to the service for each device 958 * @param inPorts list of inports related to the service for each device
1050 * @param outGroups set of output groups 959 * @param outGroups set of output groups
960 + * @param install true to install or false to remove
1051 */ 961 */
1052 - private void populateInServiceRule(Map<DeviceId, Set<PortNumber>> inPorts, Map<DeviceId, GroupId> outGroups) { 962 + private void populateInServiceRule(Map<DeviceId, Set<PortNumber>> inPorts,
963 + Map<DeviceId, GroupId> outGroups, boolean install) {
1053 checkNotNull(inPorts); 964 checkNotNull(inPorts);
1054 checkNotNull(outGroups); 965 checkNotNull(outGroups);
1055 966
...@@ -1081,7 +992,7 @@ public class CordVtnRuleInstaller { ...@@ -1081,7 +992,7 @@ public class CordVtnRuleInstaller {
1081 .makePermanent() 992 .makePermanent()
1082 .build(); 993 .build();
1083 994
1084 - processFlowRule(true, flowRule); 995 + processFlowRule(install, flowRule);
1085 }); 996 });
1086 } 997 }
1087 } 998 }
...@@ -1095,9 +1006,11 @@ public class CordVtnRuleInstaller { ...@@ -1095,9 +1006,11 @@ public class CordVtnRuleInstaller {
1095 * @param dstIp destination ip 1006 * @param dstIp destination ip
1096 * @param tunnelId tunnel id 1007 * @param tunnelId tunnel id
1097 * @param tunnelIp tunnel remote ip 1008 * @param tunnelIp tunnel remote ip
1009 + * @param install true to install or false to remove
1098 */ 1010 */
1099 private void populateDstIpRule(DeviceId deviceId, PortNumber inPort, MacAddress dstMac, 1011 private void populateDstIpRule(DeviceId deviceId, PortNumber inPort, MacAddress dstMac,
1100 - IpAddress dstIp, long tunnelId, IpAddress tunnelIp) { 1012 + IpAddress dstIp, long tunnelId, IpAddress tunnelIp,
1013 + boolean install) {
1101 TrafficSelector selector = DefaultTrafficSelector.builder() 1014 TrafficSelector selector = DefaultTrafficSelector.builder()
1102 .matchEthType(Ethernet.TYPE_IPV4) 1015 .matchEthType(Ethernet.TYPE_IPV4)
1103 .matchIPDst(dstIp.toIpPrefix()) 1016 .matchIPDst(dstIp.toIpPrefix())
...@@ -1118,7 +1031,7 @@ public class CordVtnRuleInstaller { ...@@ -1118,7 +1031,7 @@ public class CordVtnRuleInstaller {
1118 .makePermanent() 1031 .makePermanent()
1119 .build(); 1032 .build();
1120 1033
1121 - processFlowRule(true, flowRule); 1034 + processFlowRule(install, flowRule);
1122 1035
1123 for (DeviceId vSwitchId : getVirtualSwitches()) { 1036 for (DeviceId vSwitchId : getVirtualSwitches()) {
1124 if (vSwitchId.equals(deviceId)) { 1037 if (vSwitchId.equals(deviceId)) {
...@@ -1147,7 +1060,7 @@ public class CordVtnRuleInstaller { ...@@ -1147,7 +1060,7 @@ public class CordVtnRuleInstaller {
1147 .makePermanent() 1060 .makePermanent()
1148 .build(); 1061 .build();
1149 1062
1150 - processFlowRule(true, flowRule); 1063 + processFlowRule(install, flowRule);
1151 } 1064 }
1152 } 1065 }
1153 1066
...@@ -1158,8 +1071,10 @@ public class CordVtnRuleInstaller { ...@@ -1158,8 +1071,10 @@ public class CordVtnRuleInstaller {
1158 * @param inPort in port 1071 * @param inPort in port
1159 * @param mac mac address 1072 * @param mac mac address
1160 * @param tunnelId tunnel id 1073 * @param tunnelId tunnel id
1074 + * @param install true to install or false to remove
1161 */ 1075 */
1162 - private void populateTunnelInRule(DeviceId deviceId, PortNumber inPort, MacAddress mac, long tunnelId) { 1076 + private void populateTunnelInRule(DeviceId deviceId, PortNumber inPort, MacAddress mac,
1077 + long tunnelId, boolean install) {
1163 TrafficSelector selector = DefaultTrafficSelector.builder() 1078 TrafficSelector selector = DefaultTrafficSelector.builder()
1164 .matchTunnelId(tunnelId) 1079 .matchTunnelId(tunnelId)
1165 .matchEthDst(mac) 1080 .matchEthDst(mac)
...@@ -1179,7 +1094,7 @@ public class CordVtnRuleInstaller { ...@@ -1179,7 +1094,7 @@ public class CordVtnRuleInstaller {
1179 .makePermanent() 1094 .makePermanent()
1180 .build(); 1095 .build();
1181 1096
1182 - processFlowRule(true, flowRule); 1097 + processFlowRule(install, flowRule);
1183 } 1098 }
1184 1099
1185 /** 1100 /**
...@@ -1252,58 +1167,16 @@ public class CordVtnRuleInstaller { ...@@ -1252,58 +1167,16 @@ public class CordVtnRuleInstaller {
1252 } 1167 }
1253 1168
1254 /** 1169 /**
1255 - * Returns the inport from a given flow rule if the rule contains the match of it. 1170 + * Returns IP address for tunneling for a given host.
1256 * 1171 *
1257 - * @param flowRule flow rule 1172 + * @param host host
1258 - * @return port number, or null if the rule doesn't have inport match 1173 + * @return ip address, or null
1259 - */
1260 - private PortNumber getInPort(FlowRule flowRule) {
1261 - Criterion criterion = flowRule.selector().getCriterion(IN_PORT);
1262 - if (criterion != null && criterion instanceof PortCriterion) {
1263 - PortCriterion port = (PortCriterion) criterion;
1264 - return port.port();
1265 - } else {
1266 - return null;
1267 - }
1268 - }
1269 -
1270 - /**
1271 - * Returns the destination mac address from a given flow rule if the rule
1272 - * contains the instruction of it.
1273 - *
1274 - * @param flowRule flow rule
1275 - * @return mac address, or null if the rule doesn't have destination mac instruction
1276 */ 1174 */
1277 - private MacAddress getDstMacFromTreatment(FlowRule flowRule) { 1175 + private IpAddress getTunnelIp(Host host) {
1278 - Instruction instruction = flowRule.treatment().allInstructions().stream() 1176 + String ip = host.annotations().value(DATA_PLANE_IP);
1279 - .filter(inst -> inst instanceof ModEtherInstruction && 1177 + return ip == null ? null : IpAddress.valueOf(ip);
1280 - ((ModEtherInstruction) inst).subtype().equals(ETH_DST))
1281 - .findFirst()
1282 - .orElse(null);
1283 -
1284 - if (instruction == null) {
1285 - return null;
1286 } 1178 }
1287 1179
1288 - return ((ModEtherInstruction) instruction).mac();
1289 - }
1290 -
1291 - /**
1292 - * Returns the destination mac address from a given flow rule if the rule
1293 - * contains the match of it.
1294 - *
1295 - * @param flowRule flow rule
1296 - * @return mac address, or null if the rule doesn't have destination mac match
1297 - */
1298 - private MacAddress getDstMacFromSelector(FlowRule flowRule) {
1299 - Criterion criterion = flowRule.selector().getCriterion(Criterion.Type.ETH_DST);
1300 - if (criterion != null && criterion instanceof EthCriterion) {
1301 - EthCriterion eth = (EthCriterion) criterion;
1302 - return eth.mac();
1303 - } else {
1304 - return null;
1305 - }
1306 - }
1307 1180
1308 /** 1181 /**
1309 * Returns the destination IP from a given flow rule if the rule contains 1182 * Returns the destination IP from a given flow rule if the rule contains
...@@ -1323,43 +1196,6 @@ public class CordVtnRuleInstaller { ...@@ -1323,43 +1196,6 @@ public class CordVtnRuleInstaller {
1323 } 1196 }
1324 1197
1325 /** 1198 /**
1326 - * Returns the source IP from a given flow rule if the rule contains
1327 - * the match of it.
1328 - *
1329 - * @param flowRule flow rule
1330 - * @return ip prefix, or null if the rule doesn't have ip match
1331 - */
1332 - private IpPrefix getSrcIpFromSelector(FlowRule flowRule) {
1333 - Criterion criterion = flowRule.selector().getCriterion(IPV4_SRC);
1334 - if (criterion != null && criterion instanceof IPCriterion) {
1335 - IPCriterion ip = (IPCriterion) criterion;
1336 - return ip.ip();
1337 - } else {
1338 - return null;
1339 - }
1340 - }
1341 -
1342 - /**
1343 - * Returns the group ID from a given flow rule if the rule contains the
1344 - * treatment of it.
1345 - *
1346 - * @param flowRule flow rule
1347 - * @return group id, or null if the rule doesn't have group instruction
1348 - */
1349 - private GroupId getGroupIdFromTreatment(FlowRule flowRule) {
1350 - Instruction instruction = flowRule.treatment().allInstructions().stream()
1351 - .filter(inst -> inst instanceof Instructions.GroupInstruction)
1352 - .findFirst()
1353 - .orElse(null);
1354 -
1355 - if (instruction == null) {
1356 - return null;
1357 - }
1358 -
1359 - return ((Instructions.GroupInstruction) instruction).groupId();
1360 - }
1361 -
1362 - /**
1363 * Returns the output port number from a given flow rule. 1199 * Returns the output port number from a given flow rule.
1364 * 1200 *
1365 * @param flowRule flow rule 1201 * @param flowRule flow rule
...@@ -1413,7 +1249,8 @@ public class CordVtnRuleInstaller { ...@@ -1413,7 +1249,8 @@ public class CordVtnRuleInstaller {
1413 return groupId; 1249 return groupId;
1414 } 1250 }
1415 1251
1416 - GroupBuckets buckets = getServiceGroupBuckets(deviceId, service.segmentationId(), service.hosts()); 1252 + GroupBuckets buckets = getServiceGroupBuckets(
1253 + deviceId, service.segmentationId(), service.hosts());
1417 GroupDescription groupDescription = new DefaultGroupDescription( 1254 GroupDescription groupDescription = new DefaultGroupDescription(
1418 deviceId, 1255 deviceId,
1419 GroupDescription.Type.SELECT, 1256 GroupDescription.Type.SELECT,
...@@ -1435,7 +1272,8 @@ public class CordVtnRuleInstaller { ...@@ -1435,7 +1272,8 @@ public class CordVtnRuleInstaller {
1435 * @param hosts list of host 1272 * @param hosts list of host
1436 * @return group buckets 1273 * @return group buckets
1437 */ 1274 */
1438 - private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId, Map<Host, IpAddress> hosts) { 1275 + private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId,
1276 + Map<Host, IpAddress> hosts) {
1439 List<GroupBucket> buckets = Lists.newArrayList(); 1277 List<GroupBucket> buckets = Lists.newArrayList();
1440 1278
1441 for (Map.Entry<Host, IpAddress> entry : hosts.entrySet()) { 1279 for (Map.Entry<Host, IpAddress> entry : hosts.entrySet()) {
......