From 606664bfb75258db9040dad990fd79e6fd6b047c Mon Sep 17 00:00:00 2001 From: Michal Cmarada Date: Mon, 16 Oct 2017 18:30:31 +0200 Subject: [PATCH] Fixes for DVR Data caching is simpler for smoother debugging. Code is totally not clean for because of of time. Fixes related to removing configuration were made Change-Id: Ibd436e6a7926b1ddb27b40444eeaaa8a3b7390c8 Signed-off-by: Michal Cmarada Signed-off-by: Tomas Cechvala --- .../vpp/mapper/processors/SubnetHandler.java | 1 + .../config/vpp_provider/impl/VppRenderer.java | 5 +- .../renderer/vpp/iface/InterfaceManager.java | 3 - .../vpp/lisp/LispStateCommandExecutor.java | 6 + .../renderer/vpp/lisp/LispStateManager.java | 439 +++++++++--------- .../event/manager/GbpSubnetEventManager.java | 6 +- .../lisp/flat/overlay/FlatOverlayManager.java | 430 ++++++++--------- .../flat/overlay/StaticRoutingHelper.java | 144 ++---- .../container/HostRelatedInfoContainer.java | 58 +++ .../lisp/info/container/states/LispState.java | 23 + .../container/states/PhysicalInterfaces.java | 5 + .../info/container/states/PortInterfaces.java | 12 +- .../info/container/states/PortRouteState.java | 14 +- .../info/container/states/RouteState.java | 4 + .../info/container/states/SubnetHolder.java | 20 +- .../info/container/states/SubnetState.java | 15 + .../lisp/info/container/states/VrfHolder.java | 12 + .../lisp/info/container/states/VrfState.java | 16 +- .../vpp/lisp/loopback/LoopbackManager.java | 325 ++++++------- .../vpp/lisp/util/ConfigManagerHelper.java | 78 +--- .../renderer/vpp/lisp/util/Constants.java | 2 +- .../vpp/listener/VppEndpointListener.java | 58 ++- .../vpp/policy/ForwardingManager.java | 7 +- .../renderer/vpp/util/VppIidFactory.java | 18 +- .../policy/VppRendererPolicyManagerTest.java | 11 +- 25 files changed, 912 insertions(+), 800 deletions(-) diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/SubnetHandler.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/SubnetHandler.java index 20f5768a0..dc7db94aa 100644 --- a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/SubnetHandler.java +++ b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/SubnetHandler.java @@ -68,6 +68,7 @@ public class SubnetHandler { DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, HandlerUtil.getInstanceIdentifier(gbpSubnet.getId()), rwTx); + DataStoreHelper.submitToDs(rwTx); } } } \ No newline at end of file diff --git a/renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java b/renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java index 47c1cd33e..ec403258c 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java +++ b/renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java @@ -147,11 +147,11 @@ public class VppRenderer implements AutoCloseable, BindingAwareProvider { Preconditions.checkNotNull(providerContext.getSALService(MountPointService.class)); mountDataProvider = new MountedDataBrokerProvider(mountService, dataBroker); VppNodeManager vppNodeManager = new VppNodeManager(dataBroker, providerContext, publicInterfaces); - EventBus dtoEventBus = new EventBus((exception, context) -> LOG.error("Could not dispatch event: {} to {}", context.getSubscriber(), context.getSubscriberMethod(), exception)); + vppEndpointListener = new VppEndpointListener(dataBroker, dtoEventBus); LispStateManager lispStateManager = new LispStateManager(mountDataProvider); - FlatOverlayManager flatOverlayManager = new FlatOverlayManager(dataBroker, mountDataProvider); + FlatOverlayManager flatOverlayManager = new FlatOverlayManager(dataBroker, mountDataProvider, vppEndpointListener); LoopbackManager loopbackManager = new LoopbackManager(mountDataProvider); interfaceManager = new InterfaceManager(mountDataProvider, dataBroker, flatOverlayManager); @@ -174,7 +174,6 @@ public class VppRenderer implements AutoCloseable, BindingAwareProvider { dtoEventBus.register(vppRendererPolicyManager); vppNodeListener = new VppNodeListener(dataBroker, vppNodeManager, dtoEventBus); - vppEndpointListener = new VppEndpointListener(dataBroker, dtoEventBus); rendererPolicyListener = new RendererPolicyListener(dataBroker, dtoEventBus); vppGbpSubnetListener = new GbpSubnetListener(dataBroker, dtoEventBus); registerToRendererManager(); diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java index 4ed20d3cf..9f7048092 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java @@ -254,9 +254,6 @@ public class InterfaceManager implements AutoCloseable { return Futures.immediateFailedFuture(new VppRendererProcessingException(message)); } - if (ConfigUtil.getInstance().isL3FlatEnabled()) { - flatOverlayManager.handleInterfaceDeleteForFlatOverlay(vppEndpoint); - } return deleteIfaceOnVpp(ifaceWithoutBdCommand, vppNodeIid, vppEndpoint); } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateCommandExecutor.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateCommandExecutor.java index 691596651..35f31f977 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateCommandExecutor.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateCommandExecutor.java @@ -37,6 +37,12 @@ public class LispStateCommandExecutor { return executeCommand(LispUtil.HOSTNAME_TO_IID.apply(hostName), lispStateCommand); } + public static boolean executeMergeCommand(String hostName, + AbstractLispCommand lispStateCommand) { + lispStateCommand.setOperation(General.Operations.MERGE); + return executeCommand(LispUtil.HOSTNAME_TO_IID.apply(hostName), lispStateCommand); + } + public static boolean executeDeleteCommand(InstanceIdentifier nodeIid, AbstractLispCommand lispStateCommand) { lispStateCommand.setOperation(General.Operations.DELETE); diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateManager.java index 704f34454..40c0aa5be 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/LispStateManager.java @@ -10,8 +10,11 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutionException; import javax.annotation.Nonnull; @@ -22,6 +25,7 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.LispCommandW import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispConfigCommandFailedException; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispNotFoundException; +import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay.FlatOverlayManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.EndpointHost; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.LispState; @@ -33,18 +37,22 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction import org.opendaylight.groupbasedpolicy.renderer.vpp.util.LispUtil; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; -import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; 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.nat.rev150908.nat.config.nat.instances.nat.instance.MappingTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.IpPrefixType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801.Gpe; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801.NativeForwardPathsTables; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801._native.forward.paths.tables._native.forward.paths.table.NativeForwardPath; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801.gpe.feature.data.grouping.GpeFeatureData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.EidTableGrouping; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.dp.subtable.grouping.LocalMappings; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.dp.subtable.grouping.local.mappings.LocalMapping; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.dp.subtable.grouping.local.mappings.local.mapping.Eid; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.eid.table.grouping.EidTable; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.eid.table.grouping.eid.table.VniTableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.eid.table.grouping.eid.table.vni.table.VrfSubtable; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.itr.remote.locator.sets.grouping.ItrRemoteLocatorSet; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.lisp.feature.data.grouping.LispFeatureData; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.locator.sets.grouping.LocatorSets; @@ -54,6 +62,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.map.resolvers.grouping.map.resolvers.MapResolver; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.map.servers.grouping.MapServers; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170911.map.servers.grouping.map.servers.MapServer; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; @@ -74,6 +83,9 @@ public class LispStateManager { public static final String DEFAULT_LOCATOR_SET_NAME_PREFIX = "LS"; public static final String DEFAULT_MAPPING_RECORD_NAME_PREFIX = "MR_"; + // Node ID, VRF ID, route count + private Map> vnisByHostname = new HashMap<>(); + public LispStateManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) { Preconditions.checkNotNull(mountedDataBrokerProvider, "MountedDataBrokerProvider found to be null!"); @@ -84,305 +96,281 @@ public class LispStateManager { } public synchronized void processCreateEndPoint(AddressEndpointWithLocation addressEp) { - try { - if (lispStateHelper.isMetadataPort(addressEp)) { - return; - } - EndpointHost endpointHost = lispStateHelper.getEndpointHostInformation(addressEp); - LispState lispStateOfHost = configureHostIfNeeded(endpointHost); + if (!addressEp.getAddressType().equals(IpPrefixType.class)) { + return; + } + Map intfcsByHostname = FlatOverlayManager.resolveIntfcsByHosts(addressEp); + + intfcsByHostname.forEach((hostname, interfaceName) -> { + try { + configureHostIfNeeded(hostname); - long vni = getVni(addressEp.getTenant().getValue()); - long vrf = vni; + long vni = getVni(addressEp.getTenant().getValue()); + long vrf = vni; - Eid eid = lispStateHelper.getEid(addressEp, vni); - String eidMappingName = lispStateHelper.constructEidMappingName(addressEp); + Eid eid = lispStateHelper.getEid(addressEp, vni); + String eidMappingName = lispStateHelper.constructEidMappingName(addressEp, interfaceName); - addVniSpecificConfigurationsIfNeeded(endpointHost, lispStateOfHost, vni, vrf); + addVniSpecificConfigurationsIfNeeded(hostname, vni, vrf); - if (lispStateHelper.getInterfaceIp(addressEp).getValue().equals(Constants.METADATA_IP)) { - return; + if (!addEidInEidTable(hostname, eid, eidMappingName)) { + LOG.warn("Failed to add Eid: {}, eidMappingName: {} to table on host: {}", eid, eidMappingName, hostname); + } + } catch (LispConfigCommandFailedException e) { + LOG.warn("Lisp endpoint configuration failed for address endpoint: {}", addressEp); } + }); - addEidOnHostIfNeeded(endpointHost, lispStateOfHost, eid, eidMappingName); - } catch (LispConfigCommandFailedException e) { - LOG.warn("Lisp endpoint configuration failed for address endpoint: {}", addressEp); - } - } - private void addEidOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfNode, Eid eid, - String eidMappingName) - throws LispConfigCommandFailedException { - if(!lispStateOfNode.eidSetContains(eid)) { - addEidInEidTable(endpointHost, lispStateOfNode, eid, eidMappingName); - } } - private synchronized LispState configureHostIfNeeded(EndpointHost endpointHost) + private synchronized void configureHostIfNeeded(String hostName) throws LispConfigCommandFailedException { - LispState lispStateOfHost = hostRelatedInfoContainer.getLispStateOfHost(endpointHost.getHostName()); - if (lispStateOfHost == null) { - LOG.debug("Configuring host {} for LISP", endpointHost.getHostName()); - lispStateOfHost = new LispState(); + if ((vnisByHostname.get(hostName) == null)) { + + LOG.debug("Configuring host {} for LISP", hostName); + try { - enableLispOnHost(endpointHost, lispStateOfHost); - enableGpeOnHostIfNeeded(endpointHost, lispStateOfHost); - addLocatorSetOnHost(endpointHost, lispStateOfHost); - addMapResolverOnHost(endpointHost, lispStateOfHost); - enableMapRegistrationOnHostIfNeeded(endpointHost, lispStateOfHost); + boolean lispEnabled = enableLispOnHost(hostName); + Optional gpeFeatureDataOptional = GbpNetconfTransaction.read(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), + LogicalDatastoreType.CONFIGURATION, VppIidFactory.getGpeFeatureDataIid(), + GbpNetconfTransaction.RETRY_COUNT); + + LOG.trace("configureHostIfNeeded -> GpeOnHostFeatureData: {}", gpeFeatureDataOptional); + + if (!gpeFeatureDataOptional.isPresent() || !gpeFeatureDataOptional.get().isEnable()) { + enableGpeOnHostIfNeeded(hostName); + LOG.trace("configureHostIfNeeded -> GpeOnHostFeatureData were cleared"); + } + + if (lispEnabled) { + addLocatorSetOnHost(hostName); + if (!addMapResolverOnHost(hostName)) { + LOG.warn("Failed to add MAP resolver for host: {}", hostName); + } + enableMapRegistrationOnHostIfNeeded(hostName); + vnisByHostname.computeIfAbsent(hostName, k -> Lists.newArrayList()); + } else { + LOG.warn("Failed to enable LISP or GPE on host: {}", hostName); + } - hostRelatedInfoContainer.setLispStateOfHost(endpointHost.getHostName(), lispStateOfHost); } catch (LispNotFoundException e) { LOG.warn("Lisp host configuration failed: ", e.getMessage()); throw new LispConfigCommandFailedException("Failed LISP configuration!"); } } - return lispStateOfHost; } - private void enableGpeOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfHost) - throws LispConfigCommandFailedException { - if (ConfigUtil.getInstance().isL3FlatEnabled()) { - enableGpeForHost(endpointHost, lispStateOfHost); - } + private boolean enableGpeOnHostIfNeeded(String hostName) { + return enableGpeForHost(hostName); } - private void enableMapRegistrationOnHostIfNeeded(EndpointHost endpointHost, LispState lispStateOfHost) + private void enableMapRegistrationOnHostIfNeeded(String hostName) throws LispConfigCommandFailedException { if (ConfigUtil.getInstance().isLispMapRegisterEnabled()) { - enableMapRegister(endpointHost); - addMapServer(endpointHost, lispStateOfHost); + enableMapRegister(hostName); + if (!addMapServer(hostName)) { + LOG.warn("Failed to add Map server for host: {}", hostName); + } } } - private void enableLispOnHost(EndpointHost endpointHost, LispState lispState) - throws LispConfigCommandFailedException { - LOG.debug("Enabling LISP on host {}", endpointHost.getHostName()); + private boolean enableLispOnHost(String hostName) { + LOG.debug("Enabling LISP on host {}", hostName); AbstractLispCommand lispEnableCommand = LispCommandWrapper.enableLisp(); - if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), lispEnableCommand)) { - lispState.setLispEnabled(true); - } else { - throw new LispConfigCommandFailedException("Lisp Enable Command failed execution!"); - } + return LispStateCommandExecutor.executePutCommand(hostName, lispEnableCommand); } - private void enableGpeForHost(EndpointHost endpointHost, LispState lispState) - throws LispConfigCommandFailedException { + private boolean enableGpeForHost(String hostName) { AbstractLispCommand gpeEnableCommand = LispCommandWrapper.enableGpe(); - if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), gpeEnableCommand)) { - lispState.setGpeEnabled(true); - } else { - throw new LispConfigCommandFailedException("GPE Enable Command failed execution!"); - } + return LispStateCommandExecutor.executeMergeCommand(hostName, gpeEnableCommand); } - private void addLocatorSetOnHost(EndpointHost endpointHost, LispState lispState) - throws LispNotFoundException, LispConfigCommandFailedException { + private void addLocatorSetOnHost(String hostName) throws LispNotFoundException, LispConfigCommandFailedException { try { - String locatorSetName = lispStateHelper.constructLocatorSetName(lispState.getLocatorCount()); + //TODO locator is set to constant value, it has to be investigated further + String locatorSetName = lispStateHelper.constructLocatorSetName(1); String lispDataInterfaceName = lispStateHelper - .getLispDataRlocInterfaceName(endpointHost.getHostName()).get(); + .getLispDataRlocInterfaceName(hostName).get(); AbstractLispCommand addLocatorSetCommand = LispCommandWrapper.addLocatorSet(locatorSetName, lispDataInterfaceName, DEFAULT_PRIORITY, DEFAULT_WEIGHT); - if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addLocatorSetCommand)) { - lispState.setLocIntfToLocSetNameMapping(lispDataInterfaceName, locatorSetName); + + if (LispStateCommandExecutor.executePutCommand(hostName, addLocatorSetCommand)) { + addExtraItrRlocLocatorSetIfNeeded(hostName, lispDataInterfaceName); } else { - throw new LispConfigCommandFailedException("Lisp add locator set failed for host " - + endpointHost.getHostName() + " and locator interface " + lispDataInterfaceName); + LOG.warn("Failed to write locator set: {} -> {} to host: {}", locatorSetName, lispDataInterfaceName, hostName); } - - addExtraItrRlocLocatorSetIfNeeded(endpointHost, lispDataInterfaceName); } catch (InterruptedException | ExecutionException e) { throw new LispNotFoundException("No interface with Ip Address found!"); } } - private void addExtraItrRlocLocatorSetIfNeeded(EndpointHost endpointHost, String lispDataInterfaceName) + private void addExtraItrRlocLocatorSetIfNeeded(String hostName, String lispDataInterfaceName) throws LispNotFoundException, LispConfigCommandFailedException { - String lispCpRlocInterfaceName = lispStateHelper.getLispCpRlocInterfaceName(endpointHost); - if (lispCpRlocInterfaceName == null - || lispCpRlocInterfaceName.isEmpty() + String lispCpRlocInterfaceName = lispStateHelper.getLispCpRlocInterfaceName(hostName); + if (lispCpRlocInterfaceName == null || lispCpRlocInterfaceName.isEmpty() || lispCpRlocInterfaceName.equals(lispDataInterfaceName)) { return; } - addItrLocatorSet(endpointHost, lispCpRlocInterfaceName); + addItrLocatorSet(hostName, lispCpRlocInterfaceName); } - private void addItrLocatorSet(EndpointHost endpointHost, String lispCpInterfaceName) + private void addItrLocatorSet(String hostName, String lispCpInterfaceName) throws LispNotFoundException, LispConfigCommandFailedException { String locatorSetName = lispStateHelper.constructLocatorSetNameForItrRloc(); AbstractLispCommand addLocatorSetCommand = LispCommandWrapper.addLocatorSet(locatorSetName, lispCpInterfaceName, DEFAULT_PRIORITY, DEFAULT_WEIGHT); - if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addLocatorSetCommand)) { + if (!LispStateCommandExecutor.executePutCommand(hostName, addLocatorSetCommand)) { throw new LispConfigCommandFailedException("Lisp add locator set failed for host " - + endpointHost.getHostName() + " and locator interface " + lispCpInterfaceName); - } - - AbstractLispCommand addItrRlocCommand = LispCommandWrapper.addItrRloc(locatorSetName); - if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addItrRlocCommand)) { - throw new LispConfigCommandFailedException("Lisp add Itr Rloc command failed for host " - + endpointHost.getHostName() + " and locator set " + locatorSetName); + + hostName + " and locator interface " + lispCpInterfaceName); + } else { + AbstractLispCommand addItrRlocCommand = LispCommandWrapper.addItrRloc(locatorSetName); + if (!LispStateCommandExecutor.executePutCommand(hostName, addItrRlocCommand)) { + throw new LispConfigCommandFailedException( + "Lisp add Itr Rloc command failed for host " + hostName + " and locator set " + locatorSetName); + } } } - private void addMapResolverOnHost(EndpointHost endpointHost, LispState lispState) - throws LispConfigCommandFailedException { + private boolean addMapResolverOnHost(String hostname) { IpAddress mapResolverIpAddress = ConfigUtil.getInstance().getOdlIp(); Preconditions.checkNotNull(mapResolverIpAddress, "Map Resolver ip not properly configured!"); AbstractLispCommand addMapResolverCommand = LispCommandWrapper. addMapResolver(mapResolverIpAddress); - if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addMapResolverCommand)) { - lispState.addInMapResolverSet(mapResolverIpAddress); - } else { - throw new LispConfigCommandFailedException("Lisp add map resolver for host " + endpointHost.getHostName() - + " failed for ODL ip " + mapResolverIpAddress); - } + return LispStateCommandExecutor.executePutCommand(hostname, addMapResolverCommand); } - private void enableMapRegister(EndpointHost endpointHost) + private void enableMapRegister(String hostName) throws LispConfigCommandFailedException { AbstractLispCommand enableMapRegisterCommand = LispCommandWrapper.enableMapRegister(); - if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), enableMapRegisterCommand)) { - throw new LispConfigCommandFailedException("Lisp enable mapregistration for host " - + endpointHost.getHostName() + " failed!"); + if (!LispStateCommandExecutor.executePutCommand(hostName, enableMapRegisterCommand)) { + throw new LispConfigCommandFailedException("Lisp enable map registration for host " + + hostName + " failed!"); } } - private void addMapServer(EndpointHost endpointHost, LispState lispState) throws LispConfigCommandFailedException { + private boolean addMapServer(String hostName) throws LispConfigCommandFailedException { IpAddress mapServerIpAddress = ConfigUtil.getInstance().getOdlIp(); Preconditions.checkNotNull(mapServerIpAddress, "Mapserver ip not properly configured!"); AbstractLispCommand addMapServerCommand = LispCommandWrapper.addMapServer(mapServerIpAddress); - if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addMapServerCommand)) { - lispState.addInMapServerSet(mapServerIpAddress); - } else { - throw new LispConfigCommandFailedException("Lisp add map server for host " + endpointHost.getHostName() - + " failed for ODL ip " + mapServerIpAddress); - } + return LispStateCommandExecutor.executePutCommand(hostName, addMapServerCommand); } - private void addVniSpecificConfigurationsIfNeeded(EndpointHost endpointHost, - LispState lispState, - long vni, long vrf) throws LispConfigCommandFailedException { - if (!lispState.isVniConfigured(vni)) { - addVniToVrfMapping(endpointHost, lispState, vni, vrf); - addGpeNativeForwardPath(endpointHost, vrf, - hostRelatedInfoContainer.getPhysicalInterfaceState(endpointHost.getHostName()) - .getIp(PhysicalInterfaces.PhysicalInterfaceType.PUBLIC)); + private void addVniSpecificConfigurationsIfNeeded(String hostName, long vni, long vrf) { + + if (vnisByHostname.get(hostName) != null && !vnisByHostname.get(hostName).contains(Long.valueOf(vni))) { + if (addVniToVrfMapping(hostName, vni, vrf)) { + if (!addGpeNativeForwardPath(hostName, vrf, hostRelatedInfoContainer.getPhysicalInterfaceState(hostName) + .getIp(PhysicalInterfaces.PhysicalInterfaceType.PUBLIC))) { + LOG.warn("Configure GPE native forward failed for host: {} and vni: {}", hostName, vni); + } + if (vnisByHostname.get(hostName) != null) { + vnisByHostname.get(hostName).add(vni); + } + } } } - private void addVniToVrfMapping(EndpointHost endpointHost, - LispState lispState, - long vni, long vrf) throws LispConfigCommandFailedException { + private boolean addVniToVrfMapping(String hostName, long vni, long vrf) { AbstractLispCommand addVniToVrfMapping = LispCommandWrapper.mapVniToVrf(vni, vrf); - if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addVniToVrfMapping)) { - lispState.addInVniSet(vni); - } else { - throw new LispConfigCommandFailedException("Lisp add vrf " + vrf +" for vni " +vni - + " command failed!"); - } + return (LispStateCommandExecutor.executePutCommand(hostName, addVniToVrfMapping)); } - private void addGpeNativeForwardPath(EndpointHost endpointHost, - long vrf, IpAddress nativeForwardIp) throws LispConfigCommandFailedException { + private boolean addGpeNativeForwardPath(String hostname, long vrf, IpAddress nativeForwardIp){ AbstractLispCommand addNativeForwardingIp = LispCommandWrapper.addNativeForwardEntry(vrf, nativeForwardIp); - if (!LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addNativeForwardingIp)) { - throw new LispConfigCommandFailedException("Lisp add native forwarding to ip " + addNativeForwardingIp - + " for vrf " + vrf + " command failed!"); - } + return LispStateCommandExecutor.executePutCommand(hostname, addNativeForwardingIp); } - private void addEidInEidTable(EndpointHost endpointHost, - LispState lispState, - Eid eid, - String eidMappingName) throws LispConfigCommandFailedException { + private boolean addEidInEidTable(String hostName, Eid eid, String eidMappingName) + throws LispConfigCommandFailedException { AbstractLispCommand addLocalMappingInEidTableCommand = LispCommandWrapper .addLocalMappingInEidTable(eidMappingName, eid, - lispStateHelper.getFirstLocatorSetName(lispState), + lispStateHelper.constructLocatorSetName(1), lispStateHelper.getDefaultHmacKey()); - if (LispStateCommandExecutor.executePutCommand(endpointHost.getHostName(), addLocalMappingInEidTableCommand)) { - lispState.addEidInEidSet(eid); - } else { - throw new LispConfigCommandFailedException("Lisp add local mapping for eid " + eid + "failed!"); - } + return LispStateCommandExecutor.executePutCommand(hostName, addLocalMappingInEidTableCommand); } public synchronized void processDeleteEndpoint(AddressEndpointWithLocation addressEp) { - try { - - if (lispStateHelper.isMetadataPort(addressEp)) { - return; - } - - EndpointHost endpointHost = lispStateHelper.getEndpointHostInformation(addressEp); + if (!addressEp.getAddressType().equals(IpPrefixType.class)) { + return; + } + Map intfcsByHostname = FlatOverlayManager.resolveIntfcsByHosts(addressEp); - LispState lispState = hostRelatedInfoContainer.getLispStateOfHost(endpointHost.getHostName()); + intfcsByHostname.forEach((hostname, interfaceName) -> { + try { - if (lispState == null) { - LOG.debug("Endpoint not configured for LISP. EndPoint: {}", addressEp); - } else { long vni = getVni(addressEp.getTenant().getValue()); Eid eid = lispStateHelper.getEid(addressEp, vni); - String eidMappingName = lispStateHelper.constructEidMappingName(addressEp); + String eidMappingName = lispStateHelper.constructEidMappingName(addressEp, interfaceName); + + if (!deleteEidFromLocalEidTableOfHost(hostname, eid, eidMappingName)){ + LOG.warn("Failed to delete Eid : {}, eidMappingName: {} on host: {}", eid, eidMappingName, hostname); + } + + Optional localMappingsOptional = + GbpNetconfTransaction.read(VppIidFactory.getNetconfNodeIid(new NodeId(hostname)), + LogicalDatastoreType.CONFIGURATION, VppIidFactory.getLocalMappings(new VniTableKey(vni)), + GbpNetconfTransaction.RETRY_COUNT); - deleteEidFromLocalEidTableOfHostIfNeeded(endpointHost, lispState, eid, eidMappingName); + if (!localMappingsOptional.isPresent() || localMappingsOptional.get().getLocalMapping() == null + || localMappingsOptional.get().getLocalMapping().size() == 0) { + + //remove mapping table for VNI + if (GbpNetconfTransaction.netconfSyncedDelete(VppIidFactory.getNetconfNodeIid(new NodeId(hostname)), + VppIidFactory.getVniTableIid(new VniTableKey(vni)), GbpNetconfTransaction.RETRY_COUNT)) { + Preconditions.checkNotNull(hostname); + vnisByHostname.get(hostname).remove(vni); + } + } + if (vnisByHostname.get(hostname).size() == 0) { + //safe to delete lisp + deleteLispStatesFromHost(hostname); + deleteNativeForwardPathsTables(hostname); + vnisByHostname.remove(hostname); - if (lispState.eidCount() == 0) { - deleteLispStatesFromHost(endpointHost); - deleteNativeForwardPathsTables(endpointHost); } + } catch (LispConfigCommandFailedException e) { + LOG.warn("Lisp command execution failed: {}", e.getMessage()); } - } catch (LispConfigCommandFailedException e) { - LOG.warn("Lisp command execution failed: {}", e.getMessage()); - } + }); } - private void deleteEidFromLocalEidTableOfHostIfNeeded(EndpointHost endpointHost, LispState lispState, Eid eid, - String eidMappingName) throws LispConfigCommandFailedException { - if (lispState.eidSetContains(eid)) { - deleteEidFromLocalEidTableOfHost(endpointHost, lispState, eid, eidMappingName); - } - } - private void deleteEidFromLocalEidTableOfHost(EndpointHost endpointHost, - LispState lispState, - Eid eid, - String eidMappingName) throws LispConfigCommandFailedException { + + private boolean deleteEidFromLocalEidTableOfHost(String hostName, Eid eid, String eidMappingName) + throws LispConfigCommandFailedException { long value = eid.getVirtualNetworkId().getValue(); AbstractLispCommand deleteLocalMappingCommand = LispCommandWrapper .deleteLocalMappingFromEidTable(eidMappingName, value); - if (LispStateCommandExecutor - .executeDeleteCommand(endpointHost.getHostName(), deleteLocalMappingCommand)) { - LOG.debug("Successfully deleted eid {} from host {}", eid, endpointHost.getHostName()); - lispState.deleteEid(eid); - } else { - throw new LispConfigCommandFailedException("Lisp delete local mapping command failed!"); - } + return (LispStateCommandExecutor.executeDeleteCommand(hostName, deleteLocalMappingCommand)); } - private void deleteLispStatesFromHost(EndpointHost endpointHost) throws LispConfigCommandFailedException { + private void deleteLispStatesFromHost(String hostname) throws LispConfigCommandFailedException { /*AbstractLispCommand deleteLispFeatureData = LispCommandWrapper.deleteLispFeatureData(); if (LispStateCommandExecutor.executeDeleteCommand(endpointHost.getHostName(), deleteLispFeatureData)) { hostRelatedInfoContainer.deleteLispStateOfHost(endpointHost.getHostName()); - LOG.debug("Deleted all lisp data for host {}", endpointHost.getHostName()); + LOG.debug("Deleted all lisp data {}, for host {}", + hostRelatedInfoContainer.getLispStateOfHost(endpointHost.getHostName()), endpointHost.getHostName()); } else { throw new LispConfigCommandFailedException("Lisp delete feature data command failed!"); - }*/ + } + */ //Todo workaround to delete only inside data not whole lisp-feature-data // (causes VPP to crash https://jira.fd.io/browse/HC2VPP-242) remove when fixed - InstanceIdentifier nodeIid = LispUtil.HOSTNAME_TO_IID.apply(endpointHost.getHostName()); + InstanceIdentifier nodeIid = LispUtil.HOSTNAME_TO_IID.apply(hostname); Optional lispOptional = GbpNetconfTransaction.read(nodeIid, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Lisp.class), GbpNetconfTransaction.RETRY_COUNT); @@ -392,42 +380,46 @@ public class LispStateManager { if (lispFeatureData == null || nodeIid == null) { return; } - - if (lispFeatureData.getEidTable() != null) { + LOG.trace("Removing all Eids from host: {}", hostname); + if (lispFeatureData.getEidTable() != null && lispFeatureData.getEidTable().getVniTable() != null) { + + lispFeatureData.getEidTable().getVniTable().forEach(vniTable -> { + if (vniTable.getVrfSubtable() != null && vniTable.getVrfSubtable().getLocalMappings() != null + && vniTable.getVrfSubtable().getLocalMappings().getLocalMapping() != null) + //remove all mapping from vni table + vniTable.getVrfSubtable().getLocalMappings().getLocalMapping().forEach(localMapping -> { + GbpNetconfTransaction.netconfSyncedDelete(nodeIid, + InstanceIdentifier.builder(Lisp.class) + .child(LispFeatureData.class) + .child(EidTable.class) + .child(VniTable.class, vniTable.getKey()) + .child(VrfSubtable.class) + .child(LocalMappings.class) + .child(LocalMapping.class, localMapping.getKey()) + .build(), + GbpNetconfTransaction.RETRY_COUNT); + }); + //remove EID VNI table + GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class) + .child(LispFeatureData.class) + .child(EidTable.class) + .child(VniTable.class, vniTable.getKey()) + .build(), GbpNetconfTransaction.RETRY_COUNT); + }); + //remove EID table GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class).child(LispFeatureData.class).child(EidTable.class).build(), GbpNetconfTransaction.RETRY_COUNT); - } - if (lispFeatureData.getMapServers() != null) { - GbpNetconfTransaction.netconfSyncedDelete(nodeIid, - InstanceIdentifier.builder(Lisp.class).child(LispFeatureData.class).child(MapServers.class).build(), - GbpNetconfTransaction.RETRY_COUNT); } - - if (lispFeatureData.getMapRegister() != null) { - GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class) - .child(LispFeatureData.class) - .child(MapRegister.class) - .build(), GbpNetconfTransaction.RETRY_COUNT); - } - - if (lispFeatureData.getMapResolvers() != null) { - GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class) - .child(LispFeatureData.class) - .child(MapResolvers.class) - .build(), GbpNetconfTransaction.RETRY_COUNT); - } - - String skipLocator = ""; + LOG.trace("Removing ItrRemoteLocatorSet from host: {}", hostname); if (lispFeatureData.getItrRemoteLocatorSet() != null) { - skipLocator = lispFeatureData.getItrRemoteLocatorSet().getRemoteLocatorSetName(); GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class) .child(LispFeatureData.class) .child(ItrRemoteLocatorSet.class) .build(), GbpNetconfTransaction.RETRY_COUNT); } - + LOG.trace("Removing all locators from host: {}", hostname); if (lispFeatureData.getLocatorSets() != null) { List locatorSetList = lispFeatureData.getLocatorSets().getLocatorSet(); @@ -436,32 +428,61 @@ public class LispStateManager { } for (LocatorSet locatorSet : locatorSetList) { - if (!skipLocator.equalsIgnoreCase(locatorSet.getName())) { GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class) .child(LispFeatureData.class) .child(LocatorSets.class) .child(LocatorSet.class, locatorSet.getKey()) .build(), GbpNetconfTransaction.RETRY_COUNT); - } } } + LOG.trace("Removing MapResolvers from host: {}", hostname); + if (lispFeatureData.getMapResolvers() != null) { + GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class) + .child(LispFeatureData.class) + .child(MapResolvers.class) + .build(), GbpNetconfTransaction.RETRY_COUNT); + } + LOG.trace("Removing MapServers from host: {}", hostname); + if (lispFeatureData.getMapServers() != null) { + GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class) + .child(LispFeatureData.class) + .child(MapServers.class) + .build(), GbpNetconfTransaction.RETRY_COUNT); + } + LOG.trace("Removing MapServers from host: {}", hostname); + if (lispFeatureData.getMapRegister() != null) { + GbpNetconfTransaction.netconfSyncedDelete(nodeIid, InstanceIdentifier.builder(Lisp.class) + .child(LispFeatureData.class) + .child(MapRegister.class) + .build(), GbpNetconfTransaction.RETRY_COUNT); + } + + LOG.trace("Removing all locators from host: {}", hostname); + + cleanLisp(hostname); } } - private void deleteNativeForwardPathsTables(EndpointHost endpointHost) + private boolean deleteNativeForwardPathsTables(String hostname) throws LispConfigCommandFailedException { AbstractLispCommand deleteNativeForwardPathsTables = LispCommandWrapper .deleteNativeForwardPathsTables(); - if (!LispStateCommandExecutor.executeDeleteCommand(endpointHost.getHostName(), - deleteNativeForwardPathsTables)) { - throw new LispConfigCommandFailedException("Delete Native Forward Paths Tables command failed!"); - } + return LispStateCommandExecutor.executeDeleteCommand(hostname, deleteNativeForwardPathsTables); } private long getVni(String tenantUuid) { return neutronTenantToVniMapper.getVni(tenantUuid); } + + public static void cleanLisp(String hostName) + throws LispConfigCommandFailedException { + if (LispStateCommandExecutor.executeDeleteCommand(hostName, LispCommandWrapper.deleteLispFeatureData())) { + LOG.debug("Deleted all lisp data for host {}",hostName); + } else { + throw new LispConfigCommandFailedException("Lisp delete feature data command failed!"); + } + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/event/manager/GbpSubnetEventManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/event/manager/GbpSubnetEventManager.java index 5169bcf1b..18c4436e6 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/event/manager/GbpSubnetEventManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/event/manager/GbpSubnetEventManager.java @@ -60,10 +60,12 @@ public class GbpSubnetEventManager { } private void processSubnetCreated(String subnetUuid, GbpSubnet subnetInfo) { - subnetUuidToGbpSubnetInfoMapper.addSubnetInfo(subnetUuid, subnetInfo); + //subnetUuidToGbpSubnetInfoMapper.addSubnetInfo(subnetUuid, subnetInfo); + loopbackManager.gbpSubnetCreated(subnetUuid, subnetInfo); } private void processSubnetDeleted(String subnetUuid) { - subnetUuidToGbpSubnetInfoMapper.removeSubnetInfo(subnetUuid); + //subnetUuidToGbpSubnetInfoMapper.removeSubnetInfo(subnetUuid); + loopbackManager.gbpSubnetdeleted(subnetUuid); } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/flat/overlay/FlatOverlayManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/flat/overlay/FlatOverlayManager.java index 997513fa7..0ed93636d 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/flat/overlay/FlatOverlayManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/flat/overlay/FlatOverlayManager.java @@ -8,26 +8,27 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import javax.annotation.Nonnull; +import org.apache.commons.net.util.SubnetUtils; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.StaticArpCommand; +import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppPathMapper; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.EndpointHost; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PhysicalInterfaces; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortInterfaces; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortRouteState; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.SubnetState; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfHolder; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfState; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.Constants; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.IpAddressUtil; +import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener; import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General; @@ -39,18 +40,28 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocol; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170917.VniReference; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.IpPrefixType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.TapCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.Routing; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.RoutingBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; + public class FlatOverlayManager { private static final Logger LOG = LoggerFactory.getLogger(FlatOverlayManager.class); @@ -59,107 +70,24 @@ public class FlatOverlayManager { private NeutronTenantToVniMapper neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance(); private HostRelatedInfoContainer hostRelatedInfoContainer = HostRelatedInfoContainer.getInstance(); + // Node ID, VRF ID, route count + private Map> vrfsByHostname = new HashMap<>(); private StaticRoutingHelper staticRoutingHelper; + private VppEndpointListener vppEndpointListener; public FlatOverlayManager(@Nonnull DataBroker dataBroker, - @Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) { + @Nonnull MountedDataBrokerProvider mountedDataBrokerProvider, + @Nonnull VppEndpointListener vppEndpointListener) { this.overlayHelper = new ConfigManagerHelper(mountedDataBrokerProvider); staticRoutingHelper = new StaticRoutingHelper(); this.dataBroker = dataBroker; + this.vppEndpointListener = vppEndpointListener; } public void configureEndpointForFlatOverlay(AddressEndpointWithLocation addressEp) { - if (!overlayHelper.hasRelativeLocations(addressEp)) { - configureInterfaceForFlatOverlay(addressEp); - addStaticArp(addressEp); - addStaticRoute(addressEp); - } else { - Ipv4Address metadataIp = overlayHelper.getInterfaceIp(addressEp); - Ipv4Prefix metadataIpPrefix = overlayHelper.getInterfaceIpAsPrefix(addressEp); - addressEp.getRelativeLocations().getExternalLocation().forEach(externalLocation -> { - String hostName = overlayHelper.getHostName(externalLocation).get(); - String metadataInterfaceName = overlayHelper.getInterfaceName(externalLocation).get(); - - long vrf = getVni(addressEp.getTenant().getValue()); - - String metadataSubnetUuid = Constants.METADATA_SUBNET_UUID; - - PortInterfaces portInterfacesOfHost = hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName); - - if (!portInterfacesOfHost.isInterfaceConfiguredForMetadata(metadataInterfaceName)) { - addInterfaceInVrf(hostName, metadataInterfaceName, vrf); - String physicalAddress = resolvePhysicalAddress(hostName, metadataInterfaceName); - addStaticArp(hostName, metadataInterfaceName, physicalAddress, metadataIp); - addStaticRoute(hostName, vrf, metadataSubnetUuid, metadataIp, metadataIpPrefix, - metadataInterfaceName); - portInterfacesOfHost.addInterfaceInMetadataInterfaceSet(metadataInterfaceName); - } - }); - } - } - - private String resolvePhysicalAddress(String hostName, String metadataInterfaceName) { - String physAddress = null; - Optional configOptional = - DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getVppRendererConfig(), - dataBroker.newReadOnlyTransaction()); - if (configOptional.isPresent() && configOptional.get().getVppEndpoint() != null) { - java.util.Optional vppEndpointOptional = configOptional.get().getVppEndpoint().stream() - .filter(vppEndpoint -> vppEndpoint.getVppNodeId().getValue().equals(hostName)) - .filter(vppEndpoint -> vppEndpoint.getVppInterfaceName().equals(metadataInterfaceName)) - .findFirst(); - if (vppEndpointOptional.isPresent() && vppEndpointOptional.get() - .getInterfaceTypeChoice() instanceof TapCase) { - TapCase tapCase = (TapCase) vppEndpointOptional.get().getInterfaceTypeChoice(); - physAddress = tapCase.getPhysicalAddress().getValue(); - LOG.trace("Resolved PhysicalAddress : {} for metadataInterfaceName: {}, on node: {}", physAddress - , metadataInterfaceName, hostName); - } else { - LOG.warn("PhysicalAddress was not resolved for metadataInterfaceName: {}, on node: {}", - metadataInterfaceName, hostName); - } - } - - return physAddress; - } - - public void handleEndpointDeleteForFlatOverlay(AddressEndpointWithLocation addressEp) { - if (overlayHelper.hasRelativeLocations(addressEp)) { - // okay to ignore - // routes will be deleted on interface delete - return; - } - deleteStaticRoute(addressEp); - } - - public void handleInterfaceDeleteForFlatOverlay(VppEndpoint vppEndpoint) { - String hostName = vppEndpoint.getVppNodeId().getValue(); - String interfaceName = vppEndpoint.getVppInterfaceName(); - LOG.trace("handleInterfaceDeleteForFlatOverlay: hostname: {}, interfaceName: {}", hostName,interfaceName); - - Preconditions.checkNotNull(hostName, "Hostname cannot be null when deleting Interface"); - Preconditions.checkNotNull(interfaceName, "InterfaceName cannot be null when deleting Interface"); - - staticRoutingHelper.deleteAllRoutesThroughInterface(hostName, interfaceName); - - PortInterfaces portInterfaces = hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName); - portInterfaces.removePortInterface(interfaceName); - } - - private void configureInterfaceForFlatOverlay(AddressEndpointWithLocation addressEp) { - addInterfaceInVrf(addressEp); - } - - private void addInterfaceInVrf(AddressEndpointWithLocation addressEp) { - EndpointHost endpointHost = overlayHelper.getEndpointHostInformation(addressEp); - long vni = getVni(addressEp.getTenant().getValue()); - long vrf = vni; - Optional interfaceNameOptional = overlayHelper.getInterfaceName(addressEp); - - Preconditions.checkArgument(interfaceNameOptional.isPresent()); - - addInterfaceInVrf(endpointHost.getHostName(), interfaceNameOptional.get(), vrf); + addStaticRoute(addressEp); + addStaticArpAndInfcsToVrf(addressEp); } private void addInterfaceInVrf(String hostName, String interfaceName, long vrf) { @@ -178,9 +106,7 @@ public class FlatOverlayManager { } } - private boolean putVrfInInterface(String hostName, - String interfaceName, - Long vrf) { + private boolean putVrfInInterface(String hostName, String interfaceName, Long vrf) { InstanceIdentifier iid = VppIidFactory.getRoutingIid(new InterfaceKey(interfaceName)); RoutingBuilder builder = new RoutingBuilder(); builder.setIpv4VrfId(vrf); @@ -188,45 +114,36 @@ public class FlatOverlayManager { builder.build(), GbpNetconfTransaction.RETRY_COUNT); } - private void addStaticArp(AddressEndpointWithLocation addressEp) { - String hostName = overlayHelper.getHostName(addressEp).get(); - String physicalAddress = overlayHelper.getPhysicalAddress(addressEp); - Optional interfaceNameOptional = overlayHelper.getInterfaceName(addressEp); - - Preconditions.checkArgument(interfaceNameOptional.isPresent()); - - String interfaceName = interfaceNameOptional.get(); - - addStaticArp(hostName, interfaceName, physicalAddress, overlayHelper.getInterfaceIp(addressEp)); - } - - private void addStaticArp(String hostName, - String interfaceName, - String physicalAddress, - Ipv4Address ipv4Address) { - Ipv4AddressNoZone ip = new Ipv4AddressNoZone(ipv4Address); - if (physicalAddress == null || physicalAddress.isEmpty()) { - LOG.warn("Cannot add static arp for interface {}, ip={}, because physical address is null or empty", - interfaceName, ip, physicalAddress); + private void addStaticArpAndInfcsToVrf(AddressEndpointWithLocation addressEp) { + if (!addressEp.getAddressType().equals(IpPrefixType.class)) { return; } - InterfaceKey interfaceKey = new InterfaceKey(interfaceName); - if (!putStaticArp(hostName, - interfaceKey, - new PhysAddress(physicalAddress), - ip)) { - LOG.warn("Failed to put static arp with interface {} for ip={} and physical-address={}", - interfaceName, ip, physicalAddress); - } else { - LOG.debug("Added Static arp ({} {}) in host {} for interface {}", ip, physicalAddress, hostName, - interfaceName); - } + Map intfcsByHostname = resolveIntfcsByHosts(addressEp); + ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction(); + Optional cfg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getVppRendererConfig(), readTx); + readTx.close(); + intfcsByHostname.entrySet().forEach(intfcByHost -> { + if (cfg.isPresent() && !cfg.get().getVppEndpoint().isEmpty()) { + java.util.Optional foundVpp = cfg.get() + .getVppEndpoint() + .stream() + .filter(vpp -> vpp.getVppInterfaceName().equals(intfcByHost.getValue())) + .findFirst(); + if (!foundVpp.isPresent()) { + return; + } + Ipv4Address ipv4 = ConfigManagerHelper.getInterfaceIp(addressEp); + putStaticArp(intfcByHost.getKey(), new InterfaceKey(intfcByHost.getValue()), + new PhysAddress(foundVpp.get().getAddress()), new Ipv4AddressNoZone(ipv4)); + addInterfaceInVrf(intfcByHost.getKey(), intfcByHost.getValue(), + getVni(addressEp.getTenant().getValue())); + } + }); } - private boolean putStaticArp(String hostName, - InterfaceKey interfaceKey, - PhysAddress physAddress, - Ipv4AddressNoZone ip) { + private boolean putStaticArp(String hostName, InterfaceKey interfaceKey, PhysAddress physAddress, + Ipv4AddressNoZone ip) { StaticArpCommand.StaticArpCommandBuilder staticArpCommandBuilder = new StaticArpCommand.StaticArpCommandBuilder(); @@ -240,128 +157,193 @@ public class FlatOverlayManager { } private void addStaticRoute(AddressEndpointWithLocation addressEp) { - String hostName = overlayHelper.getHostName(addressEp).get(); + //TODO caller method + Optional routeId = routeId(addressEp); + if(!routeId.isPresent()) { + return; + } + + //TODO workaround for interfaces that do not exist anymore + List childs = addressEp.getChildEndpoint(); + if (childs != null) { + for (ChildEndpoint child : childs) { + child.getAddress(); + child.getContextId(); + VppEndpointKey vppEndpointKey = new VppEndpointKey(child.getAddress(), child.getAddressType(), + child.getContextId(), child.getContextType()); + ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction(); + Optional vppEp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getVppRendererConfig().child(VppEndpoint.class, vppEndpointKey), rTx); + rTx.close(); + if (!vppEp.isPresent()) { + LOG.error("Failed to add route for endpoint {}. Interface not created yet.", addressEp); + return; + } + } + } + + Map hostnamesAndIntfcs = resolveIntfcsByHosts(addressEp); long vni = getVni(addressEp.getTenant().getValue()); long vrf = vni; - String portSubnetUuid = overlayHelper.getSubnet(addressEp); + hostnamesAndIntfcs.forEach((hostname, outgoingInterfaceName) -> { - String outgoingInterfaceName = overlayHelper.getInterfaceName(addressEp).get(); - Ipv4Address ipWithoutPrefix = overlayHelper.getInterfaceIp(addressEp); + Ipv4Address ipWithoutPrefix = ConfigManagerHelper.getInterfaceIp(addressEp); - if (overlayHelper.isMetadataPort(addressEp)) { - //override original port subnet to handle the Absolute location case of address endpoint - portSubnetUuid = Constants.METADATA_SUBNET_UUID; - } - - Ipv4Prefix ipv4Prefix = overlayHelper.getInterfaceIpAsPrefix(addressEp); - - addStaticRoute(hostName, vrf, portSubnetUuid, ipWithoutPrefix, ipv4Prefix, outgoingInterfaceName); + Ipv4Prefix ipv4Prefix = overlayHelper.getInterfaceIpAsPrefix(addressEp); + LOG.trace("Adding static route for addressEp: {}", addressEp); + addStaticRoute(routeId.get(), hostname, vrf, ipWithoutPrefix, ipv4Prefix, outgoingInterfaceName); + }); } - private void addStaticRoute(String hostName, long vrfId, String hostIpSubnetUuid, - Ipv4Address ipWithoutPrefix, Ipv4Prefix ipv4Prefix, String outgoingInterfaceName) { - - VrfHolder vrfHolderOfHost = hostRelatedInfoContainer.getVrfStateOfHost(hostName); - - if (!vrfHolderOfHost.hasVrf(vrfId)) { - if (!staticRoutingHelper.addRoutingProtocolForVrf(LispUtil.HOSTNAME_TO_IID.apply(hostName), vrfId, - vrfHolderOfHost)) { - LOG.warn("Failed to add Routing protocol for host {} and vrf {}!", hostName, vrfId); + public static Map resolveIntfcsByHosts(AddressEndpointWithLocation addressEp) { + Map hostnamesAndIntfcs = new HashMap<>(); + if (addressEp.getRelativeLocations() != null + && addressEp.getRelativeLocations().getExternalLocation() != null) { + LOG.trace("deleteStaticRoutingEntry -> addresEp locations: {}", addressEp.getRelativeLocations().getExternalLocation()); + addressEp.getRelativeLocations().getExternalLocation().forEach(externalLocation -> { + Optional interfaceOptional = + VppPathMapper.interfacePathToInterfaceName(externalLocation.getExternalNodeConnector()); + if (interfaceOptional.isPresent()) { + hostnamesAndIntfcs.put( + externalLocation.getExternalNodeMountPoint().firstKeyOf(Node.class).getNodeId().getValue(), + interfaceOptional.get()); + } else { + LOG.warn("Couldn't resolve interface name for addrEP: {}", addressEp); + } + }); + } else if (addressEp.getAbsoluteLocation() != null && addressEp.getAbsoluteLocation().getLocationType() != null + && addressEp.getAbsoluteLocation().getLocationType() instanceof ExternalLocationCase) { + ExternalLocationCase externalLocationCase = + (ExternalLocationCase) addressEp.getAbsoluteLocation().getLocationType(); + LOG.trace("deleteStaticRoutingEntry -> addresEp location: {}", externalLocationCase); + Optional interfaceOptional = + VppPathMapper.interfacePathToInterfaceName(externalLocationCase.getExternalNodeConnector()); + if (interfaceOptional.isPresent()) { + hostnamesAndIntfcs.put( + externalLocationCase.getExternalNodeMountPoint().firstKeyOf(Node.class).getNodeId().getValue(), + interfaceOptional.get()); } else { + LOG.warn("Couldn't resolve interface name for addrEP: {}", addressEp); + } + } + return hostnamesAndIntfcs; + } + + private boolean addStaticRoute(Long routeId, String hostName, long vrfId, Ipv4Address ipWithoutPrefix, + Ipv4Prefix ipv4Prefix, String outgoingInterfaceName) { + if (vrfsByHostname.get(hostName) == null || !vrfsByHostname.get(hostName).keySet().contains(vrfId)) { + if (staticRoutingHelper.addRoutingProtocolForVrf(LispUtil.HOSTNAME_TO_IID.apply(hostName), vrfId)) { addStaticRouteToPublicInterface(hostName, vrfId); + countPlusPlus(hostName, vrfId); } } + if (staticRoutingHelper.addSingleStaticRouteInRoutingProtocol(routeId, hostName, vrfId, ipWithoutPrefix, + ipv4Prefix, outgoingInterfaceName, null)) { + countPlusPlus(hostName, vrfId); + return true; + } + return false; + } - VrfState vrfStateOfVrfId = vrfHolderOfHost.getVrfState(vrfId); + private void countPlusPlus(String hostName, Long vrfId) { + if (vrfsByHostname.get(hostName) == null || vrfsByHostname.get(hostName).get(vrfId) == null) { + HashMap newEntry = new HashMap<>(); + newEntry.put(vrfId, 1L); + vrfsByHostname.put(hostName, newEntry); + } else { + Long count = vrfsByHostname.get(hostName).get(vrfId); + HashMap newEntry = new HashMap<>(); + newEntry.put(vrfId, count + 1); + vrfsByHostname.put(hostName, newEntry); + } + } - if (vrfStateOfVrfId.getSubnetHolder().getSubnetState(hostIpSubnetUuid).isIpPresent(ipWithoutPrefix)) { - LOG.info("Ip already exists in host {} vrf {} ip {}", hostName, vrfId, ipWithoutPrefix); - return; + private void countMinusMinus(String hostName, Long vrfId) { + if (vrfsByHostname.get(hostName) != null && vrfsByHostname.get(hostName).get(vrfId) != null) { + Long count = vrfsByHostname.get(hostName).get(vrfId); + HashMap newEntry = new HashMap<>(); + newEntry.put(vrfId, count - 1); + vrfsByHostname.put(hostName, newEntry); } + } - if (!staticRoutingHelper.addSingleStaticRouteInRoutingProtocol(hostName, vrfId, hostIpSubnetUuid, - ipWithoutPrefix, ipv4Prefix, outgoingInterfaceName, null)) { - LOG.warn("Failed to add routing ({} via {}) in vrf {} in compute host {}!", - ipv4Prefix, outgoingInterfaceName, vrfId, hostName); - } else { - LOG.debug("Added route ({} via {}) in vrf {} in compute host {}", - ipv4Prefix, outgoingInterfaceName, vrfId, hostName); + private Long getRouteCount(String hostName, Long vrfId) { + if (vrfsByHostname.get(hostName) != null && vrfsByHostname.get(hostName).get(vrfId) != null) { + return vrfsByHostname.get(hostName).get(vrfId); } + return 0L; } private void addStaticRouteToPublicInterface(String hostName, long vrfId) { LOG.trace("addStaticRouteToPublicInterface, hostname: {}, vrfId: {}", hostName, vrfId); - Ipv4Address physicalInterfaceIp = hostRelatedInfoContainer - .getPhysicalInterfaceState(hostName) - .getIp(PhysicalInterfaces.PhysicalInterfaceType.PUBLIC).getIpv4Address(); - String interfaceName = hostRelatedInfoContainer - .getPhysicalInterfaceState(hostName) - .getName(PhysicalInterfaces.PhysicalInterfaceType.PUBLIC); - + Ipv4Address physicalInterfaceIp = hostRelatedInfoContainer.getPhysicalInterfaceState(hostName) + .getIp(PhysicalInterfaces.PhysicalInterfaceType.PUBLIC) + .getIpv4Address(); + String interfaceName = hostRelatedInfoContainer.getPhysicalInterfaceState(hostName) + .getName(PhysicalInterfaces.PhysicalInterfaceType.PUBLIC); if (interfaceName != null && !interfaceName.isEmpty()) { LOG.trace("Adding Public interface route. hostname: {}, VrfId: {}, Ip: {}, Gw: {}, InterfaceName: {}.", - hostName, vrfId, physicalInterfaceIp, null, interfaceName); - if (!staticRoutingHelper.addSingleStaticRouteInRoutingProtocol(hostName, vrfId, - Constants.PUBLIC_SUBNET_UUID, null, IpAddressUtil.toIpV4Prefix(physicalInterfaceIp), - interfaceName, new VniReference(RoutingManager.DEFAULT_TABLE))) { + hostName, vrfId, physicalInterfaceIp, null, interfaceName); + if (!staticRoutingHelper.addSingleStaticRouteInRoutingProtocol(0L, hostName, vrfId, physicalInterfaceIp, + IpAddressUtil.toIpV4Prefix(physicalInterfaceIp), interfaceName, + new VniReference(RoutingManager.DEFAULT_TABLE))) { LOG.warn("Failed to add route for physical interface in vrf {} compute host {}", vrfId, hostName); } else { - LOG.debug("Added route for physical interface {} in vrf {}", interfaceName, vrfId); + LOG.debug("addStaticRouteToPublicInterface -> Added route to public intf ({} via {}) in vrf {} in compute host {}", + IpAddressUtil.toIpV4Prefix(physicalInterfaceIp), interfaceName, vrfId, hostName); } } } - private void deleteStaticRoute(AddressEndpointWithLocation addressEp) { - String hostName = overlayHelper.getHostName(addressEp).get(); - String interfaceName = overlayHelper.getInterfaceName(addressEp).get(); - - long vni = getVni(addressEp.getTenant().getValue()); - long vrfId = vni; - - String ipSubnetUuid = overlayHelper.getSubnet(addressEp); - - if (overlayHelper.isMetadataPort(addressEp)) { - //override original port subnet to handle the Absolute location case of address endpoint - ipSubnetUuid = Constants.METADATA_SUBNET_UUID; - } - - Ipv4Address ipWithoutPrefix = overlayHelper.getInterfaceIp(addressEp); - - PortRouteState portRouteState = hostRelatedInfoContainer - .getPortInterfaceStateOfHost(hostName) - .getPortRouteState(interfaceName); - if (portRouteState == null) { - LOG.warn("Port route state is null, it has been deleted already. Skip delete for addresEp: {}.", addressEp); - return; + private Optional routeId(AddressEndpointWithLocation addressEp) { + if (!addressEp.getAddressType().equals(IpPrefixType.class) || !addressEp.getAddress().contains("/")) { + return Optional.absent(); } + String ipAddress = addressEp.getAddress().split("/")[0]; + SubnetUtils subnet = new SubnetUtils(addressEp.getAddress()); + Long routeId = Integer.toUnsignedLong(subnet.getInfo().asInteger(ipAddress)); + return Optional.of(routeId); + } - SubnetState subnetState = hostRelatedInfoContainer - .getVrfStateOfHost(hostName) - .getVrfState(vrfId) - .getSubnetHolder() - .getSubnetState(ipSubnetUuid); - - if (!subnetState.isIpPresent(ipWithoutPrefix)) { - LOG.debug("Route {} already deleted from vrf {} of host {}", ipWithoutPrefix, vrfId, hostName); + public void deleteStaticRoutingEntry(AddressEndpointWithLocation addressEp) { + //TODO create + Optional routeId = routeId(addressEp); + if(!routeId.isPresent()) { return; } + long vni = getVni(addressEp.getTenant().getValue()); + long vrfId = vni; + Map hostnamesAndIntfcs = resolveIntfcsByHosts(addressEp); + LOG.trace("deleteStaticRoutingEntry -> addresEp locations: {}", addressEp); + hostnamesAndIntfcs.entrySet().forEach(intfcsByHost -> { + LOG.trace("deleteStaticRoutingEntry -> Deleting addresEp: {} for interface: {}, on node: {}", addressEp.getKey(), intfcsByHost.getValue(), intfcsByHost.getKey()); + Ipv4Address ipWithoutPrefix = ConfigManagerHelper.getInterfaceIp(addressEp); + if (!staticRoutingHelper.deleteSingleStaticRouteFromRoutingProtocol(intfcsByHost.getKey(), vrfId, routeId.get())) { + LOG.warn("Failed to delete route ({} via {}) from vrf {} from host{}", ipWithoutPrefix, + intfcsByHost.getValue(), vrfId, intfcsByHost); + } else { + LOG.trace("deletedStaticRoutingEntry -> Deleted addresEp: {} for interface: {}, on node: {}", addressEp.getKey(), intfcsByHost.getValue(), intfcsByHost.getKey()); + countMinusMinus(intfcsByHost.getKey(), vrfId); + if (getRouteCount(intfcsByHost.getKey(), vrfId) <= 1) { + LOG.info("deletedStaticRoutingEntry -> Removing route to public int from VRF {}", vrfId); + staticRoutingHelper.deleteSingleStaticRouteFromRoutingProtocol(intfcsByHost.getKey(), vrfId, 0L); + InstanceIdentifier protocol = + VppIidFactory.getRoutingInstanceIid(StaticRoutingHelper.getRoutingProtocolName(vrfId)); + if(GbpNetconfTransaction.netconfSyncedDelete( + VppIidFactory.getNetconfNodeIid(new NodeId(intfcsByHost.getKey())), protocol, + GbpNetconfTransaction.RETRY_COUNT)) { + vrfsByHostname.get(intfcsByHost.getKey()).remove(vrfId); + } + } + LOG.trace("deleteStaticRoutingEntry -> flushPendingVppEndpoint for addresEp: {}", addressEp); + hostRelatedInfoContainer.deleteRouteFromIntfc(intfcsByHost.getKey(), intfcsByHost.getValue(), routeId.get()); + vppEndpointListener.flushPendingVppEndpoint(intfcsByHost.getKey(), intfcsByHost.getValue()); + LOG.debug("Delete Static Route ({} via {}) from vrf {} from host {}", ipWithoutPrefix, + intfcsByHost.getValue(), vrfId, intfcsByHost); + } + }); - long targetRouteId = portRouteState.getRouteIdOfIp(ipWithoutPrefix); - - if (!staticRoutingHelper.deleteSingleStaticRouteFromRoutingProtocol(hostName, - vrfId, - interfaceName, - targetRouteId)) { - LOG.warn("Failed to delete route ({} via {}) from vrf {} from host{}", - ipWithoutPrefix, interfaceName, vrfId, hostName); - - } else { - portRouteState.removeIp(ipWithoutPrefix); - subnetState.removeIp(ipWithoutPrefix); - LOG.debug("Delete Static Route ({} via {}) from vrf {} from host {}", - ipWithoutPrefix, interfaceName, vrfId, hostName); - } } public long getVni(String tenantUuid) { diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/flat/overlay/StaticRoutingHelper.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/flat/overlay/StaticRoutingHelper.java index 9a590352f..12659c504 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/flat/overlay/StaticRoutingHelper.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/flat/overlay/StaticRoutingHelper.java @@ -12,12 +12,15 @@ import com.google.common.base.Preconditions; import java.util.Collections; import java.util.List; +import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager; +import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispConfigCommandFailedException; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortInterfaces; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortRouteState; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfHolder; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfState; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.Constants; +import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.IpAddressUtil; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; @@ -46,17 +49,15 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class StaticRoutingHelper { +public class StaticRoutingHelper { private static final Logger LOG = LoggerFactory.getLogger(StaticRoutingHelper.class); private HostRelatedInfoContainer hostRelatedInfoContainer = HostRelatedInfoContainer.getInstance(); - synchronized boolean addRoutingProtocolForVrf(InstanceIdentifier nodeIid, long vrfId, - VrfHolder vrfHolderOfHost) { - String routingProtocolName = getRoutingProtocolName(vrfId); + synchronized boolean addRoutingProtocolForVrf(InstanceIdentifier nodeIid, long vrfId) { RoutingProtocolBuilder builder = new RoutingProtocolBuilder(); - builder.setKey(new RoutingProtocolKey(routingProtocolName)); - builder.setName(routingProtocolName); + builder.setKey(getRoutingProtocolName(vrfId)); + builder.setName(getRoutingProtocolName(vrfId).getName()); builder.setType(Static.class); builder.setDescription(Constants.DEFAULT_ROUTING_DESCRIPTION); RoutingProtocolVppAttrBuilder vppAugmentationBuilder = new RoutingProtocolVppAttrBuilder(); @@ -71,125 +72,66 @@ class StaticRoutingHelper { .getRoutingInstanceIid(builder.getKey()); if (GbpNetconfTransaction.netconfSyncedWrite(nodeIid, iid, builder.build(), GbpNetconfTransaction.RETRY_COUNT)) { - vrfHolderOfHost.initializeVrfState(vrfId, routingProtocolName); return true; } - return false; } - synchronized boolean addSingleStaticRouteInRoutingProtocol(String hostName, long portVrfId, String portSubnetUuid, - Ipv4Address nextHopAddress, Ipv4Prefix ipPrefix, String outgoingInterface, VniReference secondaryVrf) { + synchronized boolean addSingleStaticRouteInRoutingProtocol(Long routeId, String hostName, long portVrfId, + Ipv4Address nextHopAddress, Ipv4Prefix ipPrefix, String outgoingInterface, VniReference secondaryVrf) { RouteBuilder builder = new RouteBuilder(); - - VrfState hostVrfStateForPortVrf = hostRelatedInfoContainer - .getVrfStateOfHost(hostName) - .getVrfState(portVrfId); - - PortInterfaces hostPortInterfaces = hostRelatedInfoContainer - .getPortInterfaceStateOfHost(hostName); - - if (!hostPortInterfaces.isRoutingContextForInterfaceInitialized(outgoingInterface)) { - hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName). - initializeRoutingContextForInterface(outgoingInterface, portVrfId); - } - - Preconditions.checkNotNull(hostVrfStateForPortVrf, "Vrf has not been initialized yet"); - - long routeId = hostVrfStateForPortVrf.getNextRouteId(); - builder.setId(routeId); builder.setDestinationPrefix(ipPrefix); builder.setKey(new RouteKey(builder.getId())); if (secondaryVrf != null) { - builder.setNextHopOptions(new TableLookupBuilder().setTableLookupParams( - new TableLookupParamsBuilder().setSecondaryVrf(secondaryVrf).build()).build()); + builder.setNextHopOptions(new TableLookupBuilder() + .setTableLookupParams(new TableLookupParamsBuilder().setSecondaryVrf(secondaryVrf).build()).build()); } else { - builder.setNextHopOptions( - new SimpleNextHopBuilder().setNextHop(nextHopAddress).setOutgoingInterface(outgoingInterface).build()); + builder.setNextHopOptions(new SimpleNextHopBuilder().setNextHop(nextHopAddress) + .setOutgoingInterface(outgoingInterface) + .build()); } + String protocolName = Constants.ROUTING_PROTOCOL_NAME_PREFIX + String.valueOf(portVrfId); List routes = Collections.singletonList(builder.build()); - Ipv4 ipv4Route = new Ipv4Builder().setRoute(routes).build(); - - InstanceIdentifier iid = VppIidFactory - .getRoutingInstanceIid(new RoutingProtocolKey(hostVrfStateForPortVrf.getProtocolName())) - .child(StaticRoutes.class) - .augmentation(StaticRoutes1.class) - .child(Ipv4.class); - - RoutingProtocolKey routingProtocolKey = new RoutingProtocolKey(hostVrfStateForPortVrf.getProtocolName()); - boolean routingProtocol = - GbpNetconfTransaction.netconfSyncedMerge(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), - VppIidFactory.getRoutingInstanceIid(routingProtocolKey), - new RoutingProtocolBuilder().setKey(routingProtocolKey).setType(Static.class).build(), - GbpNetconfTransaction.RETRY_COUNT); - - if (routingProtocol && GbpNetconfTransaction.netconfSyncedMerge( - VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), iid, ipv4Route, GbpNetconfTransaction.RETRY_COUNT)) { - hostVrfStateForPortVrf.addNewPortIpInVrf(portSubnetUuid, nextHopAddress); - hostPortInterfaces.addRouteToPortInterface(outgoingInterface, portSubnetUuid, nextHopAddress, routeId); + RoutingProtocolKey routingProtocolKey = new RoutingProtocolKey(protocolName); + InstanceIdentifier iid = VppIidFactory.getRoutingInstanceIid(routingProtocolKey) + .child(StaticRoutes.class) + .augmentation(StaticRoutes1.class) + .child(Ipv4.class); + boolean txResult = + GbpNetconfTransaction.netconfSyncedMerge(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), + VppIidFactory.getRoutingInstanceIid(routingProtocolKey), + new RoutingProtocolBuilder().setKey(routingProtocolKey).setType(Static.class).build(), + GbpNetconfTransaction.RETRY_COUNT); + + if (txResult && GbpNetconfTransaction.netconfSyncedMerge(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), + iid, ipv4Route, GbpNetconfTransaction.RETRY_COUNT)) { + hostRelatedInfoContainer.addRouteToIntfc(hostName, outgoingInterface, routeId); + LOG.trace("addSingleStaticRouteInRoutingProtocol -> Route added for host: {}: {}", hostName, ipv4Route); return true; } - return false; } - synchronized boolean deleteSingleStaticRouteFromRoutingProtocol(String hostName, long vrfId, - String outgoingInterfaceName, Long routeId) { - VrfState vrfState = hostRelatedInfoContainer.getVrfStateOfHost(hostName).getVrfState(vrfId); - - Preconditions.checkNotNull(vrfState, "Vrf has not been initialized"); + public synchronized static boolean deleteSingleStaticRouteFromRoutingProtocol(String hostName, long vrfId, Long routeId) { + LOG.trace("deleteSingleStaticRouteFromRoutingProtocol -> deleting route. id: {}, vrf: {}, hostName: {}", routeId, vrfId, hostName); + String protocolName = Constants.ROUTING_PROTOCOL_NAME_PREFIX + vrfId; InstanceIdentifier iid = VppIidFactory - .getRoutingInstanceIid(new RoutingProtocolKey(vrfState.getProtocolName())) - .child(StaticRoutes.class) - .augmentation(StaticRoutes1.class) - .child(Ipv4.class) - .child(Route.class, new RouteKey(routeId)); - - if (!GbpNetconfTransaction.netconfSyncedDelete(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), iid, - GbpNetconfTransaction.RETRY_COUNT)) { - LOG.warn("Route delete failed for interface {} from {}", outgoingInterfaceName, hostName); - return false; - } - return true; - } - - synchronized void deleteAllRoutesThroughInterface(String hostName, String outgoingInterfaceName) { - PortRouteState portRouteState = hostRelatedInfoContainer - .getPortInterfaceStateOfHost(hostName) - .getPortRouteState(outgoingInterfaceName); - - long vrfId = hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName) - .getInterfaceVrfId(outgoingInterfaceName); - if(vrfId == -1) { - LOG.error("VrfID was not resolved when removing routes from interface. hostname: {}, interface: {}", - hostName, outgoingInterfaceName); - return; - } - - List ipThroughInterface = portRouteState.getAllIps(); - - for (Ipv4Address ip : ipThroughInterface) { - long routeId = portRouteState.getRouteIdOfIp(ip); - String subnetUuidOfIp = portRouteState.getSubnetUuidOfIp(ip); - boolean ok = deleteSingleStaticRouteFromRoutingProtocol(hostName, vrfId, - outgoingInterfaceName, routeId); - - if (ok) { - portRouteState.removeIp(ip); - hostRelatedInfoContainer - .getVrfStateOfHost(hostName) - .getVrfState(vrfId) - .removePortIpFromVrf(subnetUuidOfIp, ip); - } - } + .getRoutingInstanceIid(new RoutingProtocolKey(protocolName)) + .child(StaticRoutes.class) + .augmentation(StaticRoutes1.class) + .child(Ipv4.class) + .child(Route.class, new RouteKey(routeId)); + + return GbpNetconfTransaction.netconfSyncedDelete(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), iid, + GbpNetconfTransaction.RETRY_COUNT); } - private static String getRoutingProtocolName(long vrf) { - return Constants.ROUTING_PROTOCOL_NAME_PREFIX + vrf; + public static RoutingProtocolKey getRoutingProtocolName(long vrf) { + return new RoutingProtocolKey(Constants.ROUTING_PROTOCOL_NAME_PREFIX + vrf); } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/HostRelatedInfoContainer.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/HostRelatedInfoContainer.java index 1e07a7eba..bb6a08a67 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/HostRelatedInfoContainer.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/HostRelatedInfoContainer.java @@ -11,8 +11,20 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.LispState; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PhysicalInterfaces; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfHolder; +import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.collect.Table; import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * Created by Shakib Ahmed on 7/13/17. @@ -23,6 +35,9 @@ public class HostRelatedInfoContainer { private HashMap hostNameToPortInterfacesMapper; private HashMap hostNameToVrfHolderMapper; + //route IDs on an interface on a host + private Table> routeIdsByHostByVrf = HashBasedTable.create(); + private static final HostRelatedInfoContainer INSTANCE = new HostRelatedInfoContainer(); private HostRelatedInfoContainer() { @@ -32,6 +47,40 @@ public class HostRelatedInfoContainer { this.hostNameToVrfHolderMapper = new HashMap<>(); } + public void addRouteToIntfc(String hostname, String intfName, Long routeId) { + Preconditions.checkNotNull(hostname); + Preconditions.checkNotNull(intfName); + Preconditions.checkNotNull(routeId); + if (routeIdsByHostByVrf.get(hostname, intfName) != null) { + routeIdsByHostByVrf.get(hostname, intfName).add(routeId); + return; + } + routeIdsByHostByVrf.put(hostname, intfName, Sets.newHashSet(routeId)); + } + + public void deleteRouteFromIntfc(String hostname, String intfName, Long routeId) { + Preconditions.checkNotNull(hostname); + Preconditions.checkNotNull(intfName); + Preconditions.checkNotNull(routeId); + if (routeIdsByHostByVrf.get(hostname, intfName) != null) { + routeIdsByHostByVrf.get(hostname, intfName).remove(routeId); + } + } + + private static final Logger LOG = LoggerFactory.getLogger(VppEndpointListener.class); + + public boolean intfcIsBusy(String hostname, String intfName) { + Preconditions.checkNotNull(hostname); + Preconditions.checkNotNull(intfName); + if (routeIdsByHostByVrf.get(hostname, intfName) != null) { + int size = routeIdsByHostByVrf.get(hostname, intfName).size(); + LOG.trace("ISPORTBUSY -> hostname: {}, inftName: {}, entries: {}", hostname, intfName, routeIdsByHostByVrf.get(hostname, intfName)); + return (size == 0) ? false : true; + } + LOG.trace("ISPORTBUSY -> not busy interface on hostname: {}, inftName: {}", hostname, intfName); + return false; + } + public static HostRelatedInfoContainer getInstance() { return INSTANCE; } @@ -73,9 +122,18 @@ public class HostRelatedInfoContainer { } public VrfHolder getVrfStateOfHost(String hostName) { + return hostNameToVrfHolderMapper.get(hostName); + } + + public VrfHolder initializeVrfStateOfHost(String hostName) { return hostNameToVrfHolderMapper.computeIfAbsent(hostName, key -> new VrfHolder()); } + public int getVrfStateOfHostCount(String hostName) { + VrfHolder vrfHolder = hostNameToVrfHolderMapper.get(hostName); + return vrfHolder != null ? vrfHolder.vrfStateCount() : 0; + } + public void removeVrfStateOfHost(String hostName) { hostNameToVrfHolderMapper.remove(hostName); } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/LispState.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/LispState.java index 77b71ede2..8111de925 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/LispState.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/LispState.java @@ -88,6 +88,10 @@ public class LispState { return vniSet.contains(vni); } + public int vniSetCount() { + return vniSet == null ? 0 : vniSet.size(); + } + public void addInVniSet(long vni) { vniSet.add(vni); } @@ -106,4 +110,23 @@ public class LispState { public void deleteEid(Eid eid) { eidSet.remove(eid); } + + public void deleteEidSet() { + eidSet.clear(); + } + + public void deleteVniSet() { + vniSet.clear(); + } + + public void deleteLocators() { + interfaceNameToLocatorSetNameMapper.clear(); + } + + @Override public String toString() { + return "LispState{" + "lispEnabled=" + lispEnabled + ", gpeEnabled=" + gpeEnabled + + ", interfaceNameToLocatorSetNameMapper=" + interfaceNameToLocatorSetNameMapper + + ", mapServerIpAddressSet=" + mapServerIpAddressSet + ", mapResolverIpAddressSet=" + + mapResolverIpAddressSet + ", vniSet=" + vniSet + ", eidSet=" + eidSet + '}'; + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PhysicalInterfaces.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PhysicalInterfaces.java index 2026f73d8..751c9953e 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PhysicalInterfaces.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PhysicalInterfaces.java @@ -43,4 +43,9 @@ public class PhysicalInterfaces { public String getName(PhysicalInterfaceType physicalInterfaceType) { return physicalInterfaceTypeToNameMapper.get(physicalInterfaceType); } + + @Override public String toString() { + return "PhysicalInterfaces{" + "physicalInterfaceTypeToIpMapper=" + physicalInterfaceTypeToIpMapper + + ", physicalInterfaceTypeToNameMapper=" + physicalInterfaceTypeToNameMapper + '}'; + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PortInterfaces.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PortInterfaces.java index a867b28c5..d78f8e579 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PortInterfaces.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PortInterfaces.java @@ -50,15 +50,12 @@ public class PortInterfaces { metadataInterfaceSet.add(interfaceName); } - public long getInterfaceVrfId(String interfaceName) { + public Long getInterfaceVrfId(String interfaceName) { PortRouteState portRouteState = interfaceNameToPortRouteStateMapper.get(interfaceName); if (portRouteState != null) { return portRouteState.getVrfId(); - } else { - LOG.warn("cannot get VrfId for interface name. interfaceName: {}, interfaceNameToPortRouteStateMapper: {}", - interfaceName, interfaceNameToPortRouteStateMapper.values()); } - return -1L; + return null; } public void removePortInterface(String interfaceName) { @@ -69,4 +66,9 @@ public class PortInterfaces { public boolean isRoutingContextForInterfaceInitialized(String interfaceName) { return interfaceNameToPortRouteStateMapper.get(interfaceName) != null; } + + @Override public String toString() { + return "PortInterfaces{" + "interfaceNameToPortRouteStateMapper=" + interfaceNameToPortRouteStateMapper + + ", metadataInterfaceSet=" + metadataInterfaceSet + '}'; + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PortRouteState.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PortRouteState.java index c5449a98d..d0b8c75ab 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PortRouteState.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/PortRouteState.java @@ -7,7 +7,11 @@ */ package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states; +import com.google.common.collect.Lists; + import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.HashMap; @@ -36,7 +40,7 @@ public class PortRouteState { ipToSubnetUuidMapper.put(ip, ipSubnetUuid); } - public long getRouteIdOfIp(Ipv4Address interfaceIp) { + public Long getRouteIdOfIp(Ipv4Address interfaceIp) { return ipToRouteIdMapper.get(interfaceIp); } @@ -52,4 +56,12 @@ public class PortRouteState { public List getAllIps() { return new ArrayList<>(ipToRouteIdMapper.keySet()); } + + public boolean isPortRouteStateEmpty() { + return (ipToRouteIdMapper.size() == 0 && ipToSubnetUuidMapper.size() == 0); + } + + @Override public String toString() { + return "PortRouteState= {vrfId= " + vrfId + ", ipToSubnetUuidMapper= " + ipToSubnetUuidMapper + ", ipToRouteIdMapper= " + ipToRouteIdMapper + "}"; + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/RouteState.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/RouteState.java index 9ceac73f5..326435e5a 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/RouteState.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/RouteState.java @@ -46,4 +46,8 @@ public class RouteState { public List getAllIps() { return new ArrayList<>(ipToRouteIdMapper.keySet()); } + + @Override public String toString() { + return "RouteState{" + "ipToRouteIdMapper=" + ipToRouteIdMapper + '}'; + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/SubnetHolder.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/SubnetHolder.java index ee012b1f9..1132198a0 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/SubnetHolder.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/SubnetHolder.java @@ -9,9 +9,6 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.state import java.util.HashMap; -/** - * Created by Shakib Ahmed on 7/17/17. - */ public class SubnetHolder { private HashMap subnetUuidToSubnetStateMapper; @@ -20,12 +17,27 @@ public class SubnetHolder { } public SubnetState getSubnetState(String subnetUuid) { + return subnetUuidToSubnetStateMapper.get(subnetUuid); + } + + public SubnetState initializeSubnetState (String subnetUuid) { return subnetUuidToSubnetStateMapper.computeIfAbsent(subnetUuid, - key -> new SubnetState()); + key -> new SubnetState()); } public void removeSubnetState(String subnetUuid) { subnetUuidToSubnetStateMapper.remove(subnetUuid); } + public int subnetHolderCount() { + return subnetUuidToSubnetStateMapper.size(); + } + + public boolean subnetStateContains(String subnetUuid) { + return subnetUuidToSubnetStateMapper.get(subnetUuid) != null; + } + + @Override public String toString() { + return "SubnetHolder: { subnetUuidToSubnetStateMapper: {}" + subnetUuidToSubnetStateMapper + "}"; + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/SubnetState.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/SubnetState.java index 4d6885c66..ca210306b 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/SubnetState.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/SubnetState.java @@ -8,6 +8,8 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.HashSet; import java.util.Set; @@ -19,6 +21,9 @@ public class SubnetState { private String gwInterfaceName; private Set ipsInSubnet; + private static final Logger LOG = LoggerFactory.getLogger(SubnetState.class); + + public SubnetState() { ipsInSubnet = new HashSet<>(); } @@ -41,6 +46,7 @@ public class SubnetState { public void addNewIp(Ipv4Address portIp) { ipsInSubnet.add(portIp); + LOG.trace("SubnetState -> added IP: {} to SubnetState: {}", portIp, this); } public boolean isIpPresent(Ipv4Address portIp) { @@ -49,5 +55,14 @@ public class SubnetState { public void removeIp(Ipv4Address portIp) { ipsInSubnet.remove(portIp); + LOG.trace("SubnetState -> removed IP: {} from SubnetState: {}", portIp, this); + } + + public Set getIpsInSubnet() { + return ipsInSubnet; + } + + @Override public String toString() { + return "SubnetState{" + "gwInterfaceName='" + gwInterfaceName + '\'' + ", ipsInSubnet=" + ipsInSubnet + '}'; } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/VrfHolder.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/VrfHolder.java index 8aa1ba492..eaea527ff 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/VrfHolder.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/VrfHolder.java @@ -27,7 +27,19 @@ public class VrfHolder { vrfIdToVrfStateMapper.put(vrfId, new VrfState(routingProtocolName)); } + public VrfState removeVrfState(Long vrfId) { + return vrfIdToVrfStateMapper.remove(vrfId); + } + public boolean hasVrf(Long vrfId) { return vrfIdToVrfStateMapper.containsKey(vrfId); } + + public int vrfStateCount() { + return vrfIdToVrfStateMapper.size(); + } + + @Override public String toString() { + return "VrfHolder{" + "vrfIdToVrfStateMapper=" + vrfIdToVrfStateMapper + '}'; + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/VrfState.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/VrfState.java index c3d34663d..21cd1c559 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/VrfState.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/info/container/states/VrfState.java @@ -10,9 +10,6 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.state import org.apache.commons.lang3.mutable.MutableLong; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; -/** - * Created by Shakib Ahmed on 7/17/17. - */ public class VrfState { private SubnetHolder subnetHolder; private String protocolName; @@ -42,6 +39,17 @@ public class VrfState { } public void removePortIpFromVrf(String portSubnetUuid, Ipv4Address portIp) { - subnetHolder.getSubnetState(portSubnetUuid).removeIp(portIp); + if (subnetHolder.subnetStateContains(portSubnetUuid)) { + subnetHolder.getSubnetState(portSubnetUuid).removeIp(portIp); + } + } + + public int subnetCount() { + return subnetHolder.subnetHolderCount(); + } + + @Override public String toString() { + return "VrfState{" + "subnetHolder=" + subnetHolder + ", protocolName='" + protocolName + '\'' + + ", nextRouteId=" + nextRouteId + '}'; } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/loopback/LoopbackManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/loopback/LoopbackManager.java index fa28126dc..f3c223f8e 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/loopback/LoopbackManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/loopback/LoopbackManager.java @@ -8,9 +8,20 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.loopback; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Lists; +import com.google.common.collect.Table; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import javax.annotation.Nonnull; import org.apache.commons.lang3.tuple.Pair; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.LoopbackCommand; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.LoopbackCommandWrapper; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ProxyRangeCommand; @@ -20,12 +31,8 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.lisp.LispCommandW import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateCommandExecutor; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispConfigCommandFailedException; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispHelperArgumentException; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.EndpointHost; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.SubnetState; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfHolder; +import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay.FlatOverlayManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper; -import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.SubnetUuidToGbpSubnetMapper; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.Constants; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.IpAddressUtil; @@ -36,21 +43,21 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProv import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +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.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4PrefixAfi; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.IpPrefixType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.GbpSubnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801.gpe.entry.table.grouping.gpe.entry.table.GpeEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170801.gpe.entry.table.grouping.gpe.entry.table.gpe.entry.RemoteEid; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Preconditions; - /** * Created by Shakib Ahmed on 4/26/17. */ @@ -58,144 +65,115 @@ public class LoopbackManager { private static final Logger LOG = LoggerFactory.getLogger(LoopbackManager.class); private ConfigManagerHelper loopbackManagerHelper; + private Table> unnumberedCache = HashBasedTable.create(); - private HostRelatedInfoContainer hostRelatedInfoContainer = HostRelatedInfoContainer.getInstance(); - private SubnetUuidToGbpSubnetMapper subnetUuidToGbpSubnetMapper = SubnetUuidToGbpSubnetMapper.getInstance(); private NeutronTenantToVniMapper neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance(); - public LoopbackManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) { - this.loopbackManagerHelper = new ConfigManagerHelper(mountedDataBrokerProvider); - } - public void createBviLoopbackIfNeeded(AddressEndpointWithLocation addressEp, - String bridgeDomainName) { - try { - EndpointHost endpointHost = loopbackManagerHelper.getEndpointHostInformation(addressEp); - long vni = getVni(addressEp.getTenant().getValue()); - long vrfId = vni; - String subnetUuid = loopbackManagerHelper.getSubnet(addressEp); + Map GbpSubnetCache = new HashMap<>(); + Map> loopBackHostnames = new HashMap<>(); - VrfHolder hostVrfHolder = hostRelatedInfoContainer.getVrfStateOfHost(endpointHost.getHostName()); + private class LoopBackDetails { + LoopbackCommand loopbackCommand; + String hostName; - if (!hostVrfHolder.hasVrf(vrfId)) { - //dummy init for bridge domain case - hostVrfHolder.initializeVrfState(vrfId, Constants.DUMMY_PROTOCOL_BRIDGE_DOMAIN); - } + public LoopbackCommand getLoopbackCommand() { + return loopbackCommand; + } - SubnetState subnetState = hostVrfHolder.getVrfState(vni) - .getSubnetHolder() - .getSubnetState(subnetUuid); + public void setLoopbackCommand(LoopbackCommand loopbackCommand) { + this.loopbackCommand = loopbackCommand; + } - if (!subnetState.isGwConfigured()) { - return; - } + public String getHostName() { + return hostName; + } - GbpSubnet gbpSubnetInfo = Preconditions.checkNotNull(getSubnetInfo(subnetUuid), - "Subnet UUID {} hasn't been created yet!", subnetUuid); + public void setHostName(String hostName) { + this.hostName = hostName; + } + } - String gwInterfaceName = loopbackManagerHelper.getGatewayInterfaceName(Constants.GW_NAME_PREFIX, subnetUuid); - LoopbackCommand bviLoopbackCommand = LoopbackCommandWrapper - .bviLoopbackPutCommand(gwInterfaceName, vni, gbpSubnetInfo.getGatewayIp(), gbpSubnetInfo.getCidr(), - bridgeDomainName); - createLoopbackInterface(endpointHost.getHostName(), subnetState, bviLoopbackCommand); - } catch (LispConfigCommandFailedException e) { - LOG.warn("LISP couldn't be configured: {}", e.getMessage()); - } + public LoopbackManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) { + this.loopbackManagerHelper = new ConfigManagerHelper(mountedDataBrokerProvider); } public void createSimpleLoopbackIfNeeded(AddressEndpointWithLocation addressEp) { - try { + if (!addressEp.getAddressType().equals(IpPrefixType.class)) { + return; + } + Map intfcsByHostname = FlatOverlayManager.resolveIntfcsByHosts(addressEp); - if (loopbackManagerHelper.isMetadataPort(addressEp)) { - return; - } - String hostName = loopbackManagerHelper.getHostName(addressEp).get(); - long vni = getVni(addressEp.getTenant().getValue()); - long vrfId = vni; - String subnetUuid = loopbackManagerHelper.getSubnet(addressEp); - - SubnetState stateOfSubnetUuid = hostRelatedInfoContainer - .getVrfStateOfHost(hostName) - .getVrfState(vrfId).getSubnetHolder() - .getSubnetState(subnetUuid); - - GbpSubnet gbpSubnetInfo = Preconditions.checkNotNull(getSubnetInfo(subnetUuid), - "Subnet UUID {} hasn't been created yet!", subnetUuid); - - if (!stateOfSubnetUuid.isGwConfigured()) { - String interfaceName = loopbackManagerHelper.getGatewayInterfaceName(Constants.GW_NAME_PREFIX, - subnetUuid); - LoopbackCommand simpleLoopbackCommand = LoopbackCommandWrapper - .simpleLoopbackPutCommand(interfaceName, vrfId, gbpSubnetInfo.getGatewayIp(), + intfcsByHostname.forEach((hostname, interfaceName) -> { + try { + long vni = getVni(addressEp.getTenant().getValue()); + long vrfId = vni; + String subnetUuid = loopbackManagerHelper.getSubnet(addressEp); + GbpSubnet gbpSubnetInfo = GbpSubnetCache.get(subnetUuid); + String loopIntfcName = Constants.GW_NAME_PREFIX + subnetUuid; + + if (gbpSubnetInfo != null) { + Optional optionalLoopback = + GbpNetconfTransaction.read(VppIidFactory.getNetconfNodeIid(new NodeId(hostname)), + LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getInterfaceIID(new InterfaceKey(loopIntfcName)), + GbpNetconfTransaction.RETRY_COUNT); + if (!optionalLoopback.isPresent()) { + LoopbackCommand simpleLoopbackCommand = + LoopbackCommandWrapper.simpleLoopbackPutCommand(loopIntfcName, vrfId, gbpSubnetInfo.getGatewayIp(), gbpSubnetInfo.getCidr()); - createLoopbackInterface(hostName, stateOfSubnetUuid, simpleLoopbackCommand); - addProxyArpRange(hostName, vrfId, gbpSubnetInfo); - addGpeEntry(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), gbpSubnetInfo, vni); + if (createLoopbackInterface(hostname, simpleLoopbackCommand)) { + addGpeEntry(VppIidFactory.getNetconfNodeIid(new NodeId(hostname)), gbpSubnetInfo, vni); + addProxyArpRange(hostname, vrfId, gbpSubnetInfo); + if(loopBackHostnames.get(loopIntfcName) == null) { + LoopBackDetails loopBackDetails = new LoopBackDetails(); + loopBackDetails.setHostName(hostname); + loopBackDetails.setLoopbackCommand(simpleLoopbackCommand); + loopBackHostnames.put(loopIntfcName, Lists.newArrayList(loopBackDetails)); + } else { + LoopBackDetails loopBackDetails = new LoopBackDetails(); + loopBackDetails.setHostName(hostname); + loopBackDetails.setLoopbackCommand(simpleLoopbackCommand); + loopBackHostnames.get(loopIntfcName).add(loopBackDetails); + } + } + } else { + LOG.trace("Loopback already present on host: {} skip update for: {} - {} in vrf: {}", hostname, loopIntfcName, gbpSubnetInfo.getGatewayIp(), vrfId); + } + } + + + if (!addUnnumberedInterface(hostname, interfaceName, loopIntfcName)){ + LOG.warn("Failed to add unnumbered for addressEp : {}", addressEp); + } + } catch (LispConfigCommandFailedException e) { + LOG.warn("LISP couldn't be configured: {}", e.getMessage()); } + }); - String gwInterfaceName = stateOfSubnetUuid.getGwInterfaceName(); - addUnnumberedInterface(addressEp, gwInterfaceName); - } catch (LispConfigCommandFailedException e) { - LOG.warn("LISP couldn't be configured: {}", e.getMessage()); - } - } - private void createLoopbackInterface(String hostName, - SubnetState subnetState, - LoopbackCommand loopbackCommand) throws LispConfigCommandFailedException { - if (GbpNetconfTransaction.netconfSyncedWrite(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), - loopbackCommand, GbpNetconfTransaction.RETRY_COUNT)) { - subnetState.setGwInterfaceName(loopbackCommand.getName()); - } else { - throw new LispConfigCommandFailedException("BVI could not be created for " - + hostName + " and bridge domain " + loopbackCommand.getBridgeDomain()); - } } - public void handleEndpointDelete(AddressEndpointWithLocation addressEp) { + private boolean createLoopbackInterface(String hostName, LoopbackCommand loopbackCommand){ - if (loopbackManagerHelper.isMetadataPort(addressEp)) { - return; - } - String hostName = loopbackManagerHelper.getHostName(addressEp).get(); - String portSubnetUuid = loopbackManagerHelper.getSubnet(addressEp); - long vrfId = getVni(addressEp.getTenant().getValue()); - SubnetState subnetStateForSubnetUuid = hostRelatedInfoContainer - .getVrfStateOfHost(hostName) - .getVrfState(vrfId) - .getSubnetHolder() - .getSubnetState(portSubnetUuid); - - if (!subnetStateForSubnetUuid.hasIpsInSubnet()) { - String gwInterfaceName = subnetStateForSubnetUuid.getGwInterfaceName(); - GbpSubnet gbpSubnetInfo = Preconditions.checkNotNull(subnetUuidToGbpSubnetMapper.getSubnetInfo(portSubnetUuid), - "Invalid port!"); - long vni = getVni(addressEp.getTenant().getValue()); - try { - InstanceIdentifier iid = VppIidFactory.getNetconfNodeIid(new NodeId(hostName)); - deleteSpecificLoopback(iid, gwInterfaceName); - deleteProxyArpRange(hostName, vni, gbpSubnetInfo); - deleteGpeEntry(iid, Constants.GPE_ENTRY_PREFIX + gbpSubnetInfo.getId() + "_1"); - deleteGpeEntry(iid, Constants.GPE_ENTRY_PREFIX + gbpSubnetInfo.getId() + "_2"); - hostRelatedInfoContainer.getVrfStateOfHost(hostName) - .getVrfState(vrfId) - .getSubnetHolder() - .removeSubnetState(portSubnetUuid); - } catch (LispConfigCommandFailedException e) { - LOG.warn("Loopback not deleted properly: {}", e.getMessage()); - } - } + return GbpNetconfTransaction.netconfSyncedWrite(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), + loopbackCommand, GbpNetconfTransaction.RETRY_COUNT); } - private void deleteSpecificLoopback(InstanceIdentifier nodeIid, String interfaceName) throws LispConfigCommandFailedException { - if (!GbpNetconfTransaction.netconfSyncedDelete(nodeIid, - VppIidFactory.getInterfaceIID(new InterfaceKey(interfaceName)), GbpNetconfTransaction.RETRY_COUNT)) { - throw new LispConfigCommandFailedException("Failed to delete Loopback interface!"); - } else { - LOG.debug("Deleted loopback interface!"); + private boolean deleteSpecificLoopback(InstanceIdentifier nodeIid, String loopbackName) { + LOG.trace("deleteSpecificLoopback -> nodeiid: {}, loopbackInterface: {}", nodeIid, loopbackName); + if (unnumberedCache.get(new NodeKey(nodeIid.firstKeyOf(Node.class)), loopbackName) != null) { + unnumberedCache.get(new NodeKey(nodeIid.firstKeyOf(Node.class)), loopbackName).forEach(intfc -> { + if (GbpNetconfTransaction.netconfSyncedDelete(nodeIid, + VppIidFactory.getUnnumberedIid(new InterfaceKey(intfc)), GbpNetconfTransaction.RETRY_COUNT)) { + unnumberedCache.remove(new NodeKey(nodeIid.firstKeyOf(Node.class)), loopbackName); + } + }); } + return GbpNetconfTransaction.netconfSyncedDelete(nodeIid, + VppIidFactory.getInterfaceIID(new InterfaceKey(loopbackName)), GbpNetconfTransaction.RETRY_COUNT); } private void addProxyArpRange(String hostName, @@ -208,10 +186,8 @@ public class LoopbackManager { Pair startAndEndAddress = IpAddressUtil.getStartAndEndIp(subnetPrefix); - if (!putArpRangesCommand(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), - vrf, - startAndEndAddress.getLeft(), - startAndEndAddress.getRight())) { + if (!putArpRangesCommand(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), vrf, + startAndEndAddress.getLeft(), startAndEndAddress.getRight())) { throw new LispConfigCommandFailedException("Proxy arp configuration failed for subnet uuid: " + gbpSubnetInfo.getId() + "!"); } else { @@ -220,9 +196,7 @@ public class LoopbackManager { } } - private void deleteProxyArpRange(String hostName, - long vrf, - GbpSubnet gbpSubnetInfo) throws LispConfigCommandFailedException { + private boolean deleteProxyArpRange(String hostName, long vrf, GbpSubnet gbpSubnetInfo) { Ipv4Prefix subnetPrefix = gbpSubnetInfo.getCidr().getIpv4Prefix(); Preconditions.checkNotNull(subnetPrefix, "Subnet CIDR found to be null for " @@ -230,16 +204,8 @@ public class LoopbackManager { Pair startAndEndAddress = IpAddressUtil.getStartAndEndIp(subnetPrefix); - if (!deleteArpRangesCommand(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), - vrf, - startAndEndAddress.getLeft(), - startAndEndAddress.getRight())) { - throw new LispConfigCommandFailedException("Proxy arp configuration failed for subnet uuid: " + - gbpSubnetInfo.getId() + "!"); - } else { - LOG.debug("Removed proxy arp for range {} to {} on node : {}!", startAndEndAddress.getLeft(), - startAndEndAddress.getRight(), hostName); - } + return (deleteArpRangesCommand(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), vrf, + startAndEndAddress.getLeft(), startAndEndAddress.getRight())); } private boolean putArpRangesCommand(InstanceIdentifier iid, long vrf, Ipv4Address start, Ipv4Address end) { @@ -263,16 +229,19 @@ public class LoopbackManager { return GbpNetconfTransaction.netconfSyncedDelete(iid, builder.build(), GbpNetconfTransaction.RETRY_COUNT); } - private void addUnnumberedInterface(AddressEndpointWithLocation addressEp, String loopbackName) throws LispConfigCommandFailedException { - ExternalLocationCase loc = ConfigManagerHelper.resolveAndValidateLocation(addressEp); - InstanceIdentifier nodeIid = (InstanceIdentifier) loc.getExternalNodeMountPoint(); - String neutronInterfaceName = loopbackManagerHelper.getInterfaceName(addressEp).get(); - if (putUnnumberedInterface(nodeIid, neutronInterfaceName, loopbackName)) { + private boolean addUnnumberedInterface(String hostname, String neutronInterfaceName, String loopbackName) { + InstanceIdentifier nodeIid = VppIidFactory.getNetconfNodeIid(new NodeId(hostname)); + LOG.trace("Adding unnumbered configuration hostname: {}, interface: {} use : {}", hostname, neutronInterfaceName, loopbackName); + boolean unnumberWritten = putUnnumberedInterface(nodeIid, neutronInterfaceName, loopbackName); + if (unnumberWritten) { + if (unnumberedCache.get(nodeIid.firstKeyOf(Node.class), loopbackName) != null) { + unnumberedCache.get(nodeIid.firstKeyOf(Node.class), loopbackName).add(neutronInterfaceName); + } else { + unnumberedCache.put(nodeIid.firstKeyOf(Node.class), loopbackName, Lists.newArrayList(neutronInterfaceName)); + } LOG.debug("Added Interface {} as unnumbered for {}", loopbackName, neutronInterfaceName); - } else { - throw new LispConfigCommandFailedException("Unnumbered configuration failed for " + - neutronInterfaceName + " - " + loopbackName); } + return unnumberWritten; } private boolean putUnnumberedInterface(InstanceIdentifier iid, String interfaceName, String useInterface) { @@ -286,24 +255,27 @@ public class LoopbackManager { } private void addGpeEntry(InstanceIdentifier iid, GbpSubnet gbpSubnetInfo, long vni) { + LOG.trace("addGpeEntry called. iid: {}, GbpSubnet: {}, vni: {}", iid, gbpSubnetInfo, vni); try { - Pair delegatingSubnets = IpAddressUtil - .getSmallerSubnet(gbpSubnetInfo.getCidr().getIpv4Prefix()); + Pair delegatingSubnets = + IpAddressUtil.getSmallerSubnet(gbpSubnetInfo.getCidr().getIpv4Prefix()); - RemoteEid firstREid = LispUtil.toRemoteEid(LispUtil.toLispIpv4Prefix(delegatingSubnets.getLeft()), - vni, - Ipv4PrefixAfi.class); - putGpeEntry(iid, Constants.GPE_ENTRY_PREFIX + gbpSubnetInfo.getId() + "_1", firstREid, vni, vni); + RemoteEid firstREid = + LispUtil.toRemoteEid(LispUtil.toLispIpv4Prefix(delegatingSubnets.getLeft()), vni, Ipv4PrefixAfi.class); + if (!putGpeEntry(iid, Constants.GPE_ENTRY_PREFIX + gbpSubnetInfo.getId() + "_1", firstREid, vni, vni)) { + LOG.warn("Failed to write GPE entry: {}", Constants.GPE_ENTRY_PREFIX + gbpSubnetInfo.getId() + "_1"); + } if (delegatingSubnets.getLeft().equals(delegatingSubnets.getRight())) { return; } - RemoteEid secondREid = LispUtil.toRemoteEid(LispUtil.toLispIpv4Prefix(delegatingSubnets.getRight()), - vni, - Ipv4PrefixAfi.class); + RemoteEid secondREid = + LispUtil.toRemoteEid(LispUtil.toLispIpv4Prefix(delegatingSubnets.getRight()), vni, Ipv4PrefixAfi.class); - putGpeEntry(iid, Constants.GPE_ENTRY_PREFIX + gbpSubnetInfo.getId() + "_2", secondREid, vni, vni); + if (!putGpeEntry(iid, Constants.GPE_ENTRY_PREFIX + gbpSubnetInfo.getId() + "_2", secondREid, vni, vni)) { + LOG.warn("Failed to write GPE entry: {}", Constants.GPE_ENTRY_PREFIX + gbpSubnetInfo.getId() + "_2"); + } } catch (LispHelperArgumentException e) { e.printStackTrace(); } @@ -325,7 +297,46 @@ public class LoopbackManager { return neutronTenantToVniMapper.getVni(tenantUuid); } - private GbpSubnet getSubnetInfo(String subnetUuid) { - return subnetUuidToGbpSubnetMapper.getSubnetInfo(subnetUuid); + + public void gbpSubnetCreated(String subnetUuid, GbpSubnet subnetInfo) { + GbpSubnetCache.put(subnetUuid, subnetInfo); + } + + public void gbpSubnetdeleted(String subnetUuid) { + LOG.trace("gbpSubnetdeleted -> subnetUuid:{}", subnetUuid); + GbpSubnet gbpSubnet = GbpSubnetCache.get(subnetUuid); + String loopIntfcName = Constants.GW_NAME_PREFIX + subnetUuid; + List loopBackDetails = loopBackHostnames.get(loopIntfcName); + if (loopBackDetails != null) { + loopBackDetails.forEach(loopbackDetail -> { + + InstanceIdentifier iid = VppIidFactory.getNetconfNodeIid(new NodeId(loopbackDetail.getHostName())); + + if (deleteSpecificLoopback(iid, loopIntfcName)) { + if (deleteProxyArpRange(loopbackDetail.getHostName(), loopbackDetail.getLoopbackCommand().getVrfId(), gbpSubnet)) { + LOG.warn("Failed to delete ProxyArpRange: {} on host: {}", gbpSubnet.getAllocationPools(), loopbackDetail.getHostName()); + } + + if (deleteGpeEntry(iid, Constants.GPE_ENTRY_PREFIX + gbpSubnet.getId() + "_1")) { + LOG.warn("Failed to delete gpeEntry: {} on host: {}", Constants.GPE_ENTRY_PREFIX + gbpSubnet.getId() + "_1", loopbackDetail.getHostName()); + } + if (deleteGpeEntry(iid, Constants.GPE_ENTRY_PREFIX + gbpSubnet.getId() + "_2")) { + LOG.warn("Failed to delete gpeEntry: {} on host: {}", Constants.GPE_ENTRY_PREFIX + gbpSubnet.getId() + "_2", loopbackDetail.getHostName()); + } + if (deleteGpeFeatureData(loopbackDetail.getHostName())) { + LOG.warn("Failed to delete gpe configuration: {} on host: {}", loopbackDetail.getHostName()); + } + + } else { + LOG.warn("Failed to delete loopback: {} on host: {}", loopIntfcName, loopbackDetail.getHostName()); + } + }); + } + GbpSubnetCache.remove(subnetUuid); + } + + private boolean deleteGpeFeatureData(String hostname) { + return GbpNetconfTransaction.netconfSyncedDelete(VppIidFactory.getNetconfNodeIid(new NodeId(hostname)), + VppIidFactory.getGpeFeatureDataIid(), GbpNetconfTransaction.RETRY_COUNT); } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/ConfigManagerHelper.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/ConfigManagerHelper.java index c308a7211..9ae94407d 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/ConfigManagerHelper.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/ConfigManagerHelper.java @@ -82,72 +82,6 @@ public class ConfigManagerHelper { this.mountedDataBrokerProvider = mountedDataBrokerProvider; } - public EndpointHost getEndpointHostInformation(AddressEndpointWithLocation addressEpWithLoc) { - DataBroker endpointHostDataBroker = getPotentialExternalDataBroker(addressEpWithLoc).get(); - String hostName = getHostName(addressEpWithLoc).get(); - return new EndpointHost(endpointHostDataBroker, hostName); - } - - public Optional getPotentialExternalDataBroker(AddressEndpointWithLocation addressEpWithLoc) { - ExternalLocationCase externalLocationCase = resolveAndValidateLocation(addressEpWithLoc); - InstanceIdentifier vppNodeIid = - (InstanceIdentifier) externalLocationCase.getExternalNodeMountPoint(); - String interfacePath = externalLocationCase.getExternalNodeConnector(); - - Optional - potentialVppDataProvider = mountedDataBrokerProvider.resolveDataBrokerForMountPoint(vppNodeIid); - - Preconditions.checkArgument(potentialVppDataProvider.isPresent(), - "Cannot resolve data broker for interface path: {}", interfacePath); - - return potentialVppDataProvider; - } - - public Optional getPotentialExternalDataBroker(ExternalLocation externalLocation) { - InstanceIdentifier vppNodeIid = (InstanceIdentifier) externalLocation.getExternalNodeMountPoint(); - - Optional potentialVppDataProvider; - potentialVppDataProvider = mountedDataBrokerProvider.resolveDataBrokerForMountPoint(vppNodeIid); - - Preconditions.checkState(potentialVppDataProvider.isPresent(), "Data Broker missing"); - - return potentialVppDataProvider; - } - - public Optional getPotentialExternalDataBroker(VppEndpoint vppEp) { - InstanceIdentifier vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEp.getVppNodeId()); - Optional potentialVppDataProvider = - mountedDataBrokerProvider.resolveDataBrokerForMountPoint(vppNodeIid); - - Preconditions.checkArgument(potentialVppDataProvider.isPresent(), - "Cannot resolve data broker for Vpp Endpoint: {}", vppEp); - return potentialVppDataProvider; - } - - public Optional getPotentialExternalDataBroker(String hostId) { - InstanceIdentifier nodeIid = VppIidFactory.getNetconfNodeIid(new NodeId(hostId)); - Optional potentialVppDataProvider = - mountedDataBrokerProvider.resolveDataBrokerForMountPoint(nodeIid); - Preconditions.checkArgument(potentialVppDataProvider.isPresent(), - "Data Broker not found for {}", hostId); - return potentialVppDataProvider; - } - - public Optional getHostName(AddressEndpointWithLocation addrEp) { - ExternalLocationCase locationCase = resolveAndValidateLocation(addrEp); - NodeKey nodeKey = locationCase.getExternalNodeMountPoint().firstKeyOf(Node.class); - String hostId = Preconditions.checkNotNull(nodeKey.getNodeId().getValue(), - "Host Id extraction failed from address endpoint: {}", addrEp); - return Optional.fromNullable(hostId); - } - - public Optional getHostName(ExternalLocation externalLocation) { - NodeKey nodeKey = externalLocation.getExternalNodeMountPoint().firstKeyOf(Node.class); - String hostId = Preconditions.checkNotNull(nodeKey.getNodeId().getValue(), - "Host Id extraction failed from address endpoint: {}", externalLocation); - - return Optional.fromNullable(hostId); - } public static ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) { Preconditions.checkNotNull(addrEpWithLoc.getAbsoluteLocation(), "Absolute location for " + @@ -308,9 +242,9 @@ public class ConfigManagerHelper { return ip != null; } - public String getLispCpRlocInterfaceName(@Nonnull EndpointHost endpointHost) { + public String getLispCpRlocInterfaceName(@Nonnull String hostName) { List operationalInterfaceList = - InterfaceUtil.getOperationalInterfaces(LispUtil.HOSTNAME_TO_IID.apply(endpointHost.getHostName())); + InterfaceUtil.getOperationalInterfaces(LispUtil.HOSTNAME_TO_IID.apply(hostName)); if (operationalInterfaceList == null) { return null; @@ -346,8 +280,7 @@ public class ConfigManagerHelper { return LispStateManager.DEFAULT_LOCATOR_SET_NAME_PREFIX + "_itr_rloc"; } - public String constructEidMappingName(AddressEndpointWithLocation addressEp) { - String interfaceName = getInterfaceName(addressEp).get(); + public String constructEidMappingName(AddressEndpointWithLocation addressEp, String interfaceName) { String ipAddress = getInterfaceIp(addressEp).getValue(); return LispStateManager.DEFAULT_MAPPING_RECORD_NAME_PREFIX + interfaceName + "_" + ipAddress; } @@ -367,7 +300,7 @@ public class ConfigManagerHelper { return LispUtil.toEid(LispUtil.toIpv4(ipPrefix), vni, Ipv4Afi.class); } - public String getIpWithPrefixOfEndpoint(AddressEndpointWithLocation addressEp) { + private static String getIpWithPrefixOfEndpoint(AddressEndpointWithLocation addressEp) { String ipPrefix = null; if (addressEp.getAddressType().equals(IpPrefixType.class)) { ipPrefix = addressEp.getAddress(); @@ -386,7 +319,7 @@ public class ConfigManagerHelper { return Preconditions.checkNotNull(ipPrefix, "No IP address found for Address Endpoint: {}", addressEp); } - public Ipv4Address getInterfaceIp(AddressEndpointWithLocation addressEp) { + public static Ipv4Address getInterfaceIp(AddressEndpointWithLocation addressEp) { String ipPrefix = getIpWithPrefixOfEndpoint(addressEp); return LispUtil.toIpv4(ipPrefix).getIpv4(); } @@ -422,6 +355,7 @@ public class ConfigManagerHelper { return VppPathMapper.interfacePathToInterfaceName(interfacePath); } + public HmacKey getDefaultHmacKey() { return LispUtil.toHmacKey(HmacKeyType.Sha196Key, LispStateManager.DEFAULT_XTR_KEY); } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/Constants.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/Constants.java index 6b91511dd..3bfa479a5 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/Constants.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/lisp/util/Constants.java @@ -13,7 +13,7 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util; */ public class Constants { public static final String METADATA_IP = "169.254.169.254"; - public static final String METADATA_SUBNET_UUID = "dummy-metadata-subet"; + public static final String METADATA_SUBNET_UUID = "local-metadata-subnet"; public static final String ROUTING_PROTOCOL_NAME_PREFIX = "static-routing-"; public static final String DEFAULT_ROUTING_DESCRIPTION = "Static route added from GBP for flat L3 overlay"; public static final String GW_NAME_PREFIX = "loop-"; diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/listener/VppEndpointListener.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/listener/VppEndpointListener.java index de6d3d8bb..d7c53735b 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/listener/VppEndpointListener.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/listener/VppEndpointListener.java @@ -12,7 +12,10 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil; import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent; +import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer; +import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortInterfaces; import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint; @@ -21,11 +24,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; import com.google.common.eventbus.EventBus; +import javax.annotation.Nonnull; + public class VppEndpointListener extends DataTreeChangeHandler { private static final Logger LOG = LoggerFactory.getLogger(VppEndpointListener.class); + private Table pendingEndpointsTable = HashBasedTable.create(); private EventBus eventBus; public VppEndpointListener(DataBroker dataProvider, EventBus eventBus) { @@ -46,10 +54,52 @@ public class VppEndpointListener extends DataTreeChangeHandler { @Override protected void onDelete(DataObjectModification rootNode, - InstanceIdentifier rootIdentifier) { - VppEndpointConfEvent event = - new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter()); - eventBus.post(event); + InstanceIdentifier rootIdentifier) { + if (ConfigUtil.getInstance().isL3FlatEnabled()) { + VppEndpoint vppEndpointBefore = rootNode.getDataBefore(); + LOG.trace("onDelete -> Vppendpoint deleted: {}", vppEndpointBefore); + Preconditions.checkArgument(vppEndpointBefore.getVppNodeId() != null); + Preconditions.checkArgument(vppEndpointBefore.getVppInterfaceName() != null); + String intfName = rootNode.getDataBefore().getVppInterfaceName(); + LOG.info("onDelete -> Checking pending endpoint to delete {}", pendingEndpointsTable.get(vppEndpointBefore.getVppNodeId().getValue(), intfName)); + if(!portIsBusy(rootNode.getDataBefore())) { + LOG.info("onDelete -> Endpoint is not busy, deleting {}", vppEndpointBefore); + deleteVppEndpoint(new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter())); + } + else { + LOG.info("onDelete -> Caching pending deleted endpoint {}", rootNode.getDataBefore()); + pendingEndpointsTable.put(vppEndpointBefore.getVppNodeId().getValue(), intfName, new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter())); + } + } else { + deleteVppEndpoint(new VppEndpointConfEvent(rootIdentifier, rootNode.getDataBefore(), rootNode.getDataAfter())); + } + } + + private boolean portIsBusy(VppEndpoint vppEndpoint) { + HostRelatedInfoContainer hrc = HostRelatedInfoContainer.getInstance(); + boolean intfcIsInUse = + hrc.intfcIsBusy(vppEndpoint.getVppNodeId().getValue(), vppEndpoint.getVppInterfaceName()); + LOG.trace("onDelete -> isPortInUse: {} for vppEp: {}", intfcIsInUse, vppEndpoint); + return intfcIsInUse; + } + + private void deleteVppEndpoint(VppEndpointConfEvent vppEpConfEvent) { + eventBus.post(vppEpConfEvent); + } + + public void flushPendingVppEndpoint(@Nonnull String hostName,@Nonnull String intfName) { + Preconditions.checkNotNull(hostName); + Preconditions.checkNotNull(intfName); + LOG.trace("flushPendingVppEndpoint: hostname: {}, intfName: {}", hostName, intfName); + VppEndpointConfEvent vppEndpointConfEvent = pendingEndpointsTable.get(hostName, intfName); + + boolean canRemove = (vppEndpointConfEvent != null && !portIsBusy(vppEndpointConfEvent.getBefore().get())); + LOG.trace("flushPendingVppEndpoint: can remove {} - > VppEp: {}", canRemove, vppEndpointConfEvent); + if (canRemove) { + LOG.trace("flushPendingVppEndpoint: hostName: {} for interface: {}", hostName, intfName); + deleteVppEndpoint(vppEndpointConfEvent); + pendingEndpointsTable.remove(hostName, intfName); + } } @Override diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java index eaa16e67b..615431557 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java @@ -250,10 +250,6 @@ public final class ForwardingManager { rEpKey, policyCtx).get(), isBviForEndpoint(rEp)).get(); LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp); - if (ConfigUtil.getInstance().isLispOverlayEnabled()) { - loopbackManager.createBviLoopbackIfNeeded(rEp, l2FloodDomain); - } - } catch (InterruptedException | ExecutionException e) { // TODO add it to the status for renderer manager LOG.warn("Interface was not added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp, e); @@ -301,9 +297,8 @@ public final class ForwardingManager { if (ConfigUtil.getInstance().isLispOverlayEnabled()) { lispStateManager.processDeleteEndpoint(rEp); if (ConfigUtil.getInstance().isL3FlatEnabled()) { - flatOverlayManager.handleEndpointDeleteForFlatOverlay(rEp); + flatOverlayManager.deleteStaticRoutingEntry(rEp); } - loopbackManager.handleEndpointDelete(rEp); } if (rEpLoc == null || Strings.isNullOrEmpty(rEpLoc.getExternalNodeConnector())) { diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java index 5f0ce176a..90a6911eb 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java @@ -180,6 +180,14 @@ public class VppIidFactory { .build(); } + public static InstanceIdentifier getMappingsForVni(long vni) { + return InstanceIdentifier.builder(NatConfig.class) + .child(NatInstances.class) + .child(NatInstance.class, new NatInstanceKey(vni)) + .child(MappingTable.class) + .build(); + } + public static InstanceIdentifier getNatInstancesIid() { return InstanceIdentifier.builder(NatConfig.class).child(NatInstances.class).build(); } @@ -237,12 +245,16 @@ public class VppIidFactory { public static InstanceIdentifier getLocalMappingIid(VniTableKey vniTableKey, LocalMappingKey localMappingKey) { - return getVniTableIid(vniTableKey) - .child(VrfSubtable.class) - .child(LocalMappings.class) + return getLocalMappings(vniTableKey) .child(LocalMapping.class, localMappingKey); } + public static InstanceIdentifier getLocalMappings(VniTableKey vniTableKey) { + return getVniTableIid(vniTableKey) + .child(VrfSubtable.class) + .child(LocalMappings.class); + } + public static InstanceIdentifier getLispFeatureDataIid() { return InstanceIdentifier.builder(Lisp.class) .child(LispFeatureData.class).build(); diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java index 91314ac00..5c24f4289 100644 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java @@ -37,6 +37,7 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppEndpointLocationP import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay.FlatOverlayManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.loopback.LoopbackManager; +import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener; import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.CentralizedNatImpl; import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager; @@ -92,14 +93,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl. import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev170816._interface.nat.attributes.Nat; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.base.Strings; import com.google.common.collect.Lists; +import com.google.common.eventbus.EventBus; @RunWith(MockitoJUnitRunner.class) public class VppRendererPolicyManagerTest extends CustomDataBrokerTest { + private static final Logger LOG = LoggerFactory.getLogger(VppRendererPolicyManagerTest.class); private static final InstanceIdentifier RENDERER_POLICY_IID = IidFactory.rendererIid(VppRenderer.NAME).child(RendererPolicy.class); private final static String SOCKET = "socket"; @@ -136,6 +141,7 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest { private FlatOverlayManager flatOverlayManager; private DhcpRelayHandler dhcpRelayHandler; private VppRendererPolicyManager vppRendererPolicyManager; + private VppEndpointListener vppEndpointListener; @Override public Collection> getClassesFromModules() { @@ -150,13 +156,16 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest { public void init() throws Exception { mountedDataProviderMock = Mockito.mock(MountedDataBrokerProvider.class); mountPointDataBroker = getDataBroker(); + EventBus dtoEventBus = new EventBus((exception, context) -> LOG.error("Could not dispatch event: {} to {}", + context.getSubscriber(), context.getSubscriberMethod(), exception)); setup(); // initialize new data broker for ODL data store dataBroker = getDataBroker(); Mockito.when(mountedDataProviderMock.resolveDataBrokerForMountPoint(Mockito.any(InstanceIdentifier.class))) .thenReturn(Optional.of(mountPointDataBroker)); + vppEndpointListener = new VppEndpointListener(dataBroker, dtoEventBus); lispStateManager = new LispStateManager(mountedDataProviderMock); loopbackManager = new LoopbackManager(mountedDataProviderMock); - flatOverlayManager = new FlatOverlayManager(dataBroker, mountedDataProviderMock); + flatOverlayManager = new FlatOverlayManager(dataBroker, mountedDataProviderMock, vppEndpointListener); ifaceManager = new InterfaceManager(mountedDataProviderMock, dataBroker, flatOverlayManager); aclManager = new AclManager(mountedDataProviderMock, ifaceManager); natManager = new CentralizedNatImpl(dataBroker); -- 2.36.6