X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnmanager%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fvpnmanager%2FTunnelInterfaceStateListener.java;h=85d3dc0af934035d128bd329cacdfbd4408e4209;hb=2f0569ed75ef8a1fb60f992d19c8bbdf92ff45bf;hp=cdae7499f0b2073a7f9dd0140b3e6fb169164957;hpb=371ff1cf073bc85d00b27e778dd058190f702a87;p=netvirt.git diff --git a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/TunnelInterfaceStateListener.java b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/TunnelInterfaceStateListener.java index cdae7499f0..85d3dc0af9 100644 --- a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/TunnelInterfaceStateListener.java +++ b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/TunnelInterfaceStateListener.java @@ -7,43 +7,44 @@ */ package org.opendaylight.netvirt.vpnmanager; -import static java.util.stream.Collectors.toList; +import static java.util.Collections.emptyList; +import static org.opendaylight.genius.infra.Datastore.CONFIGURATION; +import static org.opendaylight.genius.infra.Datastore.OPERATIONAL; -import com.google.common.base.Optional; import com.google.common.base.Strings; import com.google.common.util.concurrent.ListenableFuture; -import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import javax.annotation.PostConstruct; +import java.util.concurrent.locks.ReentrantLock; +import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.inject.Singleton; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -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.AsyncDataTreeChangeListenerBase; import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; import org.opendaylight.genius.infra.ManagedNewTransactionRunner; import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl; -import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.genius.mdsalutil.NwConstants; +import org.opendaylight.genius.utils.JvmGlobalLocks; import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; -import org.opendaylight.infrautils.utils.concurrent.ListenableFutures; +import org.opendaylight.infrautils.utils.concurrent.Executors; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.netvirt.fibmanager.api.FibHelper; import org.opendaylight.netvirt.fibmanager.api.IFibManager; import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils; import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper; import org.opendaylight.netvirt.vpnmanager.api.VpnHelper; -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.vpn._interface.VpnInstanceNames; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; +import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan; 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.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; @@ -61,25 +62,27 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.Tep import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.extraroute.rds.DestPrefixes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesOp; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PortOpData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.Adjacency; +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.vpn._interface.VpnInstanceNames; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton -public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBase { +public class TunnelInterfaceStateListener extends AbstractAsyncDataTreeChangeListener { private static final Logger LOG = LoggerFactory.getLogger(TunnelInterfaceStateListener.class); @@ -91,6 +94,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas private final VpnSubnetRouteHandler vpnSubnetRouteHandler; private final JobCoordinator jobCoordinator; private final VpnUtil vpnUtil; + private static final int RETRY_COUNT = 3; protected enum UpdateRouteAction { ADVERTISE_ROUTE, WITHDRAW_ROUTE @@ -120,7 +124,9 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas final VpnSubnetRouteHandler vpnSubnetRouteHandler, final JobCoordinator jobCoordinator, VpnUtil vpnUtil) { - super(StateTunnelList.class, TunnelInterfaceStateListener.class); + super(dataBroker, LogicalDatastoreType.OPERATIONAL, + InstanceIdentifier.create(TunnelsState.class).child(StateTunnelList.class), + Executors.newListeningSingleThreadExecutor("TunnelInterfaceStateListener", LOG)); this.dataBroker = dataBroker; this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker); this.fibManager = fibManager; @@ -129,35 +135,32 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas this.vpnSubnetRouteHandler = vpnSubnetRouteHandler; this.jobCoordinator = jobCoordinator; this.vpnUtil = vpnUtil; + start(); } - @PostConstruct public void start() { LOG.info("{} start", getClass().getSimpleName()); - registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker); } @Override - protected InstanceIdentifier getWildCardPath() { - return InstanceIdentifier.create(TunnelsState.class).child(StateTunnelList.class); + @PreDestroy + public void close() { + super.close(); + Executors.shutdownAndAwaitTermination(getExecutorService()); } - @Override - protected TunnelInterfaceStateListener getDataTreeChangeListener() { - return TunnelInterfaceStateListener.this; - } @Override - protected void remove(InstanceIdentifier identifier, StateTunnelList del) { + public void remove(InstanceIdentifier identifier, StateTunnelList del) { LOG.trace("remove: Tunnel deletion---- {}", del); if (isGreTunnel(del)) { - programDcGwLoadBalancingGroup(del, NwConstants.DEL_FLOW); + programDcGwLoadBalancingGroup(del, NwConstants.MOD_FLOW, false); } handleTunnelEventForDPN(del, TunnelAction.TUNNEL_EP_DELETE); } @Override - protected void update(InstanceIdentifier identifier, StateTunnelList original, + public void update(InstanceIdentifier identifier, StateTunnelList original, StateTunnelList update) { LOG.trace("update: Tunnel updation---- {}", update); LOG.info("update: ITM Tunnel {} of type {} state event changed from :{} to :{}", @@ -170,50 +173,54 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas update.getTunnelInterfaceName()); return; } + boolean isTunnelUp = TunnelOperStatus.Up == update.getOperState(); if (isGreTunnel(update)) { - programDcGwLoadBalancingGroup(update, NwConstants.MOD_FLOW); + programDcGwLoadBalancingGroup(update, NwConstants.MOD_FLOW, isTunnelUp); } //Remove the corresponding nexthop from the routepath under extraroute in fibentries. - BigInteger srcDpnId = new BigInteger(update.getSrcInfo().getTepDeviceId()); - String srcTepIp = String.valueOf(update.getSrcInfo().getTepIp().getValue()); + Uint64 srcDpnId = Uint64.valueOf(update.getSrcInfo().getTepDeviceId()).intern(); + String srcTepIp = update.getSrcInfo().getTepIp().stringValue(); List vpnInstanceOpData = vpnUtil.getAllVpnInstanceOpData(); if (vpnInstanceOpData == null) { LOG.trace("update: No vpnInstanceOpdata present"); return; } - ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> - vpnInstanceOpData.stream() - .filter(opData -> opData.getVpnToDpnList() != null - && opData.getVpnToDpnList().stream().anyMatch( - vpnToDpn -> vpnToDpn.getDpnId().equals(srcDpnId))) - .forEach(opData -> { - List prefixes = VpnExtraRouteHelper.getExtraRouteDestPrefixes(dataBroker, - opData.getVpnId()); - prefixes.forEach(destPrefix -> { - VrfEntry vrfEntry = vpnUtil.getVrfEntry(opData.getVrfId(), - destPrefix.getDestPrefix()); - if (vrfEntry == null || vrfEntry.getRoutePaths() == null) { - return; + vpnInstanceOpData.stream() + .filter(opData -> opData.getVpnToDpnList() != null + && opData.getVpnToDpnList().stream().anyMatch( + vpnToDpn -> Objects.equals(vpnToDpn.getDpnId(), srcDpnId))) + .forEach(opData -> { + List prefixes = VpnExtraRouteHelper.getExtraRouteDestPrefixes(dataBroker, + opData.getVpnId()); + prefixes.forEach(destPrefix -> { + VrfEntry vrfEntry = vpnUtil.getVrfEntry(opData.getVrfId(), + destPrefix.getDestPrefix()); + if (vrfEntry == null || vrfEntry.getRoutePaths() == null) { + return; + } + List routePaths = vrfEntry.getRoutePaths(); + routePaths.forEach(routePath -> { + if (Objects.equals(routePath.getNexthopAddress(), srcTepIp)) { + String prefix = destPrefix.getDestPrefix(); + String vpnPrefixKey = VpnUtil.getVpnNamePrefixKey(opData.getVpnInstanceName(), + prefix); + // FIXME: separate out to somehow? + final ReentrantLock lock = JvmGlobalLocks.getLockForString(vpnPrefixKey); + lock.lock(); + try { + fibManager.refreshVrfEntry(opData.getVrfId(), prefix); + } finally { + lock.unlock(); } - List routePaths = vrfEntry.getRoutePaths(); - routePaths.forEach(routePath -> { - if (routePath.getNexthopAddress().equals(srcTepIp)) { - String prefix = destPrefix.getDestPrefix(); - String vpnPrefixKey = VpnUtil.getVpnNamePrefixKey(opData.getVpnInstanceName(), - prefix); - synchronized (vpnPrefixKey.intern()) { - fibManager.refreshVrfEntry(opData.getVrfId(), prefix); - } - } - }); - }); - }) - ), LOG, "Error updating route paths for FIB entries"); + } + }); + }); + }); } @Override - protected void add(InstanceIdentifier identifier, StateTunnelList add) { + public void add(InstanceIdentifier identifier, StateTunnelList add) { LOG.trace("add: Tunnel addition---- {}", add); TunnelOperStatus tunOpStatus = add.getOperState(); if (tunOpStatus != TunnelOperStatus.Down && tunOpStatus != TunnelOperStatus.Up) { @@ -224,12 +231,15 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas if (tunOpStatus != TunnelOperStatus.Up) { LOG.error("add: Tunnel {} is not yet UP.", add.getTunnelInterfaceName()); } + boolean isTunnelUp = TunnelOperStatus.Up == add.getOperState(); if (isGreTunnel(add)) { - programDcGwLoadBalancingGroup(add, NwConstants.ADD_FLOW); + programDcGwLoadBalancingGroup(add, NwConstants.ADD_FLOW, isTunnelUp); } LOG.info("add: ITM Tunnel ,type {} ,added between src: {} and dest: {}", - fibManager.getTransportTypeStr(add.getTransportType().toString()), - add.getSrcInfo().getTepDeviceId(), add.getDstInfo().getTepDeviceId()); + fibManager.getTransportTypeStr(add.getTransportType() != null + ? add.getTransportType().toString() : "Invalid"), + add.getSrcInfo() != null ? add.getSrcInfo().getTepDeviceId() : "0", + add.getDstInfo() != null ? add.getDstInfo().getTepDeviceId() : "0"); handleTunnelEventForDPN(add, TunnelAction.TUNNEL_EP_ADD); } @@ -250,11 +260,14 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") private void handleTunnelEventForDPN(StateTunnelList stateTunnelList, TunnelAction tunnelAction) { - final BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId()); - final String srcTepIp = String.valueOf(stateTunnelList.getSrcInfo().getTepIp().getValue()); - String destTepIp = String.valueOf(stateTunnelList.getDstInfo().getTepIp().getValue()); + final Uint64 srcDpnId = stateTunnelList.getSrcInfo() != null + ? Uint64.valueOf(stateTunnelList.getSrcInfo().getTepDeviceId()).intern() : Uint64.ZERO; + final String srcTepIp = stateTunnelList.getSrcInfo() != null + ? stateTunnelList.getSrcInfo().getTepIp().stringValue() : "0"; + String destTepIp = stateTunnelList.getDstInfo() != null + ? stateTunnelList.getDstInfo().getTepIp().stringValue() : "0"; String rd; - BigInteger remoteDpnId = null; + Uint64 remoteDpnId = null; boolean isTepDeletedOnDpn = false; LOG.info("handleTunnelEventForDPN: Handle tunnel event for srcDpn {} SrcTepIp {} DestTepIp {} ", @@ -276,7 +289,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas // Update the adj for the vpninterfaces for a DPN on which TEP is deleted. // Update the adj & VRF for the vpninterfaces for a DPN on which TEP is deleted. // Dont update the adj & VRF for vpninterfaces for a DPN on which TEP is not deleted. - String endpointIpForDPN = null; + String endpointIpForDPN; try { endpointIpForDPN = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, srcDpnId); } catch (Exception e) { @@ -305,7 +318,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas + " destTepIP {} returned with Errors {}", srcDpnId, srcTepIp, destTepIp, rpcResult.getErrors()); } else { - srcDpninterfacelist = rpcResult.getResult().getInterfaces(); + srcDpninterfacelist = rpcResult.getResult().nonnullInterfaces(); } } catch (Exception e) { LOG.error("handleTunnelEventForDPN: Exception when querying for GetDpnInterfaceList for srcDpnid {}" @@ -313,7 +326,8 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas } // Get the list of VpnInterfaces from Intf Mgr for a destDPN only for internal tunnel. if (tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) { - remoteDpnId = new BigInteger(stateTunnelList.getDstInfo().getTepDeviceId()); + remoteDpnId = Uint64.valueOf(stateTunnelList.getDstInfo() != null + ? stateTunnelList.getDstInfo().getTepDeviceId() : "0").intern(); try { result = intfRpcService.getDpnInterfaceList( new GetDpnInterfaceListInputBuilder().setDpid(remoteDpnId).build()); @@ -323,7 +337,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas + " srcTepIP {} destTepIp {} returned with Errors {}", remoteDpnId, srcTepIp, destTepIp, rpcResult.getErrors()); } else { - destDpninterfacelist = rpcResult.getResult().getInterfaces(); + destDpninterfacelist = rpcResult.getResult().nonnullInterfaces(); } } catch (Exception e) { LOG.error("handleTunnelEventForDPN: Exception when querying for GetDpnInterfaceList" @@ -336,20 +350,16 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas * Iterate over the list of VpnInterface for a SrcDpn on which TEP is added or deleted and read the adj. * Update the adjacencies with the updated nexthop. */ - Iterator interfacelistIter = srcDpninterfacelist.iterator(); - Interfaces interfaces = null; - String intfName = null; List subnetList = new ArrayList<>(); - Map vpnIdRdMap = new HashMap<>(); + Map vpnIdRdMap = new HashMap<>(); Set listVpnName = new HashSet<>(); - while (interfacelistIter.hasNext()) { - interfaces = interfacelistIter.next(); + for (Interfaces interfaces : srcDpninterfacelist) { if (!L2vlan.class.equals(interfaces.getInterfaceType())) { LOG.info("handleTunnelEventForDPN: Interface {} not of type L2Vlan", interfaces.getInterfaceName()); continue; } - intfName = interfaces.getInterfaceName(); + String intfName = interfaces.getInterfaceName(); VpnInterface vpnInterface = vpnUtil.getConfiguredVpnInterface(intfName); if (vpnInterface != null) { @@ -365,14 +375,12 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas * Iterate over the list of VpnInterface for destDPN and get the prefix . * Create remote rule for each of those prefix on srcDPN. */ - interfacelistIter = destDpninterfacelist.iterator(); - while (interfacelistIter.hasNext()) { - interfaces = interfacelistIter.next(); + for (Interfaces interfaces : destDpninterfacelist) { if (!L2vlan.class.equals(interfaces.getInterfaceType())) { LOG.info("handleTunnelEventForDPN: Interface {} not of type L2Vlan", interfaces.getInterfaceName()); continue; } - intfName = interfaces.getInterfaceName(); + String intfName = interfaces.getInterfaceName(); VpnInterface vpnInterface = vpnUtil.getConfiguredVpnInterface(intfName); if (vpnInterface != null) { @@ -384,8 +392,8 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas } //Iterate over the VpnId-to-Rd map. - for (Map.Entry entry : vpnIdRdMap.entrySet()) { - Long vpnId = entry.getKey(); + for (Map.Entry entry : vpnIdRdMap.entrySet()) { + Uint32 vpnId = entry.getKey(); rd = entry.getValue(); if (tunnelAction == TunnelAction.TUNNEL_EP_ADD && tunTypeVal == VpnConstants.ITMTunnelLocType.External.getValue()) { @@ -409,6 +417,24 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas } } } + /* + * Program the BGP routes of all the VPNs which have footprint on the source DPN. + * + * DC-GW LB groups are programmed in DJC Jobs, so DJC with same key is used here to make sure + * groups are programmed first, then only BGP routes are programmed. + */ + jobCoordinator.enqueueJob(FibHelper.getJobKeyForDcGwLoadBalancingGroup(srcDpnId), () -> { + listVpnName.forEach(vpnName -> { + Uint32 vpnId = vpnUtil.getVpnId(vpnName); + final String vrfId = vpnIdRdMap.get(vpnId); + if ((tunnelAction == TunnelAction.TUNNEL_EP_ADD) + && (tunTypeVal == VpnConstants.ITMTunnelLocType.External.getValue())) { + fibManager.populateExternalRoutesOnDpn(srcDpnId, vpnId, vrfId, + srcTepIp, destTepIp); + } + }); + return Collections.emptyList(); + },RETRY_COUNT); } catch (RuntimeException e) { LOG.error("handleTunnelEventForDpn: Unable to handle the tunnel event for srcDpnId {} srcTepIp {}" + " remoteDpnId {} destTepIp {}", srcDpnId, srcTepIp, remoteDpnId, destTepIp, e); @@ -418,19 +444,23 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas // TODO Clean up the exception handling @SuppressWarnings("checkstyle:IllegalCatch") private void handleTunnelEventForDPNVpn(StateTunnelList stateTunnelList, - Map vpnIdRdMap, TunnelAction tunnelAction, + Map vpnIdRdMap, TunnelAction tunnelAction, boolean isTepDeletedOnDpn, List subnetList, TunnelEventProcessingMethod method, VpnInterface cfgVpnInterface) { String rd; String intfName = cfgVpnInterface.getName(); - final BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId()); - String destTepIp = String.valueOf(stateTunnelList.getDstInfo().getTepIp().getValue()); - String srcTepIp = String.valueOf(stateTunnelList.getSrcInfo().getTepIp().getValue()); + final Uint64 srcDpnId = Uint64.valueOf(stateTunnelList.getSrcInfo() != null + ? stateTunnelList.getSrcInfo().getTepDeviceId() : "0").intern(); + String destTepIp = stateTunnelList.getDstInfo() != null ? stateTunnelList.getDstInfo().getTepIp().stringValue() + : null; + String srcTepIp = stateTunnelList.getSrcInfo() != null ? stateTunnelList.getSrcInfo().getTepIp().stringValue() + : null; int tunTypeVal = getTunnelType(stateTunnelList); - BigInteger remoteDpnId = null; + Uint64 remoteDpnId = null; if (tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) { - remoteDpnId = new BigInteger(stateTunnelList.getDstInfo().getTepDeviceId()); + remoteDpnId = Uint64.valueOf(stateTunnelList.getDstInfo() != null + ? stateTunnelList.getDstInfo().getTepDeviceId() : "0").intern(); } if (cfgVpnInterface.getVpnInstanceNames() == null) { LOG.warn("handleTunnelEventForDpn: no vpnName found for interface {}", intfName); @@ -468,7 +498,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas } } //Populate the map for VpnId-to-Rd - long vpnId = vpnUtil.getVpnId(vpnName); + Uint32 vpnId = vpnUtil.getVpnId(vpnName); rd = vpnUtil.getVpnRd(vpnName); vpnIdRdMap.put(vpnId, rd); } @@ -478,10 +508,11 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas if (opVpnInterface.isPresent()) { VpnInterfaceOpDataEntry vpnInterface = opVpnInterface.get(); AdjacenciesOp adjacencies = vpnInterface.augmentation(AdjacenciesOp.class); - List adjList = adjacencies != null ? adjacencies.getAdjacency() - : Collections.emptyList(); + List adjList = + adjacencies != null && adjacencies.getAdjacency() != null ? adjacencies.getAdjacency() + : emptyList(); String prefix = null; - long vpnId = vpnUtil.getVpnId(vpnInterface.getVpnInstanceName()); + Uint32 vpnId = vpnUtil.getVpnId(vpnInterface.getVpnInstanceName()); if (vpnIdRdMap.containsKey(vpnId)) { rd = vpnIdRdMap.get(vpnId); LOG.info("handleTunnelEventForDPN: Remote DpnId {} VpnId {} rd {} VpnInterface {}" @@ -489,7 +520,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas destTepIp); for (Adjacency adj : adjList) { prefix = adj.getIpAddress(); - long label = adj.getLabel(); + Uint32 label = adj.getLabel(); if (tunnelAction == TunnelAction.TUNNEL_EP_ADD && tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) { fibManager.manageRemoteRouteOnDPN(true, srcDpnId, vpnId, rd, prefix, destTepIp, @@ -505,7 +536,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas } } } - } catch (ReadFailedException e) { + } catch (InterruptedException | ExecutionException e) { LOG.error("handleTunnelEventForDPN: Failed to read data store for interface {} srcDpn {} srcTep {} " + "dstTep {}", intfName, srcDpnId, srcTepIp, destTepIp); } @@ -530,24 +561,26 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas @Override public List> call() { List> futures = new ArrayList<>(2); - futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> - futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx -> { - if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) { - vpnInterfaceManager.updateVpnInterfaceOnTepAdd(vpnInterface, stateTunnelList, confTx, - operTx); - } + futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> + futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> { + if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) { + vpnInterfaceManager.updateVpnInterfaceOnTepAdd(vpnInterface, stateTunnelList, confTx, operTx); + } - if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE && isTepDeletedOnDpn) { - vpnInterfaceManager.updateVpnInterfaceOnTepDelete(vpnInterface, stateTunnelList, confTx, - operTx); - } - })))); + if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE && isTepDeletedOnDpn) { + vpnInterfaceManager.updateVpnInterfaceOnTepDelete(vpnInterface, stateTunnelList, confTx, + operTx); + } + })))); return futures; } } private int getTunnelType(StateTunnelList stateTunnelList) { int tunTypeVal = 0; + if (stateTunnelList.getDstInfo() == null) { + return VpnConstants.ITMTunnelLocType.Invalid.getValue(); + } if (stateTunnelList.getDstInfo().getTepDeviceType() == TepTypeInternal.class) { tunTypeVal = VpnConstants.ITMTunnelLocType.Internal.getValue(); } else if (stateTunnelList.getDstInfo().getTepDeviceType() == TepTypeExternal.class) { @@ -564,31 +597,14 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas return del.getTransportType() == TunnelTypeMplsOverGre.class; } - private void programDcGwLoadBalancingGroup(StateTunnelList tunnelState, int addOrRemove) { + private void programDcGwLoadBalancingGroup(StateTunnelList tunnelState, int addOrRemove, boolean isTunnelUp) { IpAddress dcGwIp = tunnelState.getDstInfo().getTepIp(); - String dcGwIpAddress = String.valueOf(dcGwIp.getValue()); - List availableDcGws = getDcGwIps(); - BigInteger dpId = new BigInteger(tunnelState.getSrcInfo().getTepDeviceId()); - boolean isTunnelUp = TunnelOperStatus.Up == tunnelState.getOperState(); - fibManager.programDcGwLoadBalancingGroup(availableDcGws, dpId, dcGwIpAddress, addOrRemove, isTunnelUp, + String dcGwIpAddress = String.valueOf(dcGwIp.stringValue()); + Uint64 dpId = Uint64.valueOf(tunnelState.getSrcInfo().getTepDeviceId()).intern(); + fibManager.programDcGwLoadBalancingGroup(dpId, dcGwIpAddress, addOrRemove, isTunnelUp, tunnelState.getTransportType()); } - private List getDcGwIps() { - InstanceIdentifier dcGatewayIpListid = - InstanceIdentifier.builder(DcGatewayIpList.class).build(); - DcGatewayIpList dcGatewayIpListConfig = - MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid).orNull(); - if (dcGatewayIpListConfig == null) { - return Collections.EMPTY_LIST; - } - return dcGatewayIpListConfig.getDcGatewayIp() - .stream() - .filter(dcGwIp -> dcGwIp.getTunnnelType().equals(TunnelTypeMplsOverGre.class)) - .map(dcGwIp -> String.valueOf(dcGwIp.getIpAddress().getValue())).sorted() - .collect(toList()); - } - private boolean isTunnelInLogicalGroup(StateTunnelList stateTunnelList) { String ifaceName = stateTunnelList.getTunnelInterfaceName(); if (getTunnelType(stateTunnelList) == VpnConstants.ITMTunnelLocType.Internal.getValue()) {