Bug 7192 - Inter-VPN link routes BGP leaking not working
[netvirt.git] / vpnservice / fibmanager / fibmanager-impl / src / main / java / org / opendaylight / netvirt / fibmanager / VrfEntryListener.java
index 4f85414b8c85ca552a1f354ae579e3713f535576..362100b612eb1b92f5619de8592a1cae9352d8bb 100755 (executable)
@@ -12,8 +12,8 @@ import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
-
 import java.math.BigInteger;
+import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
@@ -25,13 +25,12 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.LinkedBlockingQueue;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.ActionType;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
@@ -442,12 +441,13 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                                                        && interVpnLink.get().isBgpRoutesLeaking() );
 
         if ( proceed ) {
-            String theOtherVpnId = interVpnLink.get().getFirstEndpoint().getVpnUuid().getValue().equals(vpnUuid)
-                    ? interVpnLink.get().getSecondEndpoint().getVpnUuid().getValue()
-                    : vpnUuid;
+            boolean isVpnFirstEndpoint = interVpnLink.get().getFirstEndpoint().getVpnUuid().getValue().equals(vpnUuid);
 
+            String theOtherVpnId = isVpnFirstEndpoint ? interVpnLink.get().getSecondEndpoint().getVpnUuid().getValue()
+                                                      : vpnUuid;
             String dstVpnRd = FibUtil.getVpnRd(dataBroker, theOtherVpnId);
-            String endpointIp = vrfEntry.getNextHopAddressList().get(0);
+            String endpointIp = isVpnFirstEndpoint ? interVpnLink.get().getFirstEndpoint().getIpAddress().toString()
+                                                   : interVpnLink.get().getSecondEndpoint().getIpAddress().toString();
 
             InstanceIdentifier<VrfEntry> vrfEntryIidInOtherVpn =
                     InstanceIdentifier.builder(FibEntries.class)
@@ -1540,13 +1540,22 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
         matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
                 MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
 
-        matches.add(new MatchInfo(MatchFieldType.eth_type,
-                new long[] { NwConstants.ETHTYPE_IPV4 }));
-
-        if(prefixLength != 0) {
-            matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] {
-                    destPrefix.getHostAddress(), Integer.toString(prefixLength)}));
+        if (destPrefix instanceof Inet4Address) {
+            matches.add(new MatchInfo(MatchFieldType.eth_type,
+                    new long[] { NwConstants.ETHTYPE_IPV4 }));
+            if(prefixLength != 0) {
+                matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] {
+                        destPrefix.getHostAddress(), Integer.toString(prefixLength)}));
+            }
+        } else {
+            matches.add(new MatchInfo(MatchFieldType.eth_type,
+                    new long[] { NwConstants.ETHTYPE_IPV6 }));
+            if(prefixLength != 0) {
+                matches.add(new MatchInfo(MatchFieldType.ipv6_destination, new String[] {
+                        destPrefix.getHostAddress() + "/" + Integer.toString(prefixLength)}));
+            }
         }
+
         int priority = DEFAULT_FIB_FLOW_PRIORITY + prefixLength;
         String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, rd, priority, destPrefix);
         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef, priority, flowRef, 0, 0,
@@ -2105,6 +2114,20 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                         child(VrfEntry.class, new VrfEntryKey(ipPrefix)).build();
         return vrfEntryId;
     }
+
+    protected Boolean isIpv4Address(String ipAddress) {
+        try {
+            InetAddress address = InetAddress.getByName(ipAddress);
+            if (address instanceof Inet4Address) {
+                return true;
+            }
+        } catch (UnknownHostException e) {
+            LOG.warn("Invalid ip address {}", ipAddress, e);
+            return false;
+        }
+        return false;
+    }
+
     protected Boolean installRouterFibEntries(final VrfEntry vrfEntry, final Collection<VpnToDpnList> vpnToDpnList,
             long vpnId, int addOrRemove) {
         RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
@@ -2128,6 +2151,10 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
     public void installRouterFibEntry(final VrfEntry vrfEntry, BigInteger dpnId, long vpnId, String routerUuid,
                                       String routerInternalIp, MacAddress routerMac, int addOrRemove) {
         String[] subSplit = routerInternalIp.split("/");
+        if (!isIpv4Address(subSplit[0])) {
+            // Ping responder using OpenFlow rules is only supported for IPv4, hence skipping.
+            return;
+        }
 
         String addRemoveStr = (addOrRemove == NwConstants.ADD_FLOW) ? "ADD_FLOW" : "DELETE_FLOW";
         LOG.trace("{}: bulding Echo Flow entity for dpid:{}, router_ip:{}, vpnId:{}, subSplit:{} ", addRemoveStr,