BUG 5783: Ping test is FAILED from VM to Invisible IP which
[netvirt.git] / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / vpnservice / VpnUtil.java
index 29ad638fa14ff79a3f8be1611ab740516db6ae54..f9a541fc075e3f0faa0a09bc78c7ecfffea072c1 100644 (file)
@@ -9,11 +9,13 @@
 package org.opendaylight.vpnservice;
 
 import java.math.BigInteger;
+import java.net.InetAddress;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.List;
 
 import com.google.common.base.Optional;
+import com.google.common.primitives.Ints;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
@@ -24,6 +26,9 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
+import org.opendaylight.vpnservice.mdsalutil.packet.ARP;
+import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
 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.VpnInstances;
@@ -34,9 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceToVpnId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacenciesBuilder;
@@ -50,6 +53,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instanc
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.Vpn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.VpnKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.Extraroute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdPools;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPool;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolKey;
@@ -59,6 +74,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.IfIndexesInterfaceMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.L3nexthop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.VpnNexthops;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.VpnNexthopsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronPortData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data.PortFixedipToPortName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data.PortFixedipToPortNameKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanTagNameMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagNameKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -81,9 +108,9 @@ public class VpnUtil {
     }
 
     static VpnInterface getVpnInterface(String intfName, String vpnName, Adjacencies aug) {
-        return new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(intfName)).setVpnInstanceName(
-            vpnName)
-                .addAugmentation(Adjacencies.class, aug).build();
+        return new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(intfName)).setVpnInstanceName(vpnName)
+                .addAugmentation(Adjacencies.class, aug)
+                .build();
     }
 
     static InstanceIdentifier<Prefixes> getPrefixToInterfaceIdentifier(long vpnId, String ipPrefix) {
@@ -97,6 +124,16 @@ public class VpnUtil {
             vpnInterfaceName).setIpAddress(ipPrefix).build();
     }
 
+    static InstanceIdentifier<Extraroute> getVpnToExtrarouteIdentifier(String vrfId, String ipPrefix) {
+        return InstanceIdentifier.builder(VpnToExtraroute.class)
+                .child(Vpn.class, new VpnKey(vrfId)).child(Extraroute.class,
+                 new ExtrarouteKey(ipPrefix)).build();
+    }
+
+    static Extraroute getVpnToExtraroute(String ipPrefix, String nextHop) {
+        return new ExtrarouteBuilder().setPrefix(ipPrefix).setNexthopIp(nextHop).build();
+    }
+
     static Adjacencies
     getVpnInterfaceAugmentation(List<Adjacency> nextHops) {
         return new AdjacenciesBuilder().setAdjacency(nextHops).build();
@@ -200,6 +237,19 @@ public class VpnUtil {
         return rd;
     }
 
+    static String getVpnRdFromVpnInstanceConfig(DataBroker broker, String vpnName) {
+        InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
+                .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+        Optional<VpnInstance> vpnInstance = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
+        String rd = null;
+        if(vpnInstance.isPresent()) {
+            VpnInstance instance = vpnInstance.get();
+            VpnAfConfig config = instance.getIpv4Family();
+            rd = config.getRouteDistinguisher();
+        }
+        return rd;
+    }
+
     static org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
            getVpnInstanceToVpnId(String vpnName, long vpnId, String rd) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceBuilder()
@@ -219,10 +269,23 @@ public class VpnUtil {
             .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)).build();
     }
 
-    static VpnInstanceOpDataEntry getVpnInstanceOpData(String rd, long vpnId) {
+    static VpnInstanceOpDataEntry getVpnInstanceOpDataBuilder(String rd, long vpnId) {
         return new VpnInstanceOpDataEntryBuilder().setVrfId(rd).setVpnId(vpnId).build();
     }
 
+    static VpnInstanceOpDataEntry updateIntfCntInVpnInstOpData(Long count, String vrfId) {
+        return new VpnInstanceOpDataEntryBuilder().setVpnInterfaceCount(count).setVrfId(vrfId).build();
+    }
+
+    static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
+        InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
+        Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(broker, LogicalDatastoreType.OPERATIONAL, id);
+        if(vpnInstanceOpData.isPresent()) {
+            return vpnInstanceOpData.get();
+        }
+        return null;
+    }
+
     static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
         Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
@@ -283,6 +346,8 @@ public class VpnUtil {
             result = tx.read(datastoreType, path).get();
         } catch (Exception e) {
             throw new RuntimeException(e);
+        } finally {
+            tx.close();
         }
 
         return result;
@@ -335,4 +400,139 @@ public class VpnUtil {
         }
     }
 
-}
+    public static long getRemoteBCGroup(long elanTag) {
+        return VpnConstants.ELAN_GID_MIN + ((elanTag % VpnConstants.ELAN_GID_MIN) *2);
+    }
+
+    // interface-index-tag operational container
+    public static IfIndexInterface getInterfaceInfoByInterfaceTag(DataBroker broker, long interfaceTag) {
+        InstanceIdentifier<IfIndexInterface> interfaceId = getInterfaceInfoEntriesOperationalDataPath(interfaceTag);
+        Optional<IfIndexInterface> existingInterfaceInfo = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, interfaceId);
+        if(existingInterfaceInfo.isPresent()) {
+            return existingInterfaceInfo.get();
+        }
+        return null;
+    }
+
+    private static InstanceIdentifier<IfIndexInterface> getInterfaceInfoEntriesOperationalDataPath(long interfaceTag) {
+        return InstanceIdentifier.builder(IfIndexesInterfaceMap.class).child(IfIndexInterface.class,
+                new IfIndexInterfaceKey((int) interfaceTag)).build();
+    }
+
+    public static String getNeutronPortNamefromPortFixedIp(DataBroker broker, String fixedIp) {
+        InstanceIdentifier id = buildFixedIpToPortNameIdentifier(fixedIp);
+        Optional<PortFixedipToPortName> portFixedipToPortNameData = read(broker, LogicalDatastoreType.CONFIGURATION,
+                id);
+        if (portFixedipToPortNameData.isPresent()) {
+            return portFixedipToPortNameData.get().getPortName();
+        }
+        return null;
+    }
+
+    private static InstanceIdentifier<PortFixedipToPortName> buildFixedIpToPortNameIdentifier(String fixedIp) {
+        InstanceIdentifier<PortFixedipToPortName> id = InstanceIdentifier.builder(NeutronPortData.class).child
+                (PortFixedipToPortName.class, new PortFixedipToPortNameKey(fixedIp)).build();
+        return id;
+    }
+
+    public static ElanTagName getElanInfoByElanTag(DataBroker broker,long elanTag) {
+        InstanceIdentifier<ElanTagName> elanId = getElanInfoEntriesOperationalDataPath(elanTag);
+        Optional<ElanTagName> existingElanInfo = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, elanId);
+        if(existingElanInfo.isPresent()) {
+            return existingElanInfo.get();
+        }
+        return null;
+    }
+
+    private static InstanceIdentifier<ElanTagName> getElanInfoEntriesOperationalDataPath(long elanTag) {
+        return InstanceIdentifier.builder(ElanTagNameMap.class).child(ElanTagName.class,
+                new ElanTagNameKey(elanTag)).build();
+    }
+
+
+    public static boolean isIpInSubnet(int ipAddress, String subnetCidr) {
+        String[] subSplit = subnetCidr.split("/");
+        if (subSplit.length < 2) {
+            return false;
+        }
+
+        String subnetStr = subSplit[0];
+        int subnet = 0;
+        try {
+            InetAddress subnetAddress = InetAddress.getByName(subnetStr);
+            subnet = Ints.fromByteArray(subnetAddress.getAddress());
+        } catch (Exception ex) {
+            LOG.error("Passed in Subnet IP string not convertible to InetAdddress " + subnetStr);
+            return false;
+        }
+        int prefixLength = Integer.valueOf(subSplit[1]);
+        int mask = -1 << (32 - prefixLength);
+        if ((subnet & mask) == (ipAddress & mask)) {
+            return true;
+        }
+        return false;
+    }
+
+    public static void removePrefixToInterfaceForVpnId(DataBroker broker, long vpnId) {
+        try {
+            // Clean up PrefixToInterface Operational DS
+            delete(broker, LogicalDatastoreType.OPERATIONAL,
+                    InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)).build(),
+                    DEFAULT_CALLBACK);
+        } catch (Exception e) {
+            LOG.error("Exception during cleanup of PrefixToInterface for VPN ID {}", vpnId, e);
+        }
+    }
+
+    public static void removeVpnExtraRouteForVpn(DataBroker broker, String vpnName) {
+        try {
+            // Clean up VPNExtraRoutes Operational DS
+            delete(broker, LogicalDatastoreType.OPERATIONAL,
+                    InstanceIdentifier.builder(VpnToExtraroute.class).child(Vpn.class, new VpnKey(vpnName)).build(),
+                    DEFAULT_CALLBACK);
+        } catch (Exception e) {
+            LOG.error("Exception during cleanup of VPNToExtraRoute for VPN {}", vpnName, e);
+        }
+    }
+
+    public static void removeVpnOpInstance(DataBroker broker, String vpnName) {
+        try {
+            // Clean up VPNInstanceOpDataEntry
+            delete(broker, LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName),
+                    DEFAULT_CALLBACK);
+        } catch (Exception e) {
+            LOG.error("Exception during cleanup of VPNInstanceOpDataEntry for VPN {}", vpnName, e);
+        }
+    }
+
+    public static void removeVpnInstanceToVpnId(DataBroker broker, String vpnName) {
+        try {
+            delete(broker, LogicalDatastoreType.CONFIGURATION, getVpnInstanceToVpnIdIdentifier(vpnName),
+                    DEFAULT_CALLBACK);
+        } catch (Exception e) {
+            LOG.error("Exception during clean up of VpnInstanceToVpnId for VPN {}", vpnName, e);
+        }
+    }
+
+    public static void removeVrfTableForVpn(DataBroker broker, String vpnName) {
+        // Clean up FIB Entries Config DS
+        try {
+            delete(broker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(vpnName)).build(),
+                    DEFAULT_CALLBACK);
+        } catch (Exception e) {
+            LOG.error("Exception during clean up of VrfTable from FIB for VPN {}", vpnName, e);
+        }
+    }
+
+    public static void removeL3nexthopForVpnId(DataBroker broker, long vpnId) {
+        try {
+            // Clean up L3NextHop Operational DS
+            delete(broker, LogicalDatastoreType.OPERATIONAL,
+                    InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class, new VpnNexthopsKey(vpnId)).build(),
+                    DEFAULT_CALLBACK);
+        } catch (Exception e) {
+            LOG.error("Exception during cleanup of L3NextHop for VPN ID {}", vpnId, e);
+        }
+    }
+}
\ No newline at end of file