X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnservice%2Fvpnmanager%2Fvpnmanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fvpnmanager%2FVpnInterfaceManager.java;h=6963239076acda6a7c5863a4ad311d497872d819;hb=f60b2b35594f7cb0bc3aeba1a48f9ef9610649d5;hp=1a6b259991d88e3e6f125caf0192cdd123d4ae2a;hpb=fcc48dc4b17b7e0c19c8b4b16c08641761efed49;p=netvirt.git diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java index 1a6b259991..6963239076 100644 --- a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java +++ b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java @@ -7,56 +7,107 @@ */ package org.opendaylight.netvirt.vpnmanager; -import com.google.common.base.*; +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterators; -import com.google.common.util.concurrent.*; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.JdkFutureAdapters; +import com.google.common.util.concurrent.ListenableFuture; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase; +import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator; +import org.opendaylight.genius.mdsalutil.ActionInfo; +import org.opendaylight.genius.mdsalutil.ActionType; +import org.opendaylight.genius.mdsalutil.FlowEntity; +import org.opendaylight.genius.mdsalutil.InstructionInfo; +import org.opendaylight.genius.mdsalutil.InstructionType; +import org.opendaylight.genius.mdsalutil.MDSALUtil; +import org.opendaylight.genius.mdsalutil.MatchFieldType; +import org.opendaylight.genius.mdsalutil.MatchInfo; +import org.opendaylight.genius.mdsalutil.MetaDataUtil; +import org.opendaylight.genius.mdsalutil.NwConstants; +import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; +import org.opendaylight.genius.utils.ServiceIndex; import org.opendaylight.netvirt.bgpmanager.api.IBgpManager; -import org.opendaylight.netvirt.fibmanager.api.RouteOrigin; import org.opendaylight.netvirt.fibmanager.api.IFibManager; +import org.opendaylight.netvirt.fibmanager.api.RouteOrigin; +import org.opendaylight.netvirt.vpnmanager.intervpnlink.InterVpnLinkUtil; import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils; - -import org.opendaylight.controller.md.sal.binding.api.*; -import org.opendaylight.genius.mdsalutil.*; -import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener; +import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig; +import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances; +import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces; import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets; import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance; +import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey; +import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface; +import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpResponseInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpResponseInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.FibRpcService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.LabelRouteMap; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.SubnetRoute; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.SubnetRouteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.label.route.map.LabelRouteInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.label.route.map.LabelRouteInfoBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.label.route.map.LabelRouteInfoKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.*; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEvent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEventBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEvent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEventBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventData; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.Vpn; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey; @@ -68,180 +119,71 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neu import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventData; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry; - -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data - .VpnInstanceOpDataEntryBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpResponseInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpResponseInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; - -import java.math.BigInteger; -import java.util.Collection; -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.concurrent.*; - -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService; -import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VpnInterfaceManager extends AbstractDataChangeListener implements AutoCloseable { +public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase + implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class); - private ListenerRegistration listenerRegistration, opListenerRegistration; - private final DataBroker broker; + private final DataBroker dataBroker; private final IBgpManager bgpManager; - private IFibManager fibManager; - private IMdsalApiManager mdsalManager; - private OdlInterfaceRpcService ifaceMgrRpcService; - private IdManagerService idManager; - private OdlArputilService arpManager; - private NeutronvpnService neuService; - private VpnSubnetRouteHandler vpnSubnetRouteHandler; + private final IFibManager fibManager; + private final IMdsalApiManager mdsalManager; + private final IdManagerService idManager; + private final OdlArputilService arpManager; + private final OdlInterfaceRpcService ifaceMgrRpcService; + private final NotificationPublishService notificationPublishService; private ConcurrentHashMap vpnIntfMap = new ConcurrentHashMap(); private ExecutorService executorService = Executors.newSingleThreadExecutor(); - private InterfaceStateChangeListener interfaceListener; - private SubnetRouteInterfaceStateChangeListener subnetRouteInterfaceListener; - private TunnelInterfaceStateListener tunnelInterfaceStateListener; - private VpnInterfaceOpListener vpnInterfaceOpListener; - private ArpNotificationHandler arpNotificationHandler; - private DpnInVpnChangeListener dpnInVpnChangeListener; - private NotificationPublishService notificationPublishService; - private FibRpcService fibService; - /** - * Responsible for listening to data change related to VPN Interface - * Bind VPN Service on the interface and informs the BGP service - * - * @param db - dataBroker service reference - * @param bgpManager Used to advertise routes to the BGP Router - * @param notificationService Used to subscribe to notification events - */ - public VpnInterfaceManager(final DataBroker db, final IBgpManager bgpManager, NotificationService notificationService) { - super(VpnInterface.class); - broker = db; + public VpnInterfaceManager(final DataBroker dataBroker, + final IBgpManager bgpManager, + final OdlArputilService arpManager, + final IdManagerService idManager, + final IMdsalApiManager mdsalManager, + final IFibManager fibManager, + final OdlInterfaceRpcService ifaceMgrRpcService, + final NotificationPublishService notificationPublishService) { + super(VpnInterface.class, VpnInterfaceManager.class); + this.dataBroker = dataBroker; this.bgpManager = bgpManager; - interfaceListener = new InterfaceStateChangeListener(db, this); - subnetRouteInterfaceListener = new SubnetRouteInterfaceStateChangeListener(db, this); - vpnInterfaceOpListener = new VpnInterfaceOpListener(); - arpNotificationHandler = new ArpNotificationHandler(this, broker); - vpnSubnetRouteHandler = new VpnSubnetRouteHandler(broker, bgpManager, this); - dpnInVpnChangeListener = new DpnInVpnChangeListener(broker); - notificationService.registerNotificationListener(vpnSubnetRouteHandler); - notificationService.registerNotificationListener(arpNotificationHandler); - notificationService.registerNotificationListener(dpnInVpnChangeListener); - registerListener(db); - } - - public void setMdsalManager(IMdsalApiManager mdsalManager) { + this.arpManager = arpManager; + this.idManager = idManager; this.mdsalManager = mdsalManager; - } - - public void setIfaceMgrRpcService(OdlInterfaceRpcService ifMgrRpcService) { - this.ifaceMgrRpcService = ifMgrRpcService; - interfaceListener.setIfaceMgrRpcService(ifMgrRpcService); - } - - public void setFibManager(IFibManager fibManager) { this.fibManager = fibManager; - } - - public IFibManager getFibManager() { - return this.fibManager; - } - - - public void setIdManager(IdManagerService idManager) { - this.idManager = idManager; - vpnSubnetRouteHandler.setIdManager(idManager); - } - - public void setArpManager(OdlArputilService arpManager) { - this.arpManager = arpManager; - } - - void setNotificationPublishService(NotificationPublishService notificationPublishService) { + this.ifaceMgrRpcService = ifaceMgrRpcService; this.notificationPublishService = notificationPublishService; } - public void setNeutronvpnManager(NeutronvpnService neuService) { this.neuService = neuService; } - - public void setFibRpcService(FibRpcService fibService) { - this.fibService = fibService; - } - - public FibRpcService getFibRpcService() { - return fibService; + public void start() { + LOG.info("{} start", getClass().getSimpleName()); + registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker); } - public VpnSubnetRouteHandler getVpnSubnetRouteHandler() { - return this.vpnSubnetRouteHandler; + @Override + protected InstanceIdentifier getWildCardPath() { + return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class); } @Override - public void close() throws Exception { - if (listenerRegistration != null) { - try { - listenerRegistration.close(); - opListenerRegistration.close(); - } catch (final Exception e) { - LOG.error("Error when cleaning up DataChangeListener.", e); - } - listenerRegistration = null; - opListenerRegistration = null; - } - LOG.info("VPN Interface Manager Closed"); + protected VpnInterfaceManager getDataTreeChangeListener() { + return VpnInterfaceManager.this; } - private void registerListener(final DataBroker db) { - try { - listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, - getWildCardPath(), VpnInterfaceManager.this, DataChangeScope.SUBTREE); - opListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, - getWildCardPath(), vpnInterfaceOpListener, DataChangeScope.SUBTREE); - } catch (final Exception e) { - LOG.error("VPN Service DataChange listener registration fail!", e); - throw new IllegalStateException("VPN Service registration Listener failed.", e); - } - } private InstanceIdentifier getInterfaceListenerPath() { return InstanceIdentifier.create(InterfacesState.class) @@ -251,11 +193,12 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier, final VpnInterface vpnInterface) { LOG.trace("VPN Interface add event - key: {}, value: {}" ,identifier, vpnInterface ); + LOG.info("VPN Interface add event - intfName {}" ,vpnInterface.getName()); final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); final String interfaceName = key.getName(); org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState = - InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName); + InterfaceUtils.getInterfaceStateFromOperDS(dataBroker, interfaceName); if(interfaceState != null){ try{ final BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(interfaceState); @@ -265,35 +208,15 @@ public class VpnInterfaceManager extends AbstractDataChangeListener>>() { @Override public List> call() throws Exception { - WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction(); - WriteTransaction writeOperTxn = broker.newWriteOnlyTransaction(); - WriteTransaction writeInvTxn = broker.newWriteOnlyTransaction(); + WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction(); + WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction(); + WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction(); processVpnInterfaceUp(dpnId, vpnInterface, ifIndex, false, writeConfigTxn, writeOperTxn, writeInvTxn); - CheckedFuture futures = writeOperTxn.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error adding oper data for interface {} to vpn {} on dpn {}", interfaceName, - vpnInterface.getVpnInstanceName(), dpnId); - throw new RuntimeException(e.getMessage()); - } - futures = writeConfigTxn.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error adding config data for interface {} to vpn {} on dpn {}", interfaceName, - vpnInterface.getVpnInstanceName(), dpnId); - throw new RuntimeException(e.getMessage()); - } - futures = writeInvTxn.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error adding inventory/flow data for interface {} to vpn {} on dpn {}", interfaceName, - vpnInterface.getVpnInstanceName(), dpnId); - throw new RuntimeException(e.getMessage()); - } - return null; + List> futures = new ArrayList>(); + futures.add(writeOperTxn.submit()); + futures.add(writeConfigTxn.submit()); + futures.add(writeInvTxn.submit()); + return futures; } }); }catch (Exception e){ @@ -309,19 +232,19 @@ public class VpnInterfaceManager extends AbstractDataChangeListener adjs = VpnUtil.getAdjacenciesForVpnInterfaceFromConfig(broker, interfaceName); + List adjs = VpnUtil.getAdjacenciesForVpnInterfaceFromConfig(dataBroker, interfaceName); if (adjs == null) { LOG.info("VPN Interface {} addition failed as adjacencies for this vpn interface could not be obtained", interfaceName); return; @@ -348,8 +271,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener> call() throws Exception { // // If another renderer(for eg : CSS) needs to be supported, check can be performed here // // to call the respective helpers. -// WriteTransaction writeTxn = broker.newWriteOnlyTransaction(); +// WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); // updateDpnDbs(dpnId, vpnName, interfaceName, addToDpn, writeTxn); // List> futures = new ArrayList<>(); // futures.add(writeTxn.submit()); @@ -460,7 +383,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener voids) { -// WriteTransaction writeTxn = broker.newWriteOnlyTransaction(); +// WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); // bindService(dpnId, vpnName, interfaceName, lPortTag, writeTxn); // processVpnInterfaceAdjacencies(dpnId, vpnName, interfaceName, writeTxn); // writeTxn.submit(); @@ -482,13 +405,15 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier, VpnInterface intf) { //Read NextHops InstanceIdentifier path = identifier.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path); + Optional adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path); - String rd = VpnUtil.getVpnRd(broker, intf.getVpnInstanceName()); + String rd = VpnUtil.getVpnRd(dataBroker, intf.getVpnInstanceName()); if (rd == null) { LOG.error("advertiseAdjacenciesForVpnFromBgp: Unable to recover rd for interface {} in vpn {}", intf.getName(), intf.getVpnInstanceName()); @@ -504,7 +429,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier, VpnInterface intf) { //Read NextHops InstanceIdentifier path = identifier.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path); + Optional adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path); - String rd = VpnUtil.getVpnRd(broker, intf.getVpnInstanceName()); + String rd = VpnUtil.getVpnRd(dataBroker, intf.getVpnInstanceName()); if (rd == null) { LOG.error("withdrawAdjacenciesForVpnFromBgp: Unable to recover rd for interface {} in vpn {}", intf.getName(), intf.getVpnInstanceName()); @@ -568,8 +493,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener instructions = new ArrayList(); - - instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(MetaDataUtil.getVpnIdMetadata(vpnId), - MetaDataUtil.METADATA_MASK_VRFID, ++instructionKey)); - instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey)); - - BoundServices - serviceInfo = - InterfaceUtils.getBoundServices(String.format("%s.%s.%s", "vpn",vpnInstanceName, vpnInterfaceName), - NwConstants.L3VPN_SERVICE_INDEX, priority, - NwConstants.COOKIE_VM_INGRESS_TABLE, instructions); - writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, - InterfaceUtils.buildServiceId(vpnInterfaceName, NwConstants.L3VPN_SERVICE_INDEX), serviceInfo, true); - makeArpFlow(dpId, NwConstants.L3VPN_SERVICE_INDEX, lPortTag, vpnInterfaceName, - vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW, writeInvTxn); - makeArpFlow(dpId, NwConstants.L3VPN_SERVICE_INDEX, lPortTag, vpnInterfaceName, - vpnId, ArpReplyOrRequest.REPLY, NwConstants.ADD_FLOW, writeInvTxn); + private void bindService(BigInteger dpId, final String vpnInstanceName, final String vpnInterfaceName, + int lPortTag, WriteTransaction writeConfigTxn, WriteTransaction writeInvTxn) { + final int priority = VpnConstants.DEFAULT_FLOW_PRIORITY; + final long vpnId = VpnUtil.getVpnId(dataBroker, vpnInstanceName); + + DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance(); + dataStoreCoordinator.enqueueJob(vpnInterfaceName, + new Callable>>() { + @Override + public List> call() throws Exception { + WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); + int instructionKey = 0; + List instructions = new ArrayList(); + + instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction( + MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID, ++instructionKey)); + instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_GW_MAC_TABLE, ++instructionKey)); + + BoundServices + serviceInfo = + InterfaceUtils.getBoundServices(String.format("%s.%s.%s", "vpn",vpnInstanceName, vpnInterfaceName), + ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX), priority, + NwConstants.COOKIE_VM_INGRESS_TABLE, instructions); + writeTxn.put(LogicalDatastoreType.CONFIGURATION, + InterfaceUtils.buildServiceId(vpnInterfaceName, ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)), serviceInfo, true); + List> futures = new ArrayList>(); + futures.add(writeTxn.submit()); + return futures; + } + }); + setupGwMacIfExternalVpn(dpId, vpnInterfaceName, vpnId, writeInvTxn, NwConstants.ADD_FLOW); + } + private void setupGwMacIfExternalVpn(BigInteger dpnId, String interfaceName, long vpnId, + WriteTransaction writeInvTxn, int addOrRemove) { + InstanceIdentifier vpnIdsInstanceIdentifier = VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId); + Optional vpnIdsOptional = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier); + if (vpnIdsOptional.isPresent() && vpnIdsOptional.get().isExternalVpn()) { + Optional gwMacAddressOptional = InterfaceUtils.getMacAddressForInterface(dataBroker, interfaceName); + if (!gwMacAddressOptional.isPresent()) { + LOG.error("Failed to get gwMacAddress for interface {}", interfaceName); + return; + } + String gwMacAddress = gwMacAddressOptional.get(); + FlowEntity flowEntity = VpnUtil.buildL3vpnGatewayFlow(dpnId, gwMacAddress, vpnId); + if (addOrRemove == NwConstants.ADD_FLOW) { + mdsalManager.addFlowToTx(flowEntity, writeInvTxn); + } else if (addOrRemove == NwConstants.DEL_FLOW) { + mdsalManager.removeFlowToTx(flowEntity, writeInvTxn); + } + } } - private void processVpnInterfaceAdjacencies(BigInteger dpnId, String vpnName, String interfaceName, + protected void processVpnInterfaceAdjacencies(BigInteger dpnId, String vpnName, String interfaceName, WriteTransaction writeConfigTxn, WriteTransaction writeOperTxn) { InstanceIdentifier identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName); // Read NextHops InstanceIdentifier path = identifier.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, path); + Optional adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path); if (adjacencies.isPresent()) { List nextHops = adjacencies.get().getAdjacency(); @@ -622,13 +574,13 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnsToImportRoute = getVpnsImportingMyRoute(vpnName); + List vpnsToImportRoute = getVpnsImportingMyRoute(vpnName); LOG.trace("NextHops for interface {} are {}", interfaceName, nextHops); for (Adjacency nextHop : nextHops) { @@ -636,6 +588,10 @@ public class VpnInterfaceManager extends AbstractDataChangeListener adjNextHop = nextHop.getNextHopIpList(); value.add(new AdjacencyBuilder(nextHop).setLabel(label).setNextHopIpList( (adjNextHop != null && !adjNextHop.isEmpty()) ? adjNextHop : Arrays.asList(nextHopIp)) @@ -646,7 +602,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener interfaceId = VpnUtil.getVpnInterfaceIdentifier(interfaceName); writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface, true); - long vpnId = VpnUtil.getVpnId(broker, vpnName); + long vpnId = VpnUtil.getVpnId(dataBroker, vpnName); for (Adjacency nextHop : aug.getAdjacency()) { long label = nextHop.getLabel(); - List nextHopList = new ArrayList<>(nextHop.getNextHopIpList()); if (rd != null) { - addToLabelMapper(label, dpnId, nextHop.getIpAddress(), nextHopList, vpnId, + addToLabelMapper(label, dpnId, nextHop.getIpAddress(), Arrays.asList(nextHopIp), vpnId, interfaceName, null,false, rd, writeOperTxn); addPrefixToBGP(rd, nextHop.getIpAddress(), nextHopIp, label, writeConfigTxn); //TODO: ERT - check for VPNs importing my route - for (VpnInstance vpn : vpnsToImportRoute) { - String vpnRd = vpn.getIpv4Family().getRouteDistinguisher(); + for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) { + String vpnRd = vpn.getVrfId(); if (vpnRd != null) { LOG.debug("Exporting route with rd {} prefix {} nexthop {} label {} to VPN {}", vpnRd, nextHop.getIpAddress(), nextHopIp, label, vpn); - fibManager.addOrUpdateFibEntry(broker, vpnRd, nextHop.getIpAddress(), Arrays.asList(nextHopIp), (int) label, + fibManager.addOrUpdateFibEntry(dataBroker, vpnRd, nextHop.getIpAddress(), Arrays.asList(nextHopIp), (int) label, RouteOrigin.SELF_IMPORTED, writeConfigTxn); } } } else { // ### add FIB route directly - fibManager.addOrUpdateFibEntry(broker, vpnName, nextHop.getIpAddress(), Arrays.asList(nextHopIp), + fibManager.addOrUpdateFibEntry(dataBroker, vpnName, nextHop.getIpAddress(), Arrays.asList(nextHopIp), (int) label, RouteOrigin.STATIC, writeConfigTxn); } } } } - private List getVpnsImportingMyRoute(final String vpnName) { - List vpnsToImportRoute = new ArrayList<>(); + private List getVpnsImportingMyRoute(final String vpnName) { + List vpnsToImportRoute = new ArrayList<>(); - InstanceIdentifier id = InstanceIdentifier.builder(VpnInstances.class) - .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); - Optional optVpnInstance = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); - final VpnInstance vpnInstance; - if (optVpnInstance.isPresent()) { - vpnInstance = optVpnInstance.get(); - } else { - LOG.debug("Could not retrieve vpn instance {} to check for vpns importing the routes", vpnName); + final String vpnRd = VpnUtil.getVpnRd(dataBroker, vpnName); + final VpnInstanceOpDataEntry vpnInstanceOpDataEntry = VpnUtil.getVpnInstanceOpData(dataBroker, vpnRd); + if (vpnInstanceOpDataEntry == null) { + LOG.debug("Could not retrieve vpn instance op data for {} to check for vpns importing the routes", vpnName); return vpnsToImportRoute; } - Predicate excludeVpn = new Predicate() { + Predicate excludeVpn = new Predicate() { @Override - public boolean apply(VpnInstance input) { + public boolean apply(VpnInstanceOpDataEntry input) { + if (input.getVpnInstanceName() == null) { + LOG.error("Received vpn instance without identity"); + return false; + } return !input.getVpnInstanceName().equals(vpnName); } }; - Predicate matchRTs = new Predicate() { + Predicate matchRTs = new Predicate() { @Override - public boolean apply(VpnInstance input) { - Iterable commonRTs = intersection(getRts(vpnInstance, VpnTarget.VrfRTType.ExportExtcommunity), + public boolean apply(VpnInstanceOpDataEntry input) { + Iterable commonRTs = intersection(getRts(vpnInstanceOpDataEntry, VpnTarget.VrfRTType.ExportExtcommunity), getRts(input, VpnTarget.VrfRTType.ImportExtcommunity)); return Iterators.size(commonRTs.iterator()) > 0; } }; - Function toInstanceName = new Function() { + Function toInstanceName = new Function() { @Override - public String apply(VpnInstance vpnInstance) { + public String apply(VpnInstanceOpDataEntry vpnInstance) { //return vpnInstance.getVpnInstanceName(); - return vpnInstance.getIpv4Family().getRouteDistinguisher(); + return vpnInstance.getVrfId(); } }; - vpnsToImportRoute = FluentIterable.from(VpnUtil.getAllVpnInstance(broker)). + vpnsToImportRoute = FluentIterable.from(VpnUtil.getAllVpnInstanceOpData(dataBroker)). filter(excludeVpn). filter(matchRTs).toList(); return vpnsToImportRoute; } - private List getVpnsExportingMyRoute(final String vpnName) { - List vpnsToExportRoute = new ArrayList<>(); + private List getVpnsExportingMyRoute(final String vpnName) { + List vpnsToExportRoute = new ArrayList<>(); - InstanceIdentifier id = InstanceIdentifier.builder(VpnInstances.class) - .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); - Optional optVpnInstance = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); - final VpnInstance vpnInstance; - if (optVpnInstance.isPresent()) { - vpnInstance = optVpnInstance.get(); - } else { - LOG.debug("Could not retrieve vpn instance {} to check for vpns exporting the routes", vpnName); + String vpnRd = VpnUtil.getVpnRd(dataBroker, vpnName); + final VpnInstanceOpDataEntry vpnInstanceOpDataEntry = VpnUtil.getVpnInstanceOpData(dataBroker, vpnRd); + if (vpnInstanceOpDataEntry == null) { + LOG.debug("Could not retrieve vpn instance op data for {} to check for vpns exporting the routes", vpnName); return vpnsToExportRoute; } - Predicate excludeVpn = new Predicate() { + Predicate excludeVpn = new Predicate() { @Override - public boolean apply(VpnInstance input) { + public boolean apply(VpnInstanceOpDataEntry input) { + if (input.getVpnInstanceName() == null) { + LOG.error("Received vpn instance without identity"); + return false; + } return !input.getVpnInstanceName().equals(vpnName); } }; - Predicate matchRTs = new Predicate() { + Predicate matchRTs = new Predicate() { @Override - public boolean apply(VpnInstance input) { - Iterable commonRTs = intersection(getRts(vpnInstance, VpnTarget.VrfRTType.ImportExtcommunity), + public boolean apply(VpnInstanceOpDataEntry input) { + Iterable commonRTs = intersection(getRts(vpnInstanceOpDataEntry, VpnTarget.VrfRTType.ImportExtcommunity), getRts(input, VpnTarget.VrfRTType.ExportExtcommunity)); return Iterators.size(commonRTs.iterator()) > 0; } }; - Function toInstanceName = new Function() { + Function toInstanceName = new Function() { @Override - public String apply(VpnInstance vpnInstance) { + public String apply(VpnInstanceOpDataEntry vpnInstance) { return vpnInstance.getVpnInstanceName(); } }; - vpnsToExportRoute = FluentIterable.from(VpnUtil.getAllVpnInstance(broker)). + vpnsToExportRoute = FluentIterable.from(VpnUtil.getAllVpnInstanceOpData(dataBroker)). filter(excludeVpn). filter(matchRTs).toList(); return vpnsToExportRoute; @@ -788,25 +743,20 @@ public class VpnInterfaceManager extends AbstractDataChangeListener getRts(VpnInstance vpnInstance, VpnTarget.VrfRTType rtType) { + private List getRts(VpnInstanceOpDataEntry vpnInstance, VpnTarget.VrfRTType rtType) { String name = vpnInstance.getVpnInstanceName(); List rts = new ArrayList<>(); - VpnAfConfig vpnConfig = vpnInstance.getIpv4Family(); - if (vpnConfig == null) { - LOG.trace("vpn config is not available for {}", name); - return rts; - } - VpnTargets targets = vpnConfig.getVpnTargets(); + org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnTargets targets = vpnInstance.getVpnTargets(); if (targets == null) { LOG.trace("vpn targets not available for {}", name); return rts; } - List vpnTargets = targets.getVpnTarget(); + List vpnTargets = targets.getVpnTarget(); if (vpnTargets == null) { LOG.trace("vpnTarget values not available for {}", name); return rts; } - for (VpnTarget target : vpnTargets) { + for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget target : vpnTargets) { //TODO: Check for RT type is Both if(target.getVrfRTType().equals(rtType) || target.getVrfRTType().equals(VpnTarget.VrfRTType.Both)) { @@ -816,7 +766,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener getExportRts(VpnInstance vpnInstance) { List exportRts = new ArrayList<>(); VpnAfConfig vpnConfig = vpnInstance.getIpv4Family(); @@ -831,111 +781,97 @@ public class VpnInterfaceManager extends AbstractDataChangeListener matches = new ArrayList(); - BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lPortTag, ++sIndex, MetaDataUtil.getVpnIdMetadata(vpnId)); - BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX, - MetaDataUtil.METADATA_MASK_LPORT_TAG, MetaDataUtil.METADATA_MASK_VRFID); - - // Matching Arp reply flows - matches.add(new MatchInfo(MatchFieldType.eth_type, new long[] { NwConstants.ETHTYPE_ARP })); - matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] { - metadata, metadataMask })); - - matches.add(new MatchInfo(MatchFieldType.arp_op, new long[] { replyOrRequest.getArpOperation() })); - - // Instruction to punt to controller - List instructions = new ArrayList(); - List actionsInfos = new ArrayList(); - actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, new String[] {})); - actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{ - Short.toString(NwConstants.LPORT_DISPATCHER_TABLE)})); - - instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos)); - - // Install the flow entry in L3_INTERFACE_TABLE - String flowRef = VpnUtil.getFlowRef(dpId, NwConstants.L3_INTERFACE_TABLE, - NwConstants.ETHTYPE_ARP, lPortTag, replyOrRequest.getArpOperation()); - FlowEntity flowEntity; - flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_INTERFACE_TABLE, flowRef, - NwConstants.DEFAULT_ARP_FLOW_PRIORITY, replyOrRequest.getName(), 0, 0, - VpnUtil.getCookieArpFlow(lPortTag), matches, instructions); - - Flow flow = flowEntity.getFlowBuilder().build(); - String flowId = flowEntity.getFlowId(); - FlowKey flowKey = new FlowKey( new FlowId(flowId)); - Node nodeDpn = buildDpnNode(dpId); - - InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) - .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class) - .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flowKey).build(); - - if (writeConfigTxn != null) { - if (addOrRemoveFlow == NwConstants.ADD_FLOW) { - LOG.debug("Creating ARP Flow for interface {}", vpnInterfaceName); - writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true); - } else { - LOG.debug("Deleting ARP Flow for interface {}", vpnInterfaceName); - writeConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId); - } - } else { - if (addOrRemoveFlow == NwConstants.ADD_FLOW) { - LOG.debug("Creating ARP Flow for interface {}",vpnInterfaceName); - mdsalManager.installFlow(flowEntity); - } else { - LOG.debug("Deleting ARP Flow for interface {}",vpnInterfaceName); - mdsalManager.removeFlow(flowEntity); - } - } - } - - //TODO: How to handle the below code, its a copy paste from MDSALManager.java - private Node buildDpnNode(BigInteger dpnId) { - NodeId nodeId = new NodeId("openflow:" + dpnId); - Node nodeDpn = new NodeBuilder().setId(nodeId).setKey(new NodeKey(nodeId)).build(); - - return nodeDpn; - } - private String getRouteDistinguisher(String vpnName) { InstanceIdentifier id = InstanceIdentifier.builder(VpnInstances.class) .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build(); - Optional vpnInstance = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); - String rd = ""; + Optional vpnInstance = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id); + String rd = null; if(vpnInstance.isPresent()) { VpnInstance instance = vpnInstance.get(); - VpnAfConfig config = instance.getIpv4Family(); + org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig config = instance.getIpv4Family(); rd = config.getRouteDistinguisher(); } return rd; } + /** + * JobCallback class is used as a future callback for + * main and rollback workers to handle success and failure. + */ + private class DpnEnterExitVpnWorker implements FutureCallback> { + BigInteger dpnId; + String vpnName; + String rd; + boolean entered; + + public DpnEnterExitVpnWorker(BigInteger dpnId, String vpnName, String rd, boolean entered) { + this.entered = entered; + this.dpnId = dpnId; + this.vpnName = vpnName; + this.rd = rd; + } + + /** + * @param voids + * This implies that all the future instances have returned success. -- TODO: Confirm this + */ + @Override + public void onSuccess(List voids) { + if (entered) { + publishAddNotification(dpnId, vpnName, rd); + } else { + publishRemoveNotification(dpnId, vpnName, rd); + } + } + + /** + * + * @param throwable + * This method is used to handle failure callbacks. + * If more retry needed, the retrycount is decremented and mainworker is executed again. + * After retries completed, rollbackworker is executed. + * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored. + */ + @Override + public void onFailure(Throwable throwable) { + LOG.warn("Job: failed with exception: {}", throwable.getStackTrace()); + } + } + private void createOrUpdateVpnToDpnList(long vpnId, BigInteger dpnId, String intfName, String vpnName) { String routeDistinguisher = getRouteDistinguisher(vpnName); String rd = (routeDistinguisher == null) ? vpnName : routeDistinguisher; Boolean newDpnOnVpn = Boolean.FALSE; - + synchronized (vpnName.intern()) { - WriteTransaction writeTxn = broker.newWriteOnlyTransaction(); + WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); InstanceIdentifier id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId); - Optional dpnInVpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); + Optional dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data .entry.vpn.to.dpn.list.VpnInterfaces vpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build(); if (dpnInVpn.isPresent()) { + VpnToDpnList vpnToDpnList = dpnInVpn.get(); + List vpnInterfaces = vpnToDpnList.getVpnInterfaces(); + if (vpnInterfaces == null) { + vpnInterfaces = new ArrayList<>(); + } + vpnInterfaces.add(vpnInterface); + VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList); + vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces); + if (writeTxn != null) { - writeTxn.put(LogicalDatastoreType.OPERATIONAL, id.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance - .op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class, - new VpnInterfacesKey(intfName)), vpnInterface, true); + writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true); } else { - VpnUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance - .op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class, - new VpnInterfacesKey(intfName)), vpnInterface); + VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build()); + } + /* If earlier state was inactive, it is considered new DPN coming back to the + * same VPN + */ + if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) { + newDpnOnVpn = Boolean.TRUE; } } else { List id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId); - Optional dpnInVpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); - WriteTransaction writeTxn = broker.newWriteOnlyTransaction(); + Optional dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id); + WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); if (dpnInVpn.isPresent()) { List vpnInterfaces = dpnInVpn.get().getVpnInterfaces(); @@ -994,7 +928,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnsToExportRoute = getVpnsExportingMyRoute(vpnName); - for (VpnInstance vpn : vpnsToExportRoute) { - String rd = vpn.getIpv4Family().getRouteDistinguisher(); - List vrfEntries = VpnUtil.getAllVrfEntries(broker, vpn.getIpv4Family().getRouteDistinguisher()); - WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction(); + List vpnsToExportRoute = getVpnsExportingMyRoute(vpnName); + for (VpnInstanceOpDataEntry vpn : vpnsToExportRoute) { + String rd = vpn.getVrfId(); + List vrfEntries = VpnUtil.getAllVrfEntries(dataBroker, vpn.getVrfId()); + WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction(); if (vrfEntries != null) { for (VrfEntry vrfEntry : vrfEntries) { try { @@ -1049,10 +982,10 @@ public class VpnInterfaceManager extends AbstractDataChangeListener getWildCardPath() { - return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class); - } - @Override public void remove( InstanceIdentifier identifier, VpnInterface vpnInterface) { LOG.trace("Remove event - key: {}, value: {}" ,identifier, vpnInterface ); + LOG.info("VPN Interface remove event - intfName {}" ,vpnInterface.getName()); final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); final String interfaceName = key.getName(); InstanceIdentifier interfaceId = VpnUtil.getVpnInterfaceIdentifier(interfaceName); - final Optional optVpnInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, interfaceId); + final Optional optVpnInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, interfaceId); org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState = - InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName); + InterfaceUtils.getInterfaceStateFromOperDS(dataBroker, interfaceName); if (optVpnInterface.isPresent()){ BigInteger dpnId = BigInteger.ZERO; Boolean dpnIdRetrieved = Boolean.FALSE; @@ -1119,35 +1048,15 @@ public class VpnInterfaceManager extends AbstractDataChangeListener>>() { @Override public List> call() throws Exception { - WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction(); - WriteTransaction writeOperTxn = broker.newWriteOnlyTransaction(); - WriteTransaction writeInvTxn = broker.newWriteOnlyTransaction(); + WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction(); + WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction(); + WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction(); processVpnInterfaceDown(dpId, interfaceName, ifIndex, false, true, writeConfigTxn, writeOperTxn, writeInvTxn); - CheckedFuture futures = writeOperTxn.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error removing Oper data for interface {} from vpn {} on dpn {}", interfaceName, - vpnOpInterface.getVpnInstanceName(), dpId); - throw new RuntimeException(e.getMessage()); - } - futures = writeConfigTxn.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error removing Config data for interface {} from vpn {} on dpn {}", interfaceName, - vpnOpInterface.getVpnInstanceName(), dpId); - throw new RuntimeException(e.getMessage()); - } - futures = writeInvTxn.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error removing Inventory/Flow data for interface {} from vpn {} on dpn {}", interfaceName, - vpnOpInterface.getVpnInstanceName(), dpId); - throw new RuntimeException(e.getMessage()); - } - return null; + List> futures = new ArrayList>(); + futures.add(writeOperTxn.submit()); + futures.add(writeConfigTxn.submit()); + futures.add(writeInvTxn.submit()); + return futures; } }); @@ -1156,24 +1065,24 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName); if (!isInterfaceStateDown) { - VpnInterface vpnInterface = VpnUtil.getOperationalVpnInterface(broker, interfaceName); + VpnInterface vpnInterface = VpnUtil.getOperationalVpnInterface(dataBroker, interfaceName); if(vpnInterface == null){ LOG.info("Unable to process delete/down for interface {} as it is not available in operational data store", interfaceName); return; }else{ final String vpnName = vpnInterface.getVpnInstanceName(); if(!vpnInterface.isScheduledForRemove()){ - VpnUtil.scheduleVpnInterfaceForRemoval(broker, interfaceName, dpId, vpnName, Boolean.TRUE, writeOperTxn); + VpnUtil.scheduleVpnInterfaceForRemoval(dataBroker, interfaceName, dpId, vpnName, Boolean.TRUE, writeOperTxn); removeAdjacenciesFromVpn(dpId, interfaceName, vpnInterface.getVpnInstanceName(), writeConfigTxn); LOG.info("Unbinding vpn service from interface {} ", interfaceName); unbindService(dpId, vpnName, interfaceName, lPortTag, isInterfaceStateDown, isConfigRemoval, writeConfigTxn, writeInvTxn); @@ -1185,7 +1094,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName); InstanceIdentifier path = identifier.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path); + Optional adjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path); - String rd = VpnUtil.getVpnRd(broker, vpnName); + String rd = VpnUtil.getVpnRd(dataBroker, vpnName); LOG.trace("removeAdjacenciesFromVpn: For interface {} RD recovered for vpn {} as rd {}", interfaceName, vpnName, rd); if (adjacencies.isPresent()) { @@ -1232,7 +1141,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener nhList = new ArrayList(); if (nextHop.getMacAddress() == null || nextHop.getMacAddress().isEmpty()) { // This is either an extra-route (or) a learned IP via subnet-route - String nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId); + String nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, dpnId); if (nextHopIp == null || nextHopIp.isEmpty()) { LOG.error("Unable to obtain nextHopIp for extra-route/learned-route in rd {} prefix {}", rd, nextHop.getIpAddress()); @@ -1247,29 +1156,29 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnsToImportRoute = getVpnsImportingMyRoute(vpnName); + List vpnsToImportRoute = getVpnsImportingMyRoute(vpnName); for (String nh : nhList) { //IRT: remove routes from other vpns importing it removePrefixFromBGP(rd, nextHop.getIpAddress(), nh, writeConfigTxn); - for (VpnInstance vpn : vpnsToImportRoute) { - String vpnRd = vpn.getIpv4Family().getRouteDistinguisher(); + for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) { + String vpnRd = vpn.getVrfId(); if (vpnRd != null) { LOG.info("Removing Exported route with rd {} prefix {} from VPN {}", vpnRd, nextHop.getIpAddress(), vpn.getVpnInstanceName()); - fibManager.removeOrUpdateFibEntry(broker, vpnRd, nextHop.getIpAddress(), nh, writeConfigTxn); + fibManager.removeOrUpdateFibEntry(dataBroker, vpnRd, nextHop.getIpAddress(), nh, writeConfigTxn); } } } } String ip = nextHop.getIpAddress().split("/")[0]; - VpnPortipToPort vpnPortipToPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(broker, + VpnPortipToPort vpnPortipToPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, vpnName, ip); if (vpnPortipToPort != null && !vpnPortipToPort.isConfig()) { LOG.trace("VpnInterfaceManager removing adjacency for Interface {} ip {} from VpnPortData Entry", vpnPortipToPort.getPortName(),ip); - VpnUtil.removeVpnPortFixedIpToPort(broker, vpnName, ip); + VpnUtil.removeVpnPortFixedIpToPort(dataBroker, vpnName, ip); } } } @@ -1277,26 +1186,36 @@ public class VpnInterfaceManager extends AbstractDataChangeListener>>() { + @Override + public List> call() throws Exception { + WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction(); + writeTxn.delete(LogicalDatastoreType.CONFIGURATION, + InterfaceUtils.buildServiceId(vpnInterfaceName, + ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX))); + + List> futures = new ArrayList>(); + futures.add(writeTxn.submit()); + return futures; + } + }); } - long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName); - makeArpFlow(dpId, NwConstants.L3VPN_SERVICE_INDEX, lPortTag, vpnInterfaceName, - vpnId, ArpReplyOrRequest.REQUEST, NwConstants.DEL_FLOW, writeInvTxn); - makeArpFlow(dpId, NwConstants.L3VPN_SERVICE_INDEX, lPortTag, vpnInterfaceName, - vpnId, ArpReplyOrRequest.REPLY, NwConstants.DEL_FLOW, writeInvTxn); + long vpnId = VpnUtil.getVpnId(dataBroker, vpnInstanceName); + setupGwMacIfExternalVpn(dpId, vpnInterfaceName, vpnId, writeConfigTxn, NwConstants.DEL_FLOW); } private void removePrefixFromBGP(String rd, String prefix, String nextHop, WriteTransaction writeConfigTxn) { try { LOG.info("VPN WITHDRAW: Removing Fib Entry rd {} prefix {}", rd, prefix); - fibManager.removeOrUpdateFibEntry(broker, rd, prefix, nextHop, writeConfigTxn); + fibManager.removeOrUpdateFibEntry(dataBroker, rd, prefix, nextHop, writeConfigTxn); bgpManager.withdrawPrefix(rd, prefix); // TODO: Might be needed to include nextHop here LOG.info("VPN WITHDRAW: Removed Fib Entry rd {} prefix {}", rd, prefix); } catch(Exception e) { @@ -1307,16 +1226,19 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier, VpnInterface original, VpnInterface update) { LOG.trace("Updating VPN Interface : key {}, original value={}, update value={}", identifier, original, update); + LOG.info("VPN Interface update event - intfName {}" ,update.getName()); String oldVpnName = original.getVpnInstanceName(); String newVpnName = update.getVpnInstanceName(); BigInteger dpnId = update.getDpnId(); - List oldAdjs = original.getAugmentation(Adjacencies.class).getAdjacency(); - List newAdjs = update.getAugmentation(Adjacencies.class).getAdjacency(); - if (oldAdjs == null) { - oldAdjs = new ArrayList<>(); + List oldAdjsList = new ArrayList<>(); + List newAdjsList = new ArrayList<>(); + Adjacencies oldAdjs = original.getAugmentation(Adjacencies.class); + Adjacencies newAdjs = update.getAugmentation(Adjacencies.class); + if (oldAdjs != null) { + oldAdjsList = oldAdjs.getAdjacency(); } - if (newAdjs == null) { - newAdjs = new ArrayList<>(); + if (newAdjs != null) { + newAdjsList = newAdjs.getAdjacency(); } //handles switching between if (!oldVpnName.equals(newVpnName)) { @@ -1326,16 +1248,16 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnInstanceNames = Arrays.asList(vpnInstanceOpDataEntry.getVpnInstanceName()); lriBuilder.setVpnInstanceList(vpnInstanceNames); @@ -1410,14 +1332,14 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vrfEntryList = Arrays.asList(vrfEntry); @@ -1442,24 +1364,24 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnsToImportRoute = getVpnsImportingMyRoute(vpnName); + List vpnsToImportRoute = getVpnsImportingMyRoute(vpnName); if (vpnsToImportRoute.size() > 0) { VrfEntry importingVrfEntry = new VrfEntryBuilder().setDestPrefix(prefix).setNextHopAddressList(Arrays.asList(nextHop)) .setLabel((long) label).setOrigin(RouteOrigin.SELF_IMPORTED.getValue()) .addAugmentation(SubnetRoute.class, route).build(); List importingVrfEntryList = Arrays.asList(importingVrfEntry); - for (VpnInstance vpnInstance : vpnsToImportRoute) { + for (VpnInstanceOpDataEntry vpnInstance : vpnsToImportRoute) { LOG.info("Exporting subnet route rd {} prefix {} nexthop {} label {} to vpn {}", rd, prefix, nextHop, label, vpnInstance.getVpnInstanceName()); - String importingRd = vpnInstance.getIpv4Family().getRouteDistinguisher(); + String importingRd = vpnInstance.getVrfId(); InstanceIdentifier importingVrfTableId = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(importingRd)).build(); VrfTables importingVrfTable = new VrfTablesBuilder().setRouteDistinguisher(importingRd).setVrfEntry(importingVrfEntryList).build(); if (writeTxn != null) { writeTxn.merge(LogicalDatastoreType.CONFIGURATION, importingVrfTableId, importingVrfTable, true); } else { - VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, importingVrfTableId, importingVrfTable); + VpnUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, importingVrfTableId, importingVrfTable); } } } @@ -1482,34 +1404,38 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnsToImportRoute = getVpnsImportingMyRoute(vpnName); - for (VpnInstance vpnInstance : vpnsToImportRoute) { - String importingRd = vpnInstance.getIpv4Family().getRouteDistinguisher(); + public void deleteSubnetRouteFibEntryFromDS(String rd, String prefix, String vpnName){ + fibManager.removeFibEntry(dataBroker, rd, prefix, null); + List vpnsToImportRoute = getVpnsImportingMyRoute(vpnName); + for (VpnInstanceOpDataEntry vpnInstance : vpnsToImportRoute) { + String importingRd = vpnInstance.getVrfId(); LOG.info("Deleting imported subnet route rd {} prefix {} from vpn {}", rd, prefix, vpnInstance.getVpnInstanceName()); - fibManager.removeOrUpdateFibEntry(broker, importingRd, prefix, null /* nextHopToRemove */, null); + fibManager.removeFibEntry(dataBroker, importingRd, prefix, null); } } - protected void addNewAdjToVpnInterface(InstanceIdentifier identifier, Adjacency adj, BigInteger dpnId) { + protected void addNewAdjToVpnInterface(InstanceIdentifier identifier, Adjacency adj) { - Optional optVpnInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, identifier); + Optional optVpnInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, identifier); if (optVpnInterface.isPresent()) { VpnInterface currVpnIntf = optVpnInterface.get(); String prefix = VpnUtil.getIpPrefix(adj.getIpAddress()); String rd = getRouteDistinguisher(currVpnIntf.getVpnInstanceName()); + rd = (rd != null) ? rd : currVpnIntf.getVpnInstanceName(); InstanceIdentifier adjPath = identifier.augmentation(Adjacencies.class); - Optional optAdjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, adjPath); + Optional optAdjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, adjPath); long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, - VpnUtil.getNextHopLabelKey((rd != null) ? rd : currVpnIntf.getVpnInstanceName(), prefix)); - + VpnUtil.getNextHopLabelKey(rd, prefix)); + if (label == 0) { + LOG.error("Unable to fetch label from Id Manager. Bailing out of adding new adjacency {} to vpn interface {} for vpn {}", adj.getIpAddress(), currVpnIntf.getName(), currVpnIntf.getVpnInstanceName()); + return; + } List adjacencies; if (optAdjacencies.isPresent()) { adjacencies = optAdjacencies.get().getAdjacency(); @@ -1519,32 +1445,45 @@ public class VpnInterfaceManager extends AbstractDataChangeListener identifier, Adjacency adj, BigInteger dpnId) { - Optional optVpnInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, identifier); + Optional optVpnInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, identifier); if (optVpnInterface.isPresent()) { VpnInterface currVpnIntf = optVpnInterface.get(); InstanceIdentifier path = identifier.augmentation(Adjacencies.class); - Optional optAdjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path); + Optional optAdjacencies = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path); if (optAdjacencies.isPresent()) { List adjacencies = optAdjacencies.get().getAdjacency(); if (!adjacencies.isEmpty()) { String rd = getRouteDistinguisher(currVpnIntf.getVpnInstanceName()); + rd = (rd != null) ? rd :currVpnIntf.getVpnInstanceName(); LOG.trace("Adjacencies are " + adjacencies); Iterator adjIt = adjacencies.iterator(); while (adjIt.hasNext()) { @@ -1557,11 +1496,13 @@ public class VpnInterfaceManager extends AbstractDataChangeListener nextHopIpList = Arrays.asList(nextHop); if (rd != null) { /* Label mapper is required only for BGP VPN and not for Internal VPN */ - addToLabelMapper((long) label, dpnId, destination, nextHopIpList, VpnUtil.getVpnId(broker, routerID), + addToLabelMapper((long) label, dpnId, destination, nextHopIpList, VpnUtil.getVpnId(dataBroker, routerID), intfName, null, false, rd, null); } // TODO (eperefr): This is a limitation to be stated in docs. When configuring static route to go to // another VPN, there can only be one nexthop or, at least, the nexthop to the interVpnLink should be in // first place. - InterVpnLink interVpnLink = VpnUtil.getInterVpnLinkByEndpointIp(broker, nextHop); - if ( interVpnLink != null ) { + Optional optInterVpnLink = InterVpnLinkUtil.getInterVpnLinkByEndpointIp(dataBroker, nextHop); + if ( optInterVpnLink.isPresent() ) { + InterVpnLink interVpnLink = optInterVpnLink.get(); // If the nexthop is the endpoint of Vpn2, then prefix must be advertised to Vpn1 in DC-GW, with nexthops // pointing to the DPNs where Vpn1 is instantiated. LFIB in these DPNS must have a flow entry, with lower // priority, where if Label matches then sets the lportTag of the Vpn2 endpoint and goes to LportDispatcher @@ -1615,24 +1557,28 @@ public class VpnInterfaceManager extends AbstractDataChangeListener { - - public VpnInterfaceOpListener() { - super(VpnInterface.class); - } - - @Override - protected void remove(final InstanceIdentifier identifier, final VpnInterface del) { - final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); - final String interfaceName = key.getName(); - final String vpnName = del.getVpnInstanceName(); - DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance(); - dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName, - new Callable>>() { - @Override - public List> call() throws Exception { - WriteTransaction writeOperTxn = broker.newWriteOnlyTransaction(); - postProcessVpnInterfaceRemoval(identifier, del, writeOperTxn); - CheckedFuture futures = writeOperTxn.submit(); - try { - futures.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.error("Error handling removal of oper data for interface {} from vpn {}", interfaceName, - vpnName); - throw new RuntimeException(e.getMessage()); - } - return null; - } - }); - } - - private void postProcessVpnInterfaceRemoval(InstanceIdentifier identifier, VpnInterface del, - WriteTransaction writeOperTxn) { - final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); - String interfaceName = key.getName(); - String vpnName = del.getVpnInstanceName(); - - LOG.trace("VpnInterfaceOpListener removed: interface name {} vpnName {}", interfaceName, vpnName); - //decrement the vpn interface count in Vpn Instance Op Data - InstanceIdentifier - id = VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnName); - Optional vpnInstance - = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); - - if (vpnInstance.isPresent()) { - String rd = null; - rd = vpnInstance.get().getVrfId(); - //String rd = getRouteDistinguisher(del.getVpnInstanceName()); - - VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd); - LOG.trace("VpnInterfaceOpListener removed: interface name {} rd {} vpnName {} in Vpn Op Instance {}", - interfaceName, rd, vpnName, vpnInstOp); - - if (vpnInstOp != null) { - // Vpn Interface removed => No more adjacencies from it. - // Hence clean up interface from vpn-dpn-interface list. - Adjacency adjacency = del.getAugmentation(Adjacencies.class).getAdjacency().get(0); - List prefixToInterface = new ArrayList<>(); - Optional prefix = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), - VpnUtil.getIpPrefix(adjacency.getIpAddress()))); - if (prefix.isPresent()) { - prefixToInterface.add(prefix.get()); - } - if (prefixToInterface.isEmpty()) { - for (String nh : adjacency.getNextHopIpList()) { - prefix = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), - VpnUtil.getIpPrefix(nh))); - if (prefix.isPresent()) - prefixToInterface.add(prefix.get()); - } - } - for (Prefixes pref : prefixToInterface) { - if (writeOperTxn != null) { - writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress())); - } else { - VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()), - VpnUtil.DEFAULT_CALLBACK); - } - updateVpnToDpnMapping(pref.getDpnId(), del.getVpnInstanceName(), interfaceName, false /* delete */); - } - } - } else { - LOG.error("rd not retrievable as vpninstancetovpnid for vpn {} is absent, trying rd as ", vpnName, vpnName); - } - notifyTaskIfRequired(interfaceName); - } - - private void notifyTaskIfRequired(String intfName) { - Runnable notifyTask = vpnIntfMap.remove(intfName); - if (notifyTask == null) { - LOG.trace("VpnInterfaceOpListener update: No Notify Task queued for vpnInterface {}", intfName); - return; - } - executorService.execute(notifyTask); - } - - @Override - protected void update(final InstanceIdentifier identifier, final VpnInterface original, - final VpnInterface update) { - final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); - final String interfaceName = key.getName(); - - if (original.getVpnInstanceName().equals(update.getVpnInstanceName())) { - return; - } - - final String vpnName = update.getVpnInstanceName(); - DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance(); - dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName, - new Callable>>() { - @Override - public List> call() throws Exception { - postProcessVpnInterfaceUpdate(identifier, original, update); - return null; - } - }); - } - - private void postProcessVpnInterfaceUpdate(InstanceIdentifier identifier, VpnInterface original, - VpnInterface update) { - final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class); - String interfaceName = key.getName(); - - //increment the vpn interface count in Vpn Instance Op Data - VpnInstanceOpDataEntry vpnInstOp = null; - InstanceIdentifier - origId = VpnUtil.getVpnInstanceToVpnIdIdentifier(original.getVpnInstanceName()); - Optional origVpnInstance - = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, origId); - - if (origVpnInstance.isPresent()) { - String rd = null; - rd = origVpnInstance.get().getVrfId(); - - vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd); - LOG.trace("VpnInterfaceOpListener updated: interface name {} original rd {} original vpnName {}", - interfaceName, rd, original.getVpnInstanceName()); - - if (vpnInstOp != null) { - Adjacency adjacency = original.getAugmentation(Adjacencies.class).getAdjacency().get(0); - List prefixToInterfaceList = new ArrayList<>(); - Optional prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), - VpnUtil.getIpPrefix(adjacency.getIpAddress()))); - if (prefixToInterface.isPresent()) { - prefixToInterfaceList.add(prefixToInterface.get()); - } else { - for (String adj : adjacency.getNextHopIpList()) { - prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, - VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), - VpnUtil.getIpPrefix(adj))); - if (prefixToInterface.isPresent()) { - prefixToInterfaceList.add(prefixToInterface.get()); - } - } - } - for (Prefixes prefix : prefixToInterfaceList) { - updateVpnToDpnMapping(prefix.getDpnId(), original.getVpnInstanceName(), interfaceName, false /* delete */); - } - } - } - notifyTaskIfRequired(interfaceName); - } - - @Override - protected void add(InstanceIdentifier identifier, VpnInterface add) { + fibManager.removeOrUpdateFibEntry(dataBroker, routerID, destination, nextHop, null); } } @@ -1880,7 +1649,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener routerDpnListIdentifier = getRouterDpnId(routerName, dpId); - Optional optionalRouterDpnList = VpnUtil.read(broker, LogicalDatastoreType + Optional optionalRouterDpnList = VpnUtil.read(dataBroker, LogicalDatastoreType .OPERATIONAL, routerDpnListIdentifier); RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName)).setInterface(vpnInterfaceName).build(); if (optionalRouterDpnList.isPresent()) { @@ -1906,7 +1675,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener routerDpnListIdentifier = getRouterDpnId(routerName, dpId); - Optional optionalRouterDpnList = VpnUtil.read(broker, LogicalDatastoreType + Optional optionalRouterDpnList = VpnUtil.read(dataBroker, LogicalDatastoreType .OPERATIONAL, routerDpnListIdentifier); if (optionalRouterDpnList.isPresent()) { List routerInterfaces = optionalRouterDpnList.get().getRouterInterfaces(); @@ -1917,7 +1686,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener routerDpnListIdentifier = getRouterDpnId(routerName, dpId); - Optional optionalRouterDpnList = VpnUtil.read(broker, LogicalDatastoreType + Optional optionalRouterDpnList = VpnUtil.read(dataBroker, LogicalDatastoreType .OPERATIONAL, routerDpnListIdentifier); if (optionalRouterDpnList.isPresent()) { List routerInterfaces = optionalRouterDpnList.get().getRouterInterfaces(); @@ -1958,58 +1727,11 @@ public class VpnInterfaceManager extends AbstractDataChangeListener vpnIfId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface); - InstanceIdentifier path = vpnIfId.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, path); - String nextHopIpAddr = null; - String nextHopMacAddress = null; - String ip = prefix.getIpv4Address().getValue(); - if (adjacencies.isPresent()) { - List adjacencyList = adjacencies.get().getAdjacency(); - ip = VpnUtil.getIpPrefix(ip); - for (Adjacency adjacs : adjacencyList) { - if (adjacs.getMacAddress() != null && !adjacs.getMacAddress().isEmpty()) { - nextHopIpAddr = adjacs.getIpAddress(); - nextHopMacAddress = adjacs.getMacAddress(); - break; - } - } - if (nextHopMacAddress != null && ip != null) { - String rd = VpnUtil.getVpnRd(broker, vpnName); - long label = - VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, - VpnUtil.getNextHopLabelKey((rd != null) ? rd : vpnName, ip)); - String nextHopIp = nextHopIpAddr.split("/")[0]; - Adjacency newAdj = new AdjacencyBuilder().setIpAddress(ip).setKey - (new AdjacencyKey(ip)).setNextHopIpList(Arrays.asList(nextHopIp)).build(); - adjacencyList.add(newAdj); - Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(adjacencyList); - VpnInterface newVpnIntf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(vpnInterface)). - setName(vpnInterface).setVpnInstanceName(vpnName).addAugmentation(Adjacencies.class, aug).build(); - VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vpnIfId, newVpnIntf); - LOG.debug(" Successfully stored subnetroute Adjacency into VpnInterface {}", vpnInterface); - } - } - - } - - public void removeMIPAdjacency(String vpnName, String vpnInterface, org.opendaylight.yang.gen.v1.urn.ietf.params - .xml.ns.yang.ietf.inet.types.rev130715.IpAddress prefix) { - String ip = VpnUtil.getIpPrefix(prefix.getIpv4Address().getValue()); - LOG.trace("Removing {} adjacency from Old VPN Interface {} ",ip,vpnInterface); - InstanceIdentifier vpnIfId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface); - InstanceIdentifier path = vpnIfId.augmentation(Adjacencies.class); - Optional adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path); - if (adjacencies.isPresent()) { - InstanceIdentifier adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class). - child(VpnInterface.class, new VpnInterfaceKey(vpnInterface)).augmentation(Adjacencies.class) - .child(Adjacency.class, new AdjacencyKey(ip)).build(); - MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier); - LOG.trace("Successfully Deleted Adjacency into VpnInterface {}", vpnInterface); + void notifyTaskIfRequired(String intfName) { + Runnable notifyTask = vpnIntfMap.remove(intfName); + if (notifyTask == null) { + return; } + executorService.execute(notifyTask); } }