Bug 7302: Enable Ping Responder for router interface IPs , on a BGPVPN
[netvirt.git] / vpnservice / fibmanager / fibmanager-impl / src / main / java / org / opendaylight / netvirt / fibmanager / FibUtil.java
index 7bb448e6899a59739ca3c8a3d7433d7c50a7ae4f..61f474322b5f0216f936f8a61f23d8d6afc1c91a 100644 (file)
@@ -29,6 +29,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.RouterInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesBuilder;
@@ -68,6 +69,7 @@ import org.slf4j.LoggerFactory;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -170,6 +172,18 @@ public class FibUtil {
         return key;
     }
 
+    static Prefixes getPrefixToInterface(DataBroker broker, Long vpnId, String ipPrefix) {
+        Optional<Prefixes> localNextHopInfoData = read(broker, LogicalDatastoreType.OPERATIONAL,
+                getPrefixToInterfaceIdentifier(vpnId, ipPrefix));
+        return localNextHopInfoData.isPresent() ? localNextHopInfoData.get() : null;
+    }
+
+    static String getMacAddressFromPrefix(DataBroker broker, String ifName, String ipPrefix) {
+        Optional<Adjacency> adjacencyData = read(broker, LogicalDatastoreType.OPERATIONAL,
+                getAdjacencyIdentifier(ifName, ipPrefix));
+        return adjacencyData.isPresent() ? adjacencyData.get().getMacAddress() : null;
+    }
+
     static void releaseId(IdManagerService idManager, String poolName, String idKey) {
         ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
         try {
@@ -223,10 +237,10 @@ public class FibUtil {
         InstanceIdentifier<InterVpnLinks> interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build();
 
         Optional<InterVpnLinks> interVpnLinksOpData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
-                interVpnLinksIid);
+                                                                     interVpnLinksIid);
 
-        return ( interVpnLinksOpData.isPresent() ) ? interVpnLinksOpData.get().getInterVpnLink()
-                : new ArrayList<InterVpnLink>();
+        return interVpnLinksOpData.isPresent() ? interVpnLinksOpData.get().getInterVpnLink()
+                                               : new ArrayList<>();
     }
 
     /**
@@ -463,6 +477,7 @@ public class FibUtil {
             throw new RuntimeException(e.getMessage());
         }
     }
+
     public static void addOrUpdateFibEntry(DataBroker broker, String rd, String prefix, List<String> nextHopList,
                                            int label, RouteOrigin origin, WriteTransaction writeConfigTxn) {
         if (rd == null || rd.isEmpty() ) {
@@ -472,14 +487,6 @@ public class FibUtil {
 
         Preconditions.checkNotNull(nextHopList, "NextHopList can't be null");
 
-        for ( String nextHop: nextHopList){
-            if (nextHop == null || nextHop.isEmpty()){
-                LOG.error("nextHop list contains null element");
-                return;
-            }
-        }
-
-        LOG.debug("Created vrfEntry for {} nexthop {} label {}", prefix, nextHopList, label);
         try{
             InstanceIdentifier<VrfEntry> vrfEntryId =
                     InstanceIdentifier.builder(FibEntries.class)
@@ -496,6 +503,7 @@ public class FibUtil {
                 } else {
                     MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry);
                 }
+                LOG.debug("Created vrfEntry for {} nexthop {} label {}", prefix, nextHopList, label);
             } else { // Found in MDSAL database
                 List<String> nh = entry.get().getNextHopAddressList();
                 for (String nextHop : nextHopList) {
@@ -511,12 +519,47 @@ public class FibUtil {
                 } else {
                     MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry);
                 }
+                LOG.debug("Updated vrfEntry for {} nexthop {} label {}", prefix, nh, label);
             }
         } catch (Exception e) {
             LOG.error("addFibEntryToDS: error ", e);
         }
     }
 
+    public static void addFibEntryForRouterInterface(DataBroker broker,
+                                                     String rd,
+                                                     String prefix,
+                                                     RouterInterface routerInterface,
+                                                     long label,
+                                                     WriteTransaction writeConfigTxn) {
+        if (rd == null || rd.isEmpty() ) {
+            LOG.error("Prefix {} not associated with vpn", prefix);
+            return;
+        }
+
+        try{
+            InstanceIdentifier<VrfEntry> vrfEntryId =
+                    InstanceIdentifier.builder(FibEntries.class)
+                            .child(VrfTables.class, new VrfTablesKey(rd))
+                            .child(VrfEntry.class, new VrfEntryKey(prefix)).build();
+
+            VrfEntry vrfEntry = new VrfEntryBuilder().setKey(new VrfEntryKey(prefix)).setDestPrefix(prefix)
+                    .setNextHopAddressList(Arrays.asList(""))
+                    .setLabel(label)
+                    .setOrigin(RouteOrigin.LOCAL.getValue())
+                    .addAugmentation(RouterInterface.class, routerInterface).build();
+
+            if (writeConfigTxn != null) {
+                writeConfigTxn.merge(LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry, true);
+            } else {
+                MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry);
+            }
+            LOG.debug("Created vrfEntry for router-interface-prefix {} rd {} label {}", prefix, rd, label);
+        } catch (Exception e) {
+            LOG.error("addFibEntryToDS: error ", e);
+        }
+    }
+
     public static void removeFibEntry(DataBroker broker, String rd, String prefix, WriteTransaction writeConfigTxn) {
 
         if (rd == null || rd.isEmpty()) {
@@ -590,6 +633,40 @@ public class FibUtil {
         }
     }
 
+    public static void updateFibEntry(DataBroker broker, String rd, String prefix, List<String> nextHopList,
+                                      WriteTransaction writeConfigTxn) {
+
+        LOG.debug("Updating fib entry for prefix {} with nextHopList {} for rd {}", prefix, nextHopList, rd);
+
+        // Looking for existing prefix in MDSAL database
+        InstanceIdentifier<VrfEntry> vrfEntryId =
+                InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd))
+                        .child(VrfEntry.class, new VrfEntryKey(prefix)).build();
+        Optional<VrfEntry> entry = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
+
+        if ( entry.isPresent() ) {
+            // Update the VRF entry with nextHopList
+            VrfEntry vrfEntry =
+                    new VrfEntryBuilder(entry.get()).setDestPrefix(prefix).setNextHopAddressList(nextHopList)
+                            .setKey(new VrfEntryKey(prefix)).build();
+            if(nextHopList.isEmpty()) {
+                if (writeConfigTxn != null) {
+                    writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry, true);
+                } else {
+                    MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry);
+                }
+            } else {
+                if (writeConfigTxn != null) {
+                    writeConfigTxn.merge(LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry, true);
+                } else {
+                    MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry);
+                }
+            }
+            LOG.debug("Updated fib entry for prefix {} with nextHopList {} for rd {}", prefix, nextHopList, rd);
+        } else {
+            LOG.warn("Could not find VrfEntry for Route-Distinguisher={} and prefix={}", rd, prefix);
+        }
+    }
 
     public static void addVrfTable(DataBroker broker, String rd, WriteTransaction writeConfigTxn) {
         LOG.debug("Adding vrf table for rd {}", rd);
@@ -618,4 +695,23 @@ public class FibUtil {
         }
     }
 
+    public static boolean isControllerManagedRoute(RouteOrigin routeOrigin) {
+        if (routeOrigin == RouteOrigin.STATIC ||
+                routeOrigin == RouteOrigin.CONNECTED ||
+                routeOrigin == RouteOrigin.LOCAL ||
+                routeOrigin == RouteOrigin.INTERVPN) {
+            return true;
+        }
+        return false;
+    }
+
+    public static boolean isControllerManagedNonInterVpnLinkRoute(RouteOrigin routeOrigin)
+    {
+        if (routeOrigin == RouteOrigin.STATIC ||
+                routeOrigin == RouteOrigin.CONNECTED ||
+                routeOrigin == RouteOrigin.LOCAL) {
+            return true;
+        }
+        return false;
+    }
 }