2 * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.vpnservice;
10 import org.opendaylight.vpnservice.utilities.InterfaceUtils;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.JdkFutureAdapters;
16 import org.opendaylight.controller.md.sal.binding.api.*;
17 import org.opendaylight.vpnservice.mdsalutil.*;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyKey;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.OdlArputilService;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpResponseInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpResponseInputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntry;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntryBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntryKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
43 import java.math.BigInteger;
44 import java.util.Collection;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.ArrayList;
48 import java.util.concurrent.*;
50 import com.google.common.base.Optional;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
53 import org.opendaylight.bgpmanager.api.IBgpManager;
54 import org.opendaylight.fibmanager.api.IFibManager;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
57 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
58 import org.opendaylight.yangtools.concepts.ListenerRegistration;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
61 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
62 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
66 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
68 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
69 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
70 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
71 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
72 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
73 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
74 import org.opendaylight.yangtools.yang.common.RpcError;
75 import org.opendaylight.yangtools.yang.common.RpcResult;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
79 public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
80 private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);
81 private ListenerRegistration<DataChangeListener> listenerRegistration, opListenerRegistration;
82 private ConcurrentMap<String, Runnable> vpnIntfMap = new ConcurrentHashMap<String, Runnable>();
83 private ExecutorService executorService = Executors.newSingleThreadExecutor();
84 private final DataBroker broker;
85 private final IBgpManager bgpManager;
86 private IFibManager fibManager;
87 private IMdsalApiManager mdsalManager;
88 private OdlInterfaceRpcService interfaceManager;
89 private ItmRpcService itmProvider;
90 private IdManagerService idManager;
91 private OdlArputilService arpManager;
92 private NeutronvpnService neuService;
93 private VpnSubnetRouteHandler vpnSubnetRouteHandler;
94 private InterfaceStateChangeListener interfaceListener;
95 private VpnInterfaceOpListener vpnInterfaceOpListener;
96 private ArpNotificationHandler arpNotificationHandler;
97 protected enum UpdateRouteAction {
98 ADVERTISE_ROUTE, WITHDRAW_ROUTE
101 * Responsible for listening to data change related to VPN Interface
102 * Bind VPN Service on the interface and informs the BGP service
104 * @param db - dataBroker service reference
106 public VpnInterfaceManager(final DataBroker db, final IBgpManager bgpManager, NotificationService notificationService) {
107 super(VpnInterface.class);
109 this.bgpManager = bgpManager;
110 interfaceListener = new InterfaceStateChangeListener(db, this);
111 vpnInterfaceOpListener = new VpnInterfaceOpListener();
112 arpNotificationHandler = new ArpNotificationHandler(this, broker);
113 notificationService.registerNotificationListener(arpNotificationHandler);
114 vpnSubnetRouteHandler = new VpnSubnetRouteHandler(broker, bgpManager, this);
115 notificationService.registerNotificationListener(vpnSubnetRouteHandler);
116 registerListener(db);
119 public void setMdsalManager(IMdsalApiManager mdsalManager) {
120 this.mdsalManager = mdsalManager;
123 public void setInterfaceManager(OdlInterfaceRpcService interfaceManager) {
124 this.interfaceManager = interfaceManager;
125 interfaceListener.setInterfaceManager(interfaceManager);
128 public void setITMProvider(ItmRpcService itmProvider) {
129 this.itmProvider = itmProvider;
132 public void setFibManager(IFibManager fibManager) {
133 this.fibManager = fibManager;
136 public void setIdManager(IdManagerService idManager) {
137 this.idManager = idManager;
138 vpnSubnetRouteHandler.setIdManager(idManager);
141 public void setArpManager(OdlArputilService arpManager) {
142 this.arpManager = arpManager;
145 public void setNeutronvpnManager(NeutronvpnService neuService) { this.neuService = neuService; }
147 public VpnSubnetRouteHandler getVpnSubnetRouteHandler() {
148 return this.vpnSubnetRouteHandler;
152 public void close() throws Exception {
153 if (listenerRegistration != null) {
155 listenerRegistration.close();
156 opListenerRegistration.close();
157 } catch (final Exception e) {
158 LOG.error("Error when cleaning up DataChangeListener.", e);
160 listenerRegistration = null;
161 opListenerRegistration = null;
163 LOG.info("VPN Interface Manager Closed");
166 private void registerListener(final DataBroker db) {
168 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
169 getWildCardPath(), VpnInterfaceManager.this, DataChangeScope.SUBTREE);
170 opListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
171 getWildCardPath(), vpnInterfaceOpListener, DataChangeScope.SUBTREE);
172 } catch (final Exception e) {
173 LOG.error("VPN Service DataChange listener registration fail!", e);
174 throw new IllegalStateException("VPN Service registration Listener failed.", e);
178 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> getInterfaceListenerPath() {
179 return InstanceIdentifier.create(InterfacesState.class)
180 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class);
184 protected void add(final InstanceIdentifier<VpnInterface> identifier,
185 final VpnInterface vpnInterface) {
186 LOG.trace("VPN Interface key: {} , value: {}", identifier, vpnInterface );
187 addInterface(identifier, vpnInterface);
190 private void addInterface(final InstanceIdentifier<VpnInterface> identifier,
191 final VpnInterface vpnInterface) {
192 LOG.trace("VPN Interface add event - key: {}, value: {}" ,identifier, vpnInterface );
193 final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
194 String interfaceName = key.getName();
196 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState =
197 InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName);
198 if (interfaceState != null) {
199 // Interface state is up
200 processVpnInterfaceUp(InterfaceUtils.getDpIdFromInterface(interfaceState), interfaceName, interfaceState.getIfIndex());
202 LOG.trace("VPN interfaces are not yet operational.");
206 protected void processVpnInterfaceUp(BigInteger dpId, String interfaceName, int lPortTag) {
208 VpnInterface vpnInterface = VpnUtil.getConfiguredVpnInterface(broker, interfaceName);
209 if(vpnInterface == null) {
210 LOG.info("Unable to process add/up for interface {} as it is not configured", interfaceName);
213 String vpnName = vpnInterface.getVpnInstanceName();
214 LOG.info("Binding vpn service to interface {} ", interfaceName);
215 long vpnId = VpnUtil.getVpnId(broker, vpnName);
216 if (vpnId == VpnConstants.INVALID_ID) {
217 LOG.trace("VpnInstance to VPNId mapping is not yet available, bailing out now.");
220 synchronized (interfaceName.intern()) {
221 if (VpnUtil.getOperationalVpnInterface(broker, vpnInterface.getName()) != null) {
222 LOG.trace("VPN Interface already provisioned , bailing out from here.");
225 bindService(dpId, vpnName, interfaceName, lPortTag);
226 updateDpnDbs(dpId, vpnName, interfaceName, true);
227 processVpnInterfaceAdjacencies(dpId, VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
232 private void updateDpnDbs(BigInteger dpId, String vpnName, String interfaceName, boolean add) {
233 long vpnId = VpnUtil.getVpnId(broker, vpnName);
235 dpId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
237 if(!dpId.equals(BigInteger.ZERO)) {
239 updateMappingDbs(vpnId, dpId, interfaceName, vpnName);
241 removeFromMappingDbs(vpnId, dpId, interfaceName, vpnName);
246 private void bindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName, int lPortTag) {
247 int priority = VpnConstants.DEFAULT_FLOW_PRIORITY;
248 long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
250 int instructionKey = 0;
251 List<Instruction> instructions = new ArrayList<Instruction>();
253 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID, ++instructionKey));
254 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey));
258 InterfaceUtils.getBoundServices(String.format("%s.%s.%s", "vpn",vpnInstanceName, vpnInterfaceName),
259 VpnConstants.L3VPN_SERVICE_IDENTIFIER, priority,
260 VpnConstants.COOKIE_VM_INGRESS_TABLE, instructions);
261 VpnUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
262 InterfaceUtils.buildServiceId(vpnInterfaceName, VpnConstants.L3VPN_SERVICE_IDENTIFIER), serviceInfo);
263 makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
264 vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW);
265 makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
266 vpnId, ArpReplyOrRequest.REPLY, NwConstants.ADD_FLOW);
270 private void processVpnInterfaceAdjacencies(BigInteger dpnId, final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {
271 String intfName = intf.getName();
273 synchronized (intfName) {
275 InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
276 Optional<Adjacencies> adjacencies = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, path);
278 if (adjacencies.isPresent()) {
279 List<Adjacency> nextHops = adjacencies.get().getAdjacency();
280 List<Adjacency> value = new ArrayList<>();
282 // Get the rd of the vpn instance
283 String rd = getRouteDistinguisher(intf.getVpnInstanceName());
285 String nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId);
286 if (nextHopIp == null){
287 LOG.error("NextHop for interface {} is null", intfName);
290 LOG.trace("NextHops are {}", nextHops);
291 for (Adjacency nextHop : nextHops) {
292 String prefix = VpnUtil.getIpPrefix(nextHop.getIpAddress());
293 long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, VpnUtil
294 .getNextHopLabelKey((rd == null) ? intf.getVpnInstanceName() : rd, prefix));
295 String adjNextHop = nextHop.getNextHopIp();
296 value.add(new AdjacencyBuilder(nextHop).setLabel(label).setNextHopIp((adjNextHop != null && !adjNextHop.isEmpty()) ? adjNextHop : nextHopIp)
297 .setIpAddress(prefix).setKey(new AdjacencyKey(prefix)).build());
298 if(nextHop.getMacAddress() != null && !nextHop.getMacAddress().isEmpty()) {
301 LogicalDatastoreType.OPERATIONAL,
302 VpnUtil.getPrefixToInterfaceIdentifier(
303 VpnUtil.getVpnId(broker, intf.getVpnInstanceName()), prefix),
304 VpnUtil.getPrefixToInterface(dpnId, intf.getName(), prefix));
306 //Extra route adjacency
309 LogicalDatastoreType.OPERATIONAL,
310 VpnUtil.getVpnToExtrarouteIdentifier(
311 (rd != null) ? rd : intf.getVpnInstanceName(), nextHop.getIpAddress()),
312 VpnUtil.getVpnToExtraroute(nextHop.getIpAddress(), nextHop.getNextHopIp()));
317 Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(value);
318 VpnInterface opInterface = VpnUtil.getVpnInterface(intfName, intf.getVpnInstanceName(), aug);
319 InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(intfName);
320 VpnUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface);
321 for (Adjacency nextHop : aug.getAdjacency()) {
322 long label = nextHop.getLabel();
323 //String adjNextHop = nextHop.getNextHopIp();
325 addPrefixToBGP(rd, nextHop.getIpAddress(),
328 // ### add FIB route directly
329 addFibEntryToDS(intf.getVpnInstanceName(), nextHop.getIpAddress(),
330 nextHopIp, (int) label);
337 private void makeArpFlow(BigInteger dpId,short sIndex, int lPortTag, String vpnInterfaceName,
338 long vpnId, ArpReplyOrRequest replyOrRequest, int addOrRemoveFlow){
339 List<MatchInfo> matches = new ArrayList<MatchInfo>();
340 BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lPortTag, ++sIndex, BigInteger.valueOf(vpnId));
341 BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
342 MetaDataUtil.METADATA_MASK_LPORT_TAG, MetaDataUtil.METADATA_MASK_VRFID);
344 // Matching Arp reply flows
345 matches.add(new MatchInfo(MatchFieldType.eth_type, new long[] { NwConstants.ETHTYPE_ARP }));
346 matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
347 metadata, metadataMask }));
349 matches.add(new MatchInfo(MatchFieldType.arp_op, new long[] { replyOrRequest.getArpOperation() }));
351 // Instruction to punt to controller
352 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
353 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
354 actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, new String[] {}));
355 instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
357 // Install the flow entry in L3_INTERFACE_TABLE
358 String flowRef = VpnUtil.getFlowRef(dpId, NwConstants.L3_INTERFACE_TABLE,
359 NwConstants.ETHTYPE_ARP, lPortTag, replyOrRequest.getArpOperation());
360 FlowEntity flowEntity;
361 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_INTERFACE_TABLE, flowRef,
362 NwConstants.DEFAULT_ARP_FLOW_PRIORITY, replyOrRequest.getName(), 0, 0,
363 VpnUtil.getCookieArpFlow(lPortTag), matches, instructions);
365 if (addOrRemoveFlow == NwConstants.ADD_FLOW) {
366 LOG.debug("Creating ARP Flow for interface {}",vpnInterfaceName);
367 mdsalManager.installFlow(flowEntity);
369 LOG.debug("Deleting ARP Flow for interface {}",vpnInterfaceName);
370 mdsalManager.removeFlow(flowEntity);
374 private String getRouteDistinguisher(String vpnName) {
375 InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
376 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
377 Optional<VpnInstance> vpnInstance = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
379 if(vpnInstance.isPresent()) {
380 VpnInstance instance = vpnInstance.get();
381 VpnAfConfig config = instance.getIpv4Family();
382 rd = config.getRouteDistinguisher();
387 private synchronized void updateMappingDbs(long vpnId, BigInteger dpnId, String intfName, String vpnName) {
388 String routeDistinguisher = getRouteDistinguisher(vpnName);
389 String rd = (routeDistinguisher == null) ? vpnName : routeDistinguisher;
390 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
391 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
392 org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces
393 vpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
395 if (dpnInVpn.isPresent()) {
396 VpnUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id.child(
397 org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance
398 .op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class,
399 new VpnInterfacesKey(intfName)), vpnInterface);
401 VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
402 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
403 VpnUtil.getVpnInstanceOpDataBuilder(rd, vpnId));
404 VpnToDpnListBuilder vpnToDpnList = new VpnToDpnListBuilder().setDpnId(dpnId);
405 List<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
406 .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = new ArrayList<>();
407 vpnInterfaces.add(vpnInterface);
408 VpnUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id,
409 vpnToDpnList.setVpnInterfaces(vpnInterfaces).build());
412 * FIXME: DC Gateway tunnel should be built dynamically
413 //this is the first VM in this VPN on the DPN, may be a new DPN has come up,
414 //if tunnel to DC GW does not exist, create it
415 //if(!tunnelExists(dpnID, bgpManager.getDCGWIP()))
416 String dcGW = bgpManager.getDCGwIP();
417 if(dcGW != null && !dcGW.isEmpty())
419 LOG.debug("Building tunnel from DPN {} to DC GW {}", dpnId, dcGW);
420 itmProvider.buildTunnelFromDPNToDCGW(dpnId, new IpAddress(dcGW.toCharArray()));
422 fibManager.populateFibOnNewDpn(dpnId, vpnId, (rd == null) ? vpnName : rd);
426 private synchronized void removeFromMappingDbs(long vpnId, BigInteger dpnId, String intfName, String vpnName) {
427 //TODO: Delay 'DPN' removal so that other services can cleanup the entries for this dpn
428 String rd = VpnUtil.getVpnRd(broker, vpnName);
429 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
430 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
431 if (dpnInVpn.isPresent()) {
432 List<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
433 .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = dpnInVpn.get().getVpnInterfaces();
434 org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces
435 currVpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
437 if (vpnInterfaces.remove(currVpnInterface)) {
438 if (vpnInterfaces.isEmpty()) {
439 VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id, VpnUtil.DEFAULT_CALLBACK);
440 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd);
442 VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id.child(
443 org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
444 .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class,
445 new VpnInterfacesKey(intfName)), VpnUtil.DEFAULT_CALLBACK);
451 private void addPrefixToBGP(String rd, String prefix, String nextHopIp, long label) {
453 bgpManager.addPrefix(rd, prefix, nextHopIp, (int)label);
454 } catch(Exception e) {
455 LOG.error("Add prefix failed", e);
460 private InstanceIdentifier<VpnInterface> getWildCardPath() {
461 return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);
465 protected void remove( InstanceIdentifier<VpnInterface> identifier, VpnInterface vpnInterface) {
466 LOG.trace("Remove event - key: {}, value: {}" ,identifier, vpnInterface );
467 final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
468 String interfaceName = key.getName();
470 InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
471 Optional<VpnInterface> existingVpnInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, interfaceId);
472 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState =
473 InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName);
475 if (existingVpnInterface.isPresent() && interfaceState != null) {
476 processVpnInterfaceDown(InterfaceUtils.getDpIdFromInterface(interfaceState), interfaceName, interfaceState.getIfIndex(), false);
478 LOG.warn("VPN interface {} was unavailable in operational data store to handle remove event", interfaceName);
482 protected void processVpnInterfaceDown(BigInteger dpId, String interfaceName, int lPortTag, boolean isInterfaceStateDown) {
483 VpnInterface vpnInterface = VpnUtil.getOperationalVpnInterface(broker, interfaceName);
484 if(vpnInterface == null) {
485 LOG.info("Unable to process delete/down for interface {} as it is not available in operational data store", interfaceName);
488 String vpnName = vpnInterface.getVpnInstanceName();
489 InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
491 synchronized (interfaceName.intern()) {
492 removeAdjacenciesFromVpn(identifier, vpnInterface);
493 LOG.info("Unbinding vpn service from interface {} ", interfaceName);
494 unbindService(dpId, vpnName, interfaceName, lPortTag, isInterfaceStateDown);
496 //wait till DCN for removal of vpn interface in operational DS arrives
497 Runnable notifyTask = new VpnNotifyTask();
498 synchronized (interfaceName.intern()) {
499 vpnIntfMap.put(interfaceName, notifyTask);
500 synchronized (notifyTask) {
502 notifyTask.wait(VpnConstants.WAIT_TIME_IN_MILLISECONDS);
503 } catch (InterruptedException e) {
511 private void removeAdjacenciesFromVpn(final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {
513 InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
514 Optional<Adjacencies> adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path);
516 String rd = VpnUtil.getVpnRd(broker, intf.getVpnInstanceName());
517 if (adjacencies.isPresent()) {
518 List<Adjacency> nextHops = adjacencies.get().getAdjacency();
520 if (!nextHops.isEmpty()) {
521 LOG.trace("NextHops are " + nextHops);
522 for (Adjacency nextHop : nextHops) {
523 VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
524 VpnUtil.getNextHopLabelKey(rd, nextHop.getIpAddress()));
525 /*VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
526 VpnUtil.getPrefixToInterfaceIdentifier(
527 VpnUtil.getVpnId(broker, intf.getVpnInstanceName()),
528 nextHop.getIpAddress()),
529 VpnUtil.DEFAULT_CALLBACK);*/
530 if (rd.equals(intf.getVpnInstanceName())) {
531 //this is an internal vpn - the rd is assigned to the vpn instance name;
532 //remove from FIB directly
533 removeFibEntryFromDS(intf.getVpnInstanceName(), nextHop.getIpAddress());
535 removePrefixFromBGP(rd, nextHop.getIpAddress());
543 private void unbindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName,
544 int lPortTag, boolean isInterfaceStateDown) {
545 if (!isInterfaceStateDown) {
546 VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION,
547 InterfaceUtils.buildServiceId(vpnInterfaceName,
548 VpnConstants.L3VPN_SERVICE_IDENTIFIER),
549 VpnUtil.DEFAULT_CALLBACK);
551 long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
552 makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
553 vpnId, ArpReplyOrRequest.REQUEST, NwConstants.DEL_FLOW);
554 makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
555 vpnId, ArpReplyOrRequest.REPLY, NwConstants.DEL_FLOW);
559 private void removePrefixFromBGP(String rd, String prefix) {
561 bgpManager.deletePrefix(rd, prefix);
562 } catch(Exception e) {
563 LOG.error("Delete prefix failed", e);
568 protected void update(InstanceIdentifier<VpnInterface> identifier, VpnInterface original, VpnInterface update) {
569 if (LOG.isTraceEnabled()) {
570 LOG.trace("Updating VPN Interface : key " + identifier + ", original value=" + original + ", update " +
573 String oldVpnName = original.getVpnInstanceName();
574 String newVpnName = update.getVpnInstanceName();
575 List<Adjacency> oldAdjs = original.getAugmentation(Adjacencies.class).getAdjacency();
576 List<Adjacency> newAdjs = update.getAugmentation(Adjacencies.class).getAdjacency();
577 if (oldAdjs == null) {
578 oldAdjs = new ArrayList<>();
580 if (newAdjs == null) {
581 newAdjs = new ArrayList<>();
583 //handles switching between <internal VPN - external VPN>
584 if (!oldVpnName.equals(newVpnName)) {
585 remove(identifier, original);
586 add(identifier, update);
588 //handle both addition and removal of adjacencies
589 //currently, new adjacency may be an extra route
590 if (!oldAdjs.equals(newAdjs)) {
591 for (Adjacency adj : newAdjs) {
592 if (oldAdjs.contains(adj)) {
595 // add new adjacency - right now only extra route will hit this path
596 addNewAdjToVpnInterface(identifier, adj);
599 for (Adjacency adj : oldAdjs) {
600 delAdjFromVpnInterface(identifier, adj);
605 public void processArpRequest(IpAddress srcIP, PhysAddress srcMac, IpAddress targetIP, String srcInterface){
606 SendArpResponseInput input = new SendArpResponseInputBuilder().setInterface(srcInterface)
607 .setIpaddress(srcIP).setSrcIpAddress(targetIP).setMacaddress(srcMac).build();
608 final String msgFormat = String.format("Send ARP Response on interface %s to destination %s", srcInterface, srcIP);
609 Future<RpcResult<Void>> future = arpManager.sendArpResponse(input);
610 Futures.addCallback(JdkFutureAdapters.listenInPoolThread(future), new FutureCallback<RpcResult<Void>>() {
612 public void onFailure(Throwable error) {
613 LOG.error("Error - {}", msgFormat, error);
617 public void onSuccess(RpcResult<Void> result) {
618 if(!result.isSuccessful()) {
619 LOG.warn("Rpc call to {} failed", msgFormat, getErrorText(result.getErrors()));
621 LOG.debug("Successful RPC Result - {}", msgFormat);
627 private String getErrorText(Collection<RpcError> errors) {
628 StringBuilder errorText = new StringBuilder();
629 for(RpcError error : errors) {
630 errorText.append(",").append(error.getErrorType()).append("-")
631 .append(error.getMessage());
633 return errorText.toString();
636 private String getTunnelInterfaceFlowRef(BigInteger dpnId, short tableId, String ifName) {
637 return new StringBuilder().append(dpnId).append(tableId).append(ifName).toString();
642 public synchronized void addFibEntryToDS(String rd, String prefix,
643 String nexthop, int label) {
645 VrfEntry vrfEntry = new VrfEntryBuilder().setDestPrefix(prefix).
646 setNextHopAddress(nexthop).setLabel((long)label).build();
647 LOG.debug("Created vrfEntry for {} nexthop {} label {}", prefix, nexthop, label);
649 List<VrfEntry> vrfEntryList = new ArrayList<VrfEntry>();
650 vrfEntryList.add(vrfEntry);
652 InstanceIdentifierBuilder<VrfTables> idBuilder =
653 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd));
654 InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
656 VrfTables vrfTableNew = new VrfTablesBuilder().setRouteDistinguisher(rd).
657 setVrfEntry(vrfEntryList).build();
659 VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableNew);
662 public synchronized void removeFibEntryFromDS(String rd, String prefix) {
664 LOG.debug("Removing fib entry with destination prefix {} from vrf table for rd {}", prefix, rd);
666 InstanceIdentifierBuilder<VrfEntry> idBuilder =
667 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix));
668 InstanceIdentifier<VrfEntry> vrfEntryId = idBuilder.build();
669 VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, VpnUtil.DEFAULT_CALLBACK);
673 public synchronized void removeVrfFromDS(String rd) {
674 LOG.debug("Removing vrf table for rd {}", rd);
676 InstanceIdentifierBuilder<VrfTables> idBuilder =
677 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd));
678 InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
680 VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId, VpnUtil.DEFAULT_CALLBACK);
684 protected void addNewAdjToVpnInterface(InstanceIdentifier<VpnInterface> identifier, Adjacency adj) {
686 Optional<VpnInterface> optVpnInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, identifier);
688 if (optVpnInterface.isPresent()) {
689 VpnInterface currVpnIntf = optVpnInterface.get();
690 String prefix = VpnUtil.getIpPrefix(adj.getIpAddress());
691 String rd = getRouteDistinguisher(currVpnIntf.getVpnInstanceName());
692 InstanceIdentifier<Adjacencies> adjPath = identifier.augmentation(Adjacencies.class);
693 Optional<Adjacencies> optAdjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, adjPath);
695 VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
696 VpnUtil.getNextHopLabelKey((rd != null) ? rd : currVpnIntf.getVpnInstanceName(), prefix));
698 List<Adjacency> adjacencies;
699 if (optAdjacencies.isPresent()) {
700 adjacencies = optAdjacencies.get().getAdjacency();
702 //This code will not be hit since VM adjacency will always be there
703 adjacencies = new ArrayList<>();
706 adjacencies.add(new AdjacencyBuilder(adj).setLabel(label).setNextHopIp(adj.getNextHopIp())
707 .setIpAddress(prefix).setKey(new AdjacencyKey(prefix)).build());
709 Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(adjacencies);
710 VpnInterface newVpnIntf = VpnUtil.getVpnInterface(currVpnIntf.getName(), currVpnIntf.getVpnInstanceName(), aug);
712 VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, identifier, newVpnIntf);
713 addExtraRoute(adj.getIpAddress(), adj.getNextHopIp(), rd, currVpnIntf.getVpnInstanceName(), (int) label, currVpnIntf.getName());
719 protected void delAdjFromVpnInterface(InstanceIdentifier<VpnInterface> identifier, Adjacency adj) {
720 Optional<VpnInterface> optVpnInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, identifier);
722 if (optVpnInterface.isPresent()) {
723 VpnInterface currVpnIntf = optVpnInterface.get();
725 InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
726 Optional<Adjacencies> optAdjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path);
727 if (optAdjacencies.isPresent()) {
728 List<Adjacency> adjacencies = optAdjacencies.get().getAdjacency();
730 if (!adjacencies.isEmpty()) {
731 String rd = getRouteDistinguisher(currVpnIntf.getVpnInstanceName());
732 LOG.trace("Adjacencies are " + adjacencies);
733 Iterator<Adjacency> adjIt = adjacencies.iterator();
734 while (adjIt.hasNext()) {
735 Adjacency adjElem = adjIt.next();
736 if (adjElem.getIpAddress().equals(adj.getIpAddress())) {
737 VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
738 VpnUtil.getNextHopLabelKey(rd, adj.getIpAddress()));
741 Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(adjacencies);
742 VpnInterface newVpnIntf = VpnUtil.getVpnInterface(currVpnIntf.getName(),
743 currVpnIntf.getVpnInstanceName(),
746 VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, identifier, newVpnIntf);
748 delExtraRoute(adj.getIpAddress(), rd, currVpnIntf.getVpnInstanceName());
759 protected void addExtraRoute(String destination, String nextHop, String rd, String routerID, int label, String intfName) {
761 //add extra route to vpn mapping; advertise with nexthop as tunnel ip
764 LogicalDatastoreType.OPERATIONAL,
765 VpnUtil.getVpnToExtrarouteIdentifier(
766 (rd != null) ? rd : routerID, destination),
767 VpnUtil.getVpnToExtraroute(destination, nextHop));
769 if (intfName != null && !intfName.isEmpty()) {
770 BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, intfName);
771 String nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId);
772 if (nextHopIp == null || nextHopIp.isEmpty()) {
773 LOG.warn("NextHop for interface {} is null / empty. Failed advertising extra route for prefix {}", intfName, destination);
778 addPrefixToBGP(rd, destination, nextHop, label);
780 // ### add FIB route directly
781 addFibEntryToDS(routerID, destination, nextHop, label);
785 protected void delExtraRoute(String destination, String rd, String routerID) {
787 removePrefixFromBGP(rd, destination);
789 // ### add FIB route directly
790 removeFibEntryFromDS(routerID, destination);
794 class VpnInterfaceOpListener extends org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener<VpnInterface> {
796 public VpnInterfaceOpListener() {
797 super(VpnInterface.class);
801 protected void remove(InstanceIdentifier<VpnInterface> identifier, VpnInterface del) {
802 final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
803 String interfaceName = key.getName();
805 //increment the vpn interface count in Vpn Instance Op Data
807 String rd = getRouteDistinguisher(del.getVpnInstanceName());
808 if(rd == null || rd.isEmpty()) rd = del.getVpnInstanceName();
809 VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
810 if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
811 ifCnt = vpnInstOp.getVpnInterfaceCount();
814 LOG.trace("VpnInterfaceOpListener remove: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt);
817 VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
818 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
819 VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK);
822 // Vpn Interface removed => No more adjacencies from it.
823 // Hence clean up interface from vpn-dpn-interface list.
824 Adjacency adjacency = del.getAugmentation(Adjacencies.class).getAdjacency().get(0);
825 Optional<Prefixes> prefixToInterface = Optional.absent();
826 prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
827 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
828 VpnUtil.getIpPrefix(adjacency.getIpAddress())));
829 if (!prefixToInterface.isPresent()) {
830 prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
831 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
832 VpnUtil.getIpPrefix(adjacency.getNextHopIp())));
834 if (prefixToInterface.isPresent()) {
835 VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
836 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
837 prefixToInterface.get().getIpAddress()),
838 VpnUtil.DEFAULT_CALLBACK);
839 updateDpnDbs(prefixToInterface.get().getDpnId(), del.getVpnInstanceName(), interfaceName, false);
841 notifyTaskIfRequired(interfaceName);
844 private void notifyTaskIfRequired(String intfName) {
845 Runnable notifyTask = vpnIntfMap.remove(intfName);
846 if (notifyTask == null) {
849 executorService.execute(notifyTask);
853 protected void update(InstanceIdentifier<VpnInterface> identifier, VpnInterface original, VpnInterface update) {
857 protected void add(InstanceIdentifier<VpnInterface> identifier, VpnInterface add) {
858 final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
859 String interfaceName = key.getName();
861 //increment the vpn interface count in Vpn Instance Op Data
863 String rd = getRouteDistinguisher(add.getVpnInstanceName());
864 if(rd == null || rd.isEmpty()) rd = add.getVpnInstanceName();
865 VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
866 if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
867 ifCnt = vpnInstOp.getVpnInterfaceCount();
870 LOG.trace("VpnInterfaceOpListener add: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt);
872 VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
873 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
874 VpnUtil.updateIntfCntInVpnInstOpData(ifCnt + 1, rd), VpnUtil.DEFAULT_CALLBACK);
880 protected void updatePrefixesForDPN(BigInteger dpnId, UpdateRouteAction action) {
882 LOG.info("Tunnel event triggered {} for Dpn:{} ", action.name(), dpnId);
883 InstanceIdentifierBuilder<VpnInstances> idBuilder = InstanceIdentifier.builder(VpnInstances.class);
884 InstanceIdentifier<VpnInstances> vpnInstancesId = idBuilder.build();
885 Optional<VpnInstances> vpnInstances = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vpnInstancesId);
887 if (vpnInstances.isPresent()) {
888 List<VpnInstance> vpnInstanceList = vpnInstances.get().getVpnInstance();
889 Iterator<VpnInstance> vpnInstIter = vpnInstanceList.iterator();
890 while (vpnInstIter.hasNext()) {
891 VpnInstance vpnInstance = vpnInstIter.next();
893 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
894 String rd = vpnConfig.getRouteDistinguisher();
895 if (rd == null || rd.isEmpty()) {
896 rd = vpnInstance.getVpnInstanceName();
898 InstanceIdentifier<VpnToDpnList> id =
899 VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
900 Optional<VpnToDpnList> dpnInVpn =
901 VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
902 if (dpnInVpn.isPresent()) {
903 // if (action == UpdateRouteAction.ADVERTISE_ROUTE) {
904 // fibManager.populateFibOnNewDpn(dpnId, VpnUtil
905 // .getVpnId(broker, vpnInstance.getVpnInstanceName()), rd);
907 List<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
908 .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces>
909 vpnInterfaces = dpnInVpn.get().getVpnInterfaces();
910 for (org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
911 .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces vpnInterface : vpnInterfaces) {
912 InstanceIdentifier<VpnInterface> vpnIntfId =
913 VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getInterfaceName());
914 InstanceIdentifier<Adjacencies> path =
915 vpnIntfId.augmentation(Adjacencies.class);
916 Optional<Adjacencies> adjacencies =
917 VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path);
919 if (adjacencies.isPresent()) {
920 List<Adjacency> adjacencyList = adjacencies.get().getAdjacency();
921 Iterator<Adjacency> adjacencyIterator = adjacencyList.iterator();
923 while (adjacencyIterator.hasNext()) {
924 Adjacency adjacency = adjacencyIterator.next();
926 if (action == UpdateRouteAction.ADVERTISE_ROUTE)
927 bgpManager.addPrefix(rd, adjacency.getIpAddress(),
928 adjacency.getNextHopIp(),
929 adjacency.getLabel().intValue());
930 else if (action == UpdateRouteAction.WITHDRAW_ROUTE)
931 bgpManager.deletePrefix(rd, adjacency.getIpAddress());
932 } catch (Exception e) {
933 LOG.error("Exception when updating prefix {} in vrf {} to BGP",
934 adjacency.getIpAddress(), rd);
940 // if (action == UpdateRouteAction.WITHDRAW_ROUTE) {
941 // fibManager.cleanUpDpnForVpn(dpnId, VpnUtil.getVpnId(broker, vpnInstance.getVpnInstanceName()), rd);
944 } catch (Exception e) {
945 LOG.error("updatePrefixesForDPN {} in vpn {} failed", dpnId, vpnInstance.getVpnInstanceName(), e);