package org.opendaylight.vpnservice;
import org.opendaylight.vpnservice.utilities.InterfaceUtils;
+
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
import org.opendaylight.controller.md.sal.binding.api.*;
-
import org.opendaylight.vpnservice.mdsalutil.*;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
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.l3vpn.rev130911.PrefixToInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.OdlArputilService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpResponseInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpResponseInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.ItmRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
-import java.util.concurrent.Future;
+import java.util.concurrent.*;
import com.google.common.base.Optional;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
import org.opendaylight.bgpmanager.api.IBgpManager;
import org.opendaylight.fibmanager.api.IFibManager;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);
- private ListenerRegistration<DataChangeListener> listenerRegistration;
+ private ListenerRegistration<DataChangeListener> listenerRegistration, opListenerRegistration;
+ private ConcurrentMap<String, Runnable> vpnIntfMap = new ConcurrentHashMap<String, Runnable>();
+ private ExecutorService executorService = Executors.newSingleThreadExecutor();
private final DataBroker broker;
private final IBgpManager bgpManager;
private IFibManager fibManager;
private ItmRpcService itmProvider;
private IdManagerService idManager;
private OdlArputilService arpManager;
+ private NeutronvpnService neuService;
+ private VpnSubnetRouteHandler vpnSubnetRouteHandler;
private InterfaceStateChangeListener interfaceListener;
+ private VpnInterfaceOpListener vpnInterfaceOpListener;
private ArpNotificationHandler arpNotificationHandler;
protected enum UpdateRouteAction {
ADVERTISE_ROUTE, WITHDRAW_ROUTE
broker = db;
this.bgpManager = bgpManager;
interfaceListener = new InterfaceStateChangeListener(db, this);
+ vpnInterfaceOpListener = new VpnInterfaceOpListener();
arpNotificationHandler = new ArpNotificationHandler(this, broker);
notificationService.registerNotificationListener(arpNotificationHandler);
+ vpnSubnetRouteHandler = new VpnSubnetRouteHandler(broker, bgpManager, this);
+ notificationService.registerNotificationListener(vpnSubnetRouteHandler);
registerListener(db);
}
public void setIdManager(IdManagerService idManager) {
this.idManager = idManager;
+ vpnSubnetRouteHandler.setIdManager(idManager);
}
public void setArpManager(OdlArputilService arpManager) {
this.arpManager = arpManager;
}
+ public void setNeutronvpnManager(NeutronvpnService neuService) { this.neuService = neuService; }
+
+ public VpnSubnetRouteHandler getVpnSubnetRouteHandler() {
+ return this.vpnSubnetRouteHandler;
+ }
+
@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");
}
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);
@Override
protected void add(final InstanceIdentifier<VpnInterface> identifier,
final VpnInterface vpnInterface) {
- LOG.trace("key: {} , value: {}", identifier, vpnInterface );
+ LOG.trace("VPN Interface key: {} , value: {}", identifier, vpnInterface );
addInterface(identifier, vpnInterface);
}
private void addInterface(final InstanceIdentifier<VpnInterface> identifier,
final VpnInterface vpnInterface) {
- LOG.trace("Add event - key: {}, value: {}" ,identifier, vpnInterface );
+ LOG.trace("VPN Interface add event - key: {}, value: {}" ,identifier, vpnInterface );
final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
String interfaceName = key.getName();
InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName);
if (interfaceState != null) {
// Interface state is up
- processVpnInterfaceUp(interfaceName, interfaceState.getIfIndex());
+ processVpnInterfaceUp(InterfaceUtils.getDpIdFromInterface(interfaceState), interfaceName, interfaceState.getIfIndex());
+ } else {
+ LOG.trace("VPN interfaces are not yet operational.");
}
}
- protected synchronized void processVpnInterfaceUp(String interfaceName, int lPortTag) {
+ protected void processVpnInterfaceUp(BigInteger dpId, String interfaceName, int lPortTag) {
VpnInterface vpnInterface = VpnUtil.getConfiguredVpnInterface(broker, interfaceName);
if(vpnInterface == null) {
}
String vpnName = vpnInterface.getVpnInstanceName();
LOG.info("Binding vpn service to interface {} ", interfaceName);
- bindService(vpnName, interfaceName, lPortTag);
- updateDpnDbs(vpnName, interfaceName, true);
- processVpnInterfaceAdjacencies(VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
+ long vpnId = VpnUtil.getVpnId(broker, vpnName);
+ if (vpnId == VpnConstants.INVALID_ID) {
+ LOG.trace("VpnInstance to VPNId mapping is not yet available, bailing out now.");
+ return;
+ }
+ synchronized (interfaceName.intern()) {
+ if (VpnUtil.getOperationalVpnInterface(broker, vpnInterface.getName()) != null) {
+ LOG.trace("VPN Interface already provisioned , bailing out from here.");
+ return;
+ }
+ bindService(dpId, vpnName, interfaceName, lPortTag);
+ updateDpnDbs(dpId, vpnName, interfaceName, true);
+ processVpnInterfaceAdjacencies(dpId, VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
+ }
}
- private void updateDpnDbs(String vpnName, String interfaceName, boolean add) {
+ private void updateDpnDbs(BigInteger dpId, String vpnName, String interfaceName, boolean add) {
long vpnId = VpnUtil.getVpnId(broker, vpnName);
- BigInteger dpId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
+ if (dpId == null) {
+ dpId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
+ }
if(!dpId.equals(BigInteger.ZERO)) {
if(add)
updateMappingDbs(vpnId, dpId, interfaceName, vpnName);
}
- private void bindService(String vpnInstanceName, String vpnInterfaceName, int lPortTag) {
+ private void bindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName, int lPortTag) {
int priority = VpnConstants.DEFAULT_FLOW_PRIORITY;
long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
List<Instruction> instructions = new ArrayList<Instruction>();
instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID, ++instructionKey));
- instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(VpnConstants.FIB_TABLE, ++instructionKey));
+ instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey));
BoundServices
serviceInfo =
VpnConstants.COOKIE_VM_INGRESS_TABLE, instructions);
VpnUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
InterfaceUtils.buildServiceId(vpnInterfaceName, VpnConstants.L3VPN_SERVICE_IDENTIFIER), serviceInfo);
- makeArpFlow(VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName, vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW);
+ makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+ vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW);
+ makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+ vpnId, ArpReplyOrRequest.REPLY, NwConstants.ADD_FLOW);
}
- private void processVpnInterfaceAdjacencies(final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {
+ private void processVpnInterfaceAdjacencies(BigInteger dpnId, final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {
String intfName = intf.getName();
synchronized (intfName) {
// Get the rd of the vpn instance
String rd = getRouteDistinguisher(intf.getVpnInstanceName());
- BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, intfName);
String nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId);
if (nextHopIp == null){
LOG.error("NextHop for interface {} is null", intfName);
VpnUtil.getPrefixToInterfaceIdentifier(
VpnUtil.getVpnId(broker, intf.getVpnInstanceName()), prefix),
VpnUtil.getPrefixToInterface(dpnId, intf.getName(), prefix));
+ } else {
+ //Extra route adjacency
+ VpnUtil.syncUpdate(
+ broker,
+ LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnToExtrarouteIdentifier(
+ (rd != null) ? rd : intf.getVpnInstanceName(), nextHop.getIpAddress()),
+ VpnUtil.getVpnToExtraroute(nextHop.getIpAddress(), nextHop.getNextHopIp()));
+
}
}
VpnUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface);
for (Adjacency nextHop : aug.getAdjacency()) {
long label = nextHop.getLabel();
- String adjNextHop = nextHop.getNextHopIp();
+ //String adjNextHop = nextHop.getNextHopIp();
if (rd != null) {
addPrefixToBGP(rd, nextHop.getIpAddress(),
- (adjNextHop != null && !adjNextHop.isEmpty()) ? adjNextHop : nextHopIp, label);
+ nextHopIp, label);
} else {
// ### add FIB route directly
addFibEntryToDS(intf.getVpnInstanceName(), nextHop.getIpAddress(),
- (adjNextHop != null && !adjNextHop.isEmpty()) ? adjNextHop : nextHopIp, (int) label);
+ nextHopIp, (int) label);
}
}
}
}
}
- private void makeArpFlow(short sIndex, int lPortTag, String vpnInterfaceName, long vpnId, ArpReplyOrRequest replyOrRequest, int addOrRemoveFlow){
+ private void makeArpFlow(BigInteger dpId,short sIndex, int lPortTag, String vpnInterfaceName,
+ long vpnId, ArpReplyOrRequest replyOrRequest, int addOrRemoveFlow){
List<MatchInfo> matches = new ArrayList<MatchInfo>();
- BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lPortTag, sIndex, BigInteger.valueOf(vpnId));
+ BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lPortTag, ++sIndex, BigInteger.valueOf(vpnId));
BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
MetaDataUtil.METADATA_MASK_LPORT_TAG, MetaDataUtil.METADATA_MASK_VRFID);
instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
// Install the flow entry in L3_INTERFACE_TABLE
- BigInteger dpId = InterfaceUtils.getDpnForInterface(interfaceManager, vpnInterfaceName);
- String flowRef = VpnUtil.getFlowRef(dpId, VpnConstants.L3_INTERFACE_TABLE,
+ String flowRef = VpnUtil.getFlowRef(dpId, NwConstants.L3_INTERFACE_TABLE,
NwConstants.ETHTYPE_ARP, lPortTag, replyOrRequest.getArpOperation());
FlowEntity flowEntity;
- flowEntity = MDSALUtil.buildFlowEntity(dpId, VpnConstants.L3_INTERFACE_TABLE, flowRef,
+ flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_INTERFACE_TABLE, flowRef,
NwConstants.DEFAULT_ARP_FLOW_PRIORITY, replyOrRequest.getName(), 0, 0,
VpnUtil.getCookieArpFlow(lPortTag), matches, instructions);
} else {
VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
VpnUtil.getVpnInstanceOpDataIdentifier(rd),
- VpnUtil.getVpnInstanceOpData(rd, vpnId));
+ VpnUtil.getVpnInstanceOpDataBuilder(rd, vpnId));
VpnToDpnListBuilder vpnToDpnList = new VpnToDpnListBuilder().setDpnId(dpnId);
List<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = new ArrayList<>();
InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName);
if (existingVpnInterface.isPresent() && interfaceState != null) {
- processVpnInterfaceDown(interfaceName, interfaceState.getIfIndex());
+ processVpnInterfaceDown(InterfaceUtils.getDpIdFromInterface(interfaceState), interfaceName, interfaceState.getIfIndex(), false);
} else {
LOG.warn("VPN interface {} was unavailable in operational data store to handle remove event", interfaceName);
}
}
- protected synchronized void processVpnInterfaceDown(String interfaceName, int lPortTag) {
+ protected void processVpnInterfaceDown(BigInteger dpId, String interfaceName, int lPortTag, boolean isInterfaceStateDown) {
VpnInterface vpnInterface = VpnUtil.getOperationalVpnInterface(broker, interfaceName);
if(vpnInterface == null) {
LOG.info("Unable to process delete/down for interface {} as it is not available in operational data store", interfaceName);
String vpnName = vpnInterface.getVpnInstanceName();
InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
- removeAdjacenciesFromVpn(identifier, vpnInterface);
- LOG.info("Unbinding vpn service from interface {} ", interfaceName);
- unbindService(vpnName, interfaceName, lPortTag);
- updateDpnDbs(vpnName, interfaceName, false);
- VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, identifier, VpnUtil.DEFAULT_CALLBACK);
+ synchronized (interfaceName.intern()) {
+ removeAdjacenciesFromVpn(identifier, vpnInterface);
+ LOG.info("Unbinding vpn service from interface {} ", interfaceName);
+ unbindService(dpId, vpnName, interfaceName, lPortTag, isInterfaceStateDown);
+
+ //wait till DCN for removal of vpn interface in operational DS arrives
+ Runnable notifyTask = new VpnNotifyTask();
+ synchronized (interfaceName.intern()) {
+ vpnIntfMap.put(interfaceName, notifyTask);
+ synchronized (notifyTask) {
+ try {
+ notifyTask.wait(VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ }
}
private void removeAdjacenciesFromVpn(final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {
Optional<Adjacencies> adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path);
String rd = VpnUtil.getVpnRd(broker, intf.getVpnInstanceName());
+ LOG.trace("removeAdjacenciesFromVpn: For interface {} RD recovered for vpn {} as rd {}", intf.getName(),
+ intf.getVpnInstanceName(), rd);
if (adjacencies.isPresent()) {
List<Adjacency> nextHops = adjacencies.get().getAdjacency();
for (Adjacency nextHop : nextHops) {
VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
VpnUtil.getNextHopLabelKey(rd, nextHop.getIpAddress()));
- VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+ /*VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
VpnUtil.getPrefixToInterfaceIdentifier(
VpnUtil.getVpnId(broker, intf.getVpnInstanceName()),
nextHop.getIpAddress()),
- VpnUtil.DEFAULT_CALLBACK);
+ VpnUtil.DEFAULT_CALLBACK);*/
if (rd.equals(intf.getVpnInstanceName())) {
//this is an internal vpn - the rd is assigned to the vpn instance name;
//remove from FIB directly
}
- private void unbindService(String vpnInstanceName, String vpnInterfaceName, int lPortTag) {
- VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION,
- InterfaceUtils.buildServiceId(vpnInterfaceName,VpnConstants.L3VPN_SERVICE_IDENTIFIER),
- VpnUtil.DEFAULT_CALLBACK);
+ private void unbindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName,
+ int lPortTag, boolean isInterfaceStateDown) {
+ if (!isInterfaceStateDown) {
+ VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION,
+ InterfaceUtils.buildServiceId(vpnInterfaceName,
+ VpnConstants.L3VPN_SERVICE_IDENTIFIER),
+ VpnUtil.DEFAULT_CALLBACK);
+ }
long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
- makeArpFlow(VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+ makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
vpnId, ArpReplyOrRequest.REQUEST, NwConstants.DEL_FLOW);
+ makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+ vpnId, ArpReplyOrRequest.REPLY, NwConstants.DEL_FLOW);
}
}
@Override
- protected void update(InstanceIdentifier<VpnInterface> identifier,
- VpnInterface original, VpnInterface update) {
- LOG.trace("Update VPN Interface {} , original {}, update {}",
- identifier, original, update);
- String vpnName = original.getVpnInstanceName();
-
- boolean vpnNameChanged = false;
- String rd = getRouteDistinguisher(vpnName);
- String newRd = rd;
- String newVpnName = update.getVpnInstanceName();
- if(!vpnName.equals(newVpnName)) {
- //VPN for this interface got changed.
- //Remove the interface from old VPN and add it to new VPN
- newRd = getRouteDistinguisher(newVpnName);
- if(newRd.equals("")) {
- LOG.warn("VPN Instance {} not found. Update operation aborted", newVpnName);
- return;
- }
- vpnNameChanged = true;
- LOG.debug("New VPN Name for the interface {} is {}", newVpnName, original.getName());
+ protected void update(InstanceIdentifier<VpnInterface> identifier, VpnInterface original, VpnInterface update) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Updating VPN Interface : key " + identifier + ", original value=" + original + ", update " +
+ "value=" + update);
}
-
+ String oldVpnName = original.getVpnInstanceName();
+ String newVpnName = update.getVpnInstanceName();
List<Adjacency> oldAdjs = original.getAugmentation(Adjacencies.class).getAdjacency();
List<Adjacency> newAdjs = update.getAugmentation(Adjacencies.class).getAdjacency();
- if(vpnNameChanged && newAdjs != null && !newAdjs.isEmpty()) {
- long label = VpnConstants.INVALID_ID;
- InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
- Optional<Adjacencies> adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path);
- if (adjacencies.isPresent()) {
- List<Adjacency> nextHops = adjacencies.get().getAdjacency();
- for(Adjacency nextHop : nextHops) {
- label = nextHop.getLabel();
- if(label == VpnConstants.INVALID_ID) {
- //Generate label using ID Manager
- label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
- VpnUtil.getNextHopLabelKey(newRd, nextHop.getIpAddress()));
- }
- if (rd != null) {
- removePrefixFromBGP(rd, nextHop.getIpAddress());
- } else {
- removeFibEntryFromDS(vpnName, nextHop.getIpAddress());
- }
- //updatePrefixToBGP(newRd, nextHop, nextHopIp, label);
- }
- processVpnInterfaceAdjacencies(identifier, update);
- VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, identifier, update);
- }
- } else if (oldAdjs != newAdjs) {
- //handle both addition and removal of adjacencies
- //currently, new adjacency may be an extra route
+ if (oldAdjs == null) {
+ oldAdjs = new ArrayList<>();
+ }
+ if (newAdjs == null) {
+ newAdjs = new ArrayList<>();
+ }
+ //handles switching between <internal VPN - external VPN>
+ if (!oldVpnName.equals(newVpnName)) {
+ remove(identifier, original);
+ add(identifier, update);
+ }
+ //handle both addition and removal of adjacencies
+ //currently, new adjacency may be an extra route
+ if (!oldAdjs.equals(newAdjs)) {
for (Adjacency adj : newAdjs) {
if (oldAdjs.contains(adj)) {
oldAdjs.remove(adj);
addNewAdjToVpnInterface(identifier, adj);
}
}
-
for (Adjacency adj : oldAdjs) {
delAdjFromVpnInterface(identifier, adj);
}
}
- else {
- LOG.debug("No Update information is available for VPN Interface to proceed");
- }
-
}
public void processArpRequest(IpAddress srcIP, PhysAddress srcMac, IpAddress targetIP, String srcInterface){
VrfTables vrfTableNew = new VrfTablesBuilder().setRouteDistinguisher(rd).
setVrfEntry(vrfEntryList).build();
- VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, vrfTableId, vrfTableNew);
+ VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableNew);
}
public synchronized void removeFibEntryFromDS(String rd, String prefix) {
InstanceIdentifierBuilder<VrfEntry> idBuilder =
InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix));
InstanceIdentifier<VrfEntry> vrfEntryId = idBuilder.build();
- VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, vrfEntryId, VpnUtil.DEFAULT_CALLBACK);
+ VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, VpnUtil.DEFAULT_CALLBACK);
}
InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd));
InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
- VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, vrfTableId, VpnUtil.DEFAULT_CALLBACK);
+ VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId, VpnUtil.DEFAULT_CALLBACK);
}
VpnInterface newVpnIntf = VpnUtil.getVpnInterface(currVpnIntf.getName(), currVpnIntf.getVpnInstanceName(), aug);
VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, identifier, newVpnIntf);
- addExtraRoute(adj.getIpAddress(), adj.getNextHopIp(), rd, currVpnIntf.getVpnInstanceName(), (int) label);
+ addExtraRoute(adj.getIpAddress(), adj.getNextHopIp(), rd, currVpnIntf.getVpnInstanceName(), (int) label, currVpnIntf.getName());
}
adjIt.remove();
Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(adjacencies);
- VpnInterface newVpnIntf = VpnUtil.getVpnInterface(currVpnIntf.getName(), currVpnIntf.getVpnInstanceName(), aug);
+ VpnInterface newVpnIntf = VpnUtil.getVpnInterface(currVpnIntf.getName(),
+ currVpnIntf.getVpnInstanceName(),
+ aug);
VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, identifier, newVpnIntf);
}
- protected void addExtraRoute(String destination, String nextHop, String rd, String routerID, int label) {
+ protected void addExtraRoute(String destination, String nextHop, String rd, String routerID, int label, String intfName) {
+
+ //add extra route to vpn mapping; advertise with nexthop as tunnel ip
+ VpnUtil.syncUpdate(
+ broker,
+ LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnToExtrarouteIdentifier(
+ (rd != null) ? rd : routerID, destination),
+ VpnUtil.getVpnToExtraroute(destination, nextHop));
+
+ if (intfName != null && !intfName.isEmpty()) {
+ BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, intfName);
+ String nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId);
+ if (nextHopIp == null || nextHopIp.isEmpty()) {
+ LOG.warn("NextHop for interface {} is null / empty. Failed advertising extra route for prefix {}", intfName, destination);
+ }
+ nextHop = nextHopIp;
+ }
if (rd != null) {
addPrefixToBGP(rd, destination, nextHop, label);
} else {
}
}
+ class VpnInterfaceOpListener extends org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener<VpnInterface> {
+
+ public VpnInterfaceOpListener() {
+ super(VpnInterface.class);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<VpnInterface> identifier, VpnInterface del) {
+ 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<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
+ id = VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnName);
+ Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> 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) {
+ Long ifCnt = 0L;
+ ifCnt = vpnInstOp.getVpnInterfaceCount();
+ LOG.trace("VpnInterfaceOpListener removed: interface name {} rd {} vpnName {} Intf count {}",
+ interfaceName, rd, vpnName, ifCnt);
+ if ((ifCnt != null) && (ifCnt > 0)) {
+ VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+ VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK);
+ }
+
+ // 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);
+ Optional<Prefixes> prefixToInterface = Optional.absent();
+ prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+ VpnUtil.getIpPrefix(adjacency.getIpAddress())));
+ if (!prefixToInterface.isPresent()) {
+ prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+ VpnUtil.getIpPrefix(adjacency.getNextHopIp())));
+ }
+ if (prefixToInterface.isPresent()) {
+ VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+ prefixToInterface.get().getIpAddress()),
+ VpnUtil.DEFAULT_CALLBACK);
+ updateDpnDbs(prefixToInterface.get().getDpnId(), del.getVpnInstanceName(), interfaceName, false);
+ }
+ }
+ } 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) {
+ return;
+ }
+ executorService.execute(notifyTask);
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<VpnInterface> identifier, VpnInterface original, VpnInterface update) {
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<VpnInterface> identifier, VpnInterface add) {
+ final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+ String interfaceName = key.getName();
+
+ //increment the vpn interface count in Vpn Instance Op Data
+ Long ifCnt = 0L;
+ String rd = getRouteDistinguisher(add.getVpnInstanceName());
+ if(rd == null || rd.isEmpty()) rd = add.getVpnInstanceName();
+ VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
+ if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
+ ifCnt = vpnInstOp.getVpnInterfaceCount();
+ }
+
+ LOG.trace("VpnInterfaceOpListener add: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt);
+
+ VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+ VpnUtil.updateIntfCntInVpnInstOpData(ifCnt + 1, rd), VpnUtil.DEFAULT_CALLBACK);
+
+
+ }
+ }
+
protected void updatePrefixesForDPN(BigInteger dpnId, UpdateRouteAction action) {
+ LOG.info("Tunnel event triggered {} for Dpn:{} ", action.name(), dpnId);
InstanceIdentifierBuilder<VpnInstances> idBuilder = InstanceIdentifier.builder(VpnInstances.class);
InstanceIdentifier<VpnInstances> vpnInstancesId = idBuilder.build();
Optional<VpnInstances> vpnInstances = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vpnInstancesId);
Iterator<VpnInstance> vpnInstIter = vpnInstanceList.iterator();
while (vpnInstIter.hasNext()) {
VpnInstance vpnInstance = vpnInstIter.next();
- VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
- String rd = vpnConfig.getRouteDistinguisher();
-
- InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
- Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
- if (dpnInVpn.isPresent()) {
- if (action == UpdateRouteAction.ADVERTISE_ROUTE) {
- fibManager.populateFibOnNewDpn(dpnId, VpnUtil
- .getVpnId(broker, vpnInstance.getVpnInstanceName()), rd);
+ try {
+ VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
+ String rd = vpnConfig.getRouteDistinguisher();
+ if (rd == null || rd.isEmpty()) {
+ rd = vpnInstance.getVpnInstanceName();
}
- List<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
- .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = dpnInVpn.get().getVpnInterfaces();
- for(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
- .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces vpnInterface : vpnInterfaces) {
- InstanceIdentifier<VpnInterface> vpnIntfId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getInterfaceName());
- InstanceIdentifier<Adjacencies> path = vpnIntfId.augmentation(Adjacencies.class);
- Optional<Adjacencies> adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path);
-
- if (adjacencies.isPresent()) {
- List<Adjacency> adjacencyList = adjacencies.get().getAdjacency();
- Iterator<Adjacency> adjacencyIterator = adjacencyList.iterator();
-
- while (adjacencyIterator.hasNext()) {
- Adjacency adjacency = adjacencyIterator.next();
- try {
- if(action == UpdateRouteAction.ADVERTISE_ROUTE)
- bgpManager.addPrefix(rd, adjacency.getIpAddress(), adjacency.getNextHopIp(), adjacency.getLabel().intValue());
- else if(action == UpdateRouteAction.WITHDRAW_ROUTE)
- bgpManager.deletePrefix(rd, adjacency.getIpAddress());
- } catch (Exception e) {
- LOG.error("Exception when updating prefix {} in vrf {} to BGP", adjacency.getIpAddress(), rd);
+ InstanceIdentifier<VpnToDpnList> id =
+ VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
+ Optional<VpnToDpnList> dpnInVpn =
+ VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
+ if (dpnInVpn.isPresent()) {
+ // if (action == UpdateRouteAction.ADVERTISE_ROUTE) {
+ // fibManager.populateFibOnNewDpn(dpnId, VpnUtil
+ // .getVpnId(broker, vpnInstance.getVpnInstanceName()), rd);
+ // }
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
+ .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces>
+ vpnInterfaces = dpnInVpn.get().getVpnInterfaces();
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
+ .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces vpnInterface : vpnInterfaces) {
+ InstanceIdentifier<VpnInterface> vpnIntfId =
+ VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getInterfaceName());
+ InstanceIdentifier<Adjacencies> path =
+ vpnIntfId.augmentation(Adjacencies.class);
+ Optional<Adjacencies> adjacencies =
+ VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path);
+
+ if (adjacencies.isPresent()) {
+ List<Adjacency> adjacencyList = adjacencies.get().getAdjacency();
+ Iterator<Adjacency> adjacencyIterator = adjacencyList.iterator();
+
+ while (adjacencyIterator.hasNext()) {
+ Adjacency adjacency = adjacencyIterator.next();
+ try {
+ if (action == UpdateRouteAction.ADVERTISE_ROUTE)
+ bgpManager.addPrefix(rd, adjacency.getIpAddress(),
+ adjacency.getNextHopIp(),
+ adjacency.getLabel().intValue());
+ else if (action == UpdateRouteAction.WITHDRAW_ROUTE)
+ bgpManager.deletePrefix(rd, adjacency.getIpAddress());
+ } catch (Exception e) {
+ LOG.error("Exception when updating prefix {} in vrf {} to BGP",
+ adjacency.getIpAddress(), rd);
+ }
}
}
- }
+ }
+ // if (action == UpdateRouteAction.WITHDRAW_ROUTE) {
+ // fibManager.cleanUpDpnForVpn(dpnId, VpnUtil.getVpnId(broker, vpnInstance.getVpnInstanceName()), rd);
+ // }
}
- if (action == UpdateRouteAction.WITHDRAW_ROUTE) {
- fibManager.cleanUpDpnForVpn(dpnId, VpnUtil
- .getVpnId(broker, vpnInstance.getVpnInstanceName()), rd);
- }
+ } catch (Exception e) {
+ LOG.error("updatePrefixesForDPN {} in vpn {} failed", dpnId, vpnInstance.getVpnInstanceName(), e);
}
}
}