"neutronvpn:createL3VPN" fails to create L3VPN for IPv6 use case.
[netvirt.git] / neutronvpn / impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnUtils.java
index 21c1df342bfeb1e9f00879ed7e86ffaee88a24c2..9ccdd3d85b13e009ed979118ed857016f1fb37e9 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netvirt.neutronvpn;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.base.Function;
@@ -32,6 +33,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.concurrent.locks.ReentrantLock;
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -53,13 +55,8 @@ import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
+import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
@@ -109,6 +106,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortIdSubportData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
@@ -783,9 +787,9 @@ public class NeutronvpnUtils {
             Subnet subnet = getNeutronSubnet(subnetId);
             if (subnet != null) {
                 Class<? extends IpVersionBase> ipVersion =
-                        NeutronSecurityRuleConstants.IP_VERSION_MAP.get(subnet.getIpVersion());
+                        NeutronSecurityGroupConstants.IP_VERSION_MAP.get(subnet.getIpVersion());
                 Class<? extends Dhcpv6Base> raMode = subnet.getIpv6RaMode() == null ? null
-                        : NeutronSecurityRuleConstants.RA_MODE_MAP.get(subnet.getIpv6RaMode());
+                        : NeutronSecurityGroupConstants.RA_MODE_MAP.get(subnet.getIpv6RaMode());
                 SubnetInfo subnetInfo = new SubnetInfoBuilder().withKey(new SubnetInfoKey(subnetId))
                         .setIpVersion(ipVersion).setIpPrefix(new IpPrefixOrAddress(subnet.getCidr()))
                         .setIpv6RaMode(raMode).setGatewayIp(subnet.getGatewayIp()).build();
@@ -885,8 +889,8 @@ public class NeutronvpnUtils {
             LOG.trace("Neutron port with fixedIp: {}, vpn {}, interface {}, mac {}, isSubnetIp {} added to "
                 + "VpnPortipToPort DS", fixedIp, vpnName, portName, macAddress, isSubnetIp);
         } catch (Exception e) {
-            LOG.error("Failure while creating VPNPortFixedIpToPort map for vpn {} - fixedIP {}", vpnName, fixedIp,
-                    e);
+            LOG.error("Failure while creating VPNPortFixedIpToPort map for vpn {} - fixedIP {} for port {} with "
+                    + "macAddress {}", vpnName, fixedIp, portName, macAddress, e);
         }
     }
 
@@ -1153,19 +1157,21 @@ public class NeutronvpnUtils {
         return Optional.absent();
     }
 
-    protected void releaseRDId(String poolName, String idKey) {
+    protected Integer releaseId(String poolName, String idKey) {
         ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
         try {
-            RpcResult<ReleaseIdOutput> rpcResult = idManager.releaseId(idInput).get();
-            if (!rpcResult.isSuccessful()) {
-                LOG.error("RPC Call to Get Unique Id returned with errors for poolname {} and ID Key {}: {}",
-                        poolName, idKey, rpcResult.getErrors());
+            Future<RpcResult<ReleaseIdOutput>> result = idManager.releaseId(idInput);
+            if (result == null || result.get() == null || !result.get().isSuccessful()) {
+                LOG.error("releaseId: RPC Call to release Id from pool {} with key {} returned with Errors {}",
+                        poolName, idKey, (result != null && result.get() != null) ? result.get().getErrors() :
+                                "RpcResult is null");
             } else {
-                LOG.info("ID {} for RD released successfully", idKey);
+                return result.get().getResult().getIdValues().get(0).intValue();
             }
         } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Exception when trying to release ID for poolname {} and ID Key {}", poolName, idKey, e);
+            LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
         }
+        return NeutronConstants.INVALID_ID;
     }
 
     protected static IpAddress getIpv6LinkLocalAddressFromMac(MacAddress mac) {
@@ -1216,10 +1222,7 @@ public class NeutronvpnUtils {
         Optional<VpnInstances> vpnInstancesOptional = read(LogicalDatastoreType.CONFIGURATION, path);
         if (vpnInstancesOptional.isPresent() && vpnInstancesOptional.get().getVpnInstance() != null) {
             for (VpnInstance vpnInstance : vpnInstancesOptional.get().getVpnInstance()) {
-                if (vpnInstance.getIpv4Family() == null) {
-                    continue;
-                }
-                List<String> rds = vpnInstance.getIpv4Family().getRouteDistinguisher();
+                List<String> rds = vpnInstance.getRouteDistinguisher();
                 if (rds != null) {
                     existingRDs.addAll(rds);
                 }
@@ -1458,13 +1461,13 @@ public class NeutronvpnUtils {
 
     public void updateVpnInstanceWithIpFamily(String vpnName, IpVersionChoice ipVersion, boolean add) {
         jobCoordinator.enqueueJob("VPN-" + vpnName, () -> {
-            VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpDataEntryFromVpnId(vpnName);
-            if (vpnInstanceOpDataEntry == null) {
+            VpnInstance vpnInstance = getVpnInstance(dataBroker, new Uuid(vpnName));
+            if (vpnInstance == null) {
                 return Collections.emptyList();
             }
-            if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
+            if (vpnInstance.isL2vpn()) {
                 LOG.debug("updateVpnInstanceWithIpFamily: Update VpnInstance {} with ipFamily {}."
-                        + "VpnInstanceOpDataEntry is L2 instance. Do nothing.", vpnName, ipVersion);
+                        + "VpnInstance is L2 instance. Do nothing.", vpnName, ipVersion);
                 return Collections.emptyList();
             }
             if (ipVersion == IpVersionChoice.UNDEFINED) {
@@ -1472,23 +1475,32 @@ public class NeutronvpnUtils {
                         + "is not allowed. Do nothing", vpnName);
                 return Collections.emptyList();
             }
-            VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder(vpnInstanceOpDataEntry);
+            VpnInstanceBuilder builder = new VpnInstanceBuilder(vpnInstance);
             boolean ipConfigured = add;
-            if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4AND6)) {
-                builder.setIpv4Configured(ipConfigured);
-                builder.setIpv6Configured(ipConfigured);
-            } else if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4)) {
-                builder.setIpv4Configured(ipConfigured);
-            } else if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV6)) {
-                builder.setIpv6Configured(ipConfigured);
+
+            int originalValue = vpnInstance.getIpAddressFamilyConfigured().getIntValue();
+            int updatedValue = ipVersion.choice;
+
+            if (originalValue != updatedValue) {
+                if (ipConfigured) {
+                    originalValue = originalValue == 0 ? updatedValue : updatedValue + originalValue;
+                } else {
+                    originalValue = 10 - updatedValue;
+                }
+            } else if (!ipConfigured) {
+                originalValue = 0;
             }
+
+            builder.setIpAddressFamilyConfigured(VpnInstance.IpAddressFamilyConfigured.forValue(originalValue));
+
+            InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
+                    .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+            LOG.info("updateVpnInstanceWithIpFamily: Successfully {} IP family {} to Vpn {}",
+                    add == true ? "added" : "removed", ipVersion, vpnName);
             return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-                    OPERATIONAL, tx -> {
-                    tx.merge(getVpnOpDataIdentifier(vpnInstanceOpDataEntry.getVrfId()), builder.build(), false);
-                    LOG.info("updateVpnInstanceWithIpFamily: Successfully {} {} to Vpn {}",
-                            add == true ? "added" : "removed", ipVersion, vpnName);
-                }));
+                    CONFIGURATION, tx -> tx.merge(vpnIdentifier, builder.build(), false)));
         });
+        return;
     }
 
     /**