Avoid NPE for IPv6 external subnets
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / VpnManagerImpl.java
index dfd320b8fee88091b6c7ad690759228f8fc5c912..447931e8bd89e6dbb825f8f4ec7cf777691e5d67 100644 (file)
@@ -22,6 +22,8 @@ import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 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.ReadFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
@@ -42,6 +44,7 @@ import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
+import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
 import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper;
@@ -187,11 +190,13 @@ public class VpnManagerImpl implements IVpnManager {
     public void addExtraRoute(String vpnName, String destination, String nextHop, String rd, String routerID,
             Long l3vni, RouteOrigin origin, String intfName, Adjacency operationalAdj,
             VrfEntry.EncapType encapType, WriteTransaction writeConfigTxn) {
-
-        Boolean writeConfigTxnPresent = true;
         if (writeConfigTxn == null) {
-            writeConfigTxnPresent = false;
-            writeConfigTxn = dataBroker.newWriteOnlyTransaction();
+            String finalNextHop = nextHop;
+            ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+                addExtraRoute(vpnName, destination, finalNextHop, rd, routerID, l3vni, origin, intfName, operationalAdj,
+                        encapType, tx)),
+                    LOG, "Error adding extra route");
+            return;
         }
 
         //add extra route to vpn mapping; advertise with nexthop as tunnel ip
@@ -254,10 +259,6 @@ public class VpnManagerImpl implements IVpnManager {
                 }
             }
         }
-
-        if (!writeConfigTxnPresent) {
-            writeConfigTxn.submit();
-        }
     }
 
     @Override
@@ -269,12 +270,13 @@ public class VpnManagerImpl implements IVpnManager {
     @Override
     public void delExtraRoute(String vpnName, String destination, String nextHop, String rd, String routerID,
             String intfName, WriteTransaction writeConfigTxn) {
-        Boolean writeConfigTxnPresent = true;
-        BigInteger dpnId = null;
         if (writeConfigTxn == null) {
-            writeConfigTxnPresent = false;
-            writeConfigTxn = dataBroker.newWriteOnlyTransaction();
+            ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+                delExtraRoute(vpnName, destination, nextHop, rd, routerID, intfName, tx)),
+                    LOG, "Error deleting extra route");
+            return;
         }
+        BigInteger dpnId = null;
         String tunnelIp = nextHop;
         if (intfName != null && !intfName.isEmpty()) {
             dpnId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, intfName);
@@ -296,9 +298,6 @@ public class VpnManagerImpl implements IVpnManager {
             LOG.info("delExtraRoute: Removed extra route {} from interface {} for rd {}", destination, intfName,
                     routerID);
         }
-        if (!writeConfigTxnPresent) {
-            writeConfigTxn.submit();
-        }
     }
 
  // TODO Clean up the exception handling
@@ -356,13 +355,18 @@ public class VpnManagerImpl implements IVpnManager {
     @Override
     public boolean isVPNConfigured() {
         InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class).build();
-        Optional<VpnInstances> optionalVpns = TransactionUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
-            vpnsIdentifier);
-        if (!optionalVpns.isPresent()
-            || optionalVpns.get().getVpnInstance() == null
-            || optionalVpns.get().getVpnInstance().isEmpty()) {
-            LOG.trace("isVPNConfigured: No VPNs configured.");
-            return false;
+        try {
+            Optional<VpnInstances> optionalVpns =
+                    SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                            vpnsIdentifier);
+            if (!optionalVpns.isPresent()
+                    || optionalVpns.get().getVpnInstance() == null
+                    || optionalVpns.get().getVpnInstance().isEmpty()) {
+                LOG.trace("isVPNConfigured: No VPNs configured.");
+                return false;
+            }
+        } catch (ReadFailedException e) {
+            throw new RuntimeException("Error reading VPN " + vpnsIdentifier, e);
         }
         LOG.trace("isVPNConfigured: VPNs are configured on the system.");
         return true;
@@ -417,12 +421,12 @@ public class VpnManagerImpl implements IVpnManager {
     }
 
     private void addGwMac(String srcMacAddress, WriteTransaction tx, long vpnId, BigInteger dpId, long subnetVpnId) {
-        FlowEntity flowEntity = VpnUtil.buildL3vpnGatewayFlow(dpId, srcMacAddress, vpnId, subnetVpnId);
+        FlowEntity flowEntity = VpnUtil.buildL3vpnGatewayFlow(dataBroker, dpId, srcMacAddress, vpnId, subnetVpnId);
         mdsalManager.addFlowToTx(flowEntity, tx);
     }
 
     private void removeGwMac(String srcMacAddress, WriteTransaction tx, long vpnId, BigInteger dpId, long subnetVpnId) {
-        FlowEntity flowEntity = VpnUtil.buildL3vpnGatewayFlow(dpId, srcMacAddress, vpnId, subnetVpnId);
+        FlowEntity flowEntity = VpnUtil.buildL3vpnGatewayFlow(dataBroker, dpId, srcMacAddress, vpnId, subnetVpnId);
         mdsalManager.removeFlowToTx(flowEntity, tx);
     }
 
@@ -560,6 +564,10 @@ public class VpnManagerImpl implements IVpnManager {
             ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(
                 tx -> {
                     for (String fixedIp : fixedIps) {
+                        IpVersionChoice ipVersionChoice = VpnUtil.getIpVersionFromString(fixedIp);
+                        if (ipVersionChoice == IpVersionChoice.IPV6) {
+                            continue;
+                        }
                         installArpResponderFlowsToExternalNetworkIp(macAddress, dpnId, extInterfaceName, lportTag,
                                 fixedIp);
                     }
@@ -567,6 +575,10 @@ public class VpnManagerImpl implements IVpnManager {
             ListenableFutures.addErrorLogging(future, LOG, "Commit transaction");
         } else {
             for (String fixedIp : fixedIps) {
+                IpVersionChoice ipVersionChoice = VpnUtil.getIpVersionFromString(fixedIp);
+                if (ipVersionChoice == IpVersionChoice.IPV6) {
+                    continue;
+                }
                 installArpResponderFlowsToExternalNetworkIp(macAddress, dpnId, extInterfaceName, lportTag,
                         fixedIp);
             }