2 * Copyright (c) 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.netvirt.vpnmanager.intervpnlink;
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.Future;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
21 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
26 import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
27 import org.opendaylight.genius.mdsalutil.MDSALUtil;
28 import org.opendaylight.genius.mdsalutil.NwConstants;
29 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
30 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
31 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
32 import org.opendaylight.netvirt.vpnmanager.VpnConstants;
33 import org.opendaylight.netvirt.vpnmanager.VpnUtil;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkCreationError;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkCreationErrorBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.creation.error.InterVpnLinkCreationErrorMessage;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.creation.error.InterVpnLinkCreationErrorMessageBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkStateBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.inter.vpn.link.state.FirstEndpointState;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.inter.vpn.link.state.FirstEndpointStateBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.inter.vpn.link.state.SecondEndpointState;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.inter.vpn.link.state.SecondEndpointStateBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLinkKey;
59 import org.opendaylight.yangtools.concepts.ListenerRegistration;
60 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
61 import org.opendaylight.yangtools.yang.common.RpcResult;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
65 public class InterVpnLinkListener extends AbstractDataChangeListener<InterVpnLink> implements AutoCloseable {
66 private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkListener.class);
67 private ListenerRegistration<DataChangeListener> listenerRegistration;
68 private final DataBroker dataBroker;
69 private final IMdsalApiManager mdsalManager;
70 private final IdManagerService idManager;
71 private final IBgpManager bgpManager;
72 private final NotificationPublishService notificationsService;
73 private static final String NBR_OF_DPNS_PROPERTY_NAME = "vpnservice.intervpnlink.number.dpns";
74 private static final int INVALID_ID = 0;
76 public InterVpnLinkListener(final DataBroker dataBroker, final IdManagerService idManager,
77 final IMdsalApiManager mdsalManager, final IBgpManager bgpManager,
78 final NotificationPublishService notifService) {
79 super(InterVpnLink.class);
80 this.dataBroker = dataBroker;
81 this.idManager = idManager;
82 this.mdsalManager = mdsalManager;
83 this.bgpManager = bgpManager;
84 this.notificationsService = notifService;
88 LOG.info("{} start", getClass().getSimpleName());
89 listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
90 getWildCardPath(), this, AsyncDataBroker.DataChangeScope.SUBTREE);
93 private InstanceIdentifier<InterVpnLink> getWildCardPath() {
94 return InstanceIdentifier.create(InterVpnLinks.class).child(InterVpnLink.class);
98 public void close() throws Exception {
99 if (listenerRegistration != null) {
100 listenerRegistration.close();
101 listenerRegistration = null;
103 LOG.info("{} close", getClass().getSimpleName());
106 private String getInterVpnLinkIfaceName(String vpnUuid, BigInteger dpnId ) {
107 return String.format("InterVpnLink.%s.%s", vpnUuid, dpnId.toString());
111 protected void add(InstanceIdentifier<InterVpnLink> identifier, InterVpnLink add) {
113 int numberOfDpns = Integer.getInteger(NBR_OF_DPNS_PROPERTY_NAME, 1);
114 // Create VpnLink state
115 InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid = VpnUtil.getInterVpnLinkStateIid(add.getName());
116 InterVpnLinkState vpnLinkState = new InterVpnLinkStateBuilder().setInterVpnLinkName(add.getName()).build();
117 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkState);
119 InterVpnLinkKey key = add.getKey();
120 Uuid firstEndpointVpnUuid = add.getFirstEndpoint().getVpnUuid();
121 Uuid secondEndpointVpnUuid = add.getSecondEndpoint().getVpnUuid();
123 if (!checkVpnAvailability(key, firstEndpointVpnUuid)) {
124 String errMsg = String.format("Vpn already associated with a previous inter-vpn-link {}",
125 firstEndpointVpnUuid);
127 setInError(vpnLinkStateIid, vpnLinkState, errMsg);
132 if (!checkVpnAvailability(key, secondEndpointVpnUuid)) {
133 String errMsg = String.format("Vpn already associated with a previous inter-vpn-link {}",
134 secondEndpointVpnUuid);
136 setInError(vpnLinkStateIid, vpnLinkState, errMsg);
140 // TODO: Doing like this we are retrieving operative DPNs from MDSAL when we just need one. Fix it
141 List<BigInteger> firstDpnList = VpnUtil.pickRandomDPNs(dataBroker, numberOfDpns, null);
142 if (firstDpnList != null && !firstDpnList.isEmpty()) {
143 // TODO: Limitation to be solved later
144 // List<BigInteger> secondDpnList = VpnUtil.pickRandomDPNs(dataBroker, numberOfDpns, firstDpnList);
145 List<BigInteger> secondDpnList = firstDpnList;
147 Integer firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
148 Integer secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
149 FirstEndpointState firstEndPointState =
150 new FirstEndpointStateBuilder().setVpnUuid(firstEndpointVpnUuid).setDpId(firstDpnList)
151 .setLportTag(firstVpnLportTag).build();
152 SecondEndpointState secondEndPointState =
153 new SecondEndpointStateBuilder().setVpnUuid(secondEndpointVpnUuid).setDpId(secondDpnList)
154 .setLportTag(secondVpnLportTag).build();
156 InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, add.getName(), InterVpnLinkState.State.Active,
157 firstEndPointState, secondEndPointState);
159 // Note that in the DPN of the firstEndpoint we install the lportTag of the secondEndpoint and viceversa
160 InterVpnLinkUtil.installLPortDispatcherTableFlow(dataBroker, mdsalManager, add, firstDpnList,
161 secondEndpointVpnUuid, secondVpnLportTag);
162 InterVpnLinkUtil.installLPortDispatcherTableFlow(dataBroker, mdsalManager, add, secondDpnList,
163 firstEndpointVpnUuid, firstVpnLportTag);
164 // Update the VPN -> DPNs Map.
165 // Note: when a set of DPNs is calculated for Vpn1, these DPNs are added to the VpnToDpn map of Vpn2. Why?
166 // because we do the handover from Vpn1 to Vpn2 in those DPNs, so in those DPNs we must know how to reach
167 // to Vpn2 targets. If new Vpn2 targets are added later, the Fib will be maintained in these DPNs even if
168 // Vpn2 is not physically present there.
169 InterVpnLinkUtil.updateVpnToDpnMap(dataBroker, firstDpnList, secondEndpointVpnUuid);
170 InterVpnLinkUtil.updateVpnToDpnMap(dataBroker, secondDpnList, firstEndpointVpnUuid);
172 // Now, if the corresponding flags are activated, there will be some routes exchange
173 leakRoutesIfNeeded(add);
175 // If there is no connection to DPNs, the InterVpnLink is created and the InterVpnLinkState is also created
176 // with the corresponding LPortTags but no DPN is assigned since there is no DPN operative.
177 Integer firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + firstEndpointVpnUuid.getValue());
178 Integer secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + secondEndpointVpnUuid.getValue());
179 FirstEndpointState firstEndPointState =
180 new FirstEndpointStateBuilder().setVpnUuid(firstEndpointVpnUuid)
181 .setLportTag(firstVpnLportTag).build();
182 SecondEndpointState secondEndPointState =
183 new SecondEndpointStateBuilder().setVpnUuid(secondEndpointVpnUuid)
184 .setLportTag(secondVpnLportTag).build();
185 InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, add.getName(), InterVpnLinkState.State.Error,
186 firstEndPointState, secondEndPointState);
192 private void leakRoutesIfNeeded(InterVpnLink vpnLink) {
194 // The type of routes to exchange depend on the leaking flags that have been activated
195 List<RouteOrigin> originsToConsider = new ArrayList<>();
196 if ( vpnLink.isBgpRoutesLeaking() ) {
197 originsToConsider.add(RouteOrigin.BGP);
200 /* For now, only BGP leaking. Leave this here for when the other leakings are activated
201 if ( vpnLink.isConnectedRoutesLeaking() ) {
202 originsToConsider.add(RouteOrigin.CONNECTED);
204 if ( vpnLink.isStaticRoutesLeaking() ) {
205 originsToConsider.add(RouteOrigin.STATIC);
206 NOTE: There are 2 types of static routes depending on the nexthop:
207 + static route when nexthop is a VM, the Dc-GW or a DPNIP
208 + static route when nexthop is an InterVPN Link
209 Only the 1st type should be considered since the 2nd has a special treatment
211 String vpn1Uuid = vpnLink.getFirstEndpoint().getVpnUuid().getValue();
212 String vpn2Uuid = vpnLink.getSecondEndpoint().getVpnUuid().getValue();
214 if ( ! originsToConsider.isEmpty() ) {
215 // 1st Endpoint ==> 2nd endpoint
216 leakRoutes(vpnLink, vpn1Uuid, vpn2Uuid, originsToConsider);
218 // 2nd Endpoint ==> 1st endpoint
219 leakRoutes(vpnLink, vpnLink.getSecondEndpoint().getVpnUuid().getValue(),
220 vpnLink.getFirstEndpoint().getVpnUuid().getValue(),
224 // Static routes in Vpn1 pointing to Vpn2's endpoint
225 leakExtraRoutesToVpnEndpoint(vpnLink, vpn1Uuid, vpn2Uuid);
227 // Static routes in Vpn2 pointing to Vpn1's endpoint
228 leakExtraRoutesToVpnEndpoint(vpnLink, vpn2Uuid, vpn1Uuid);
231 private void leakRoutes(InterVpnLink vpnLink, String srcVpnUuid, String dstVpnUuid,
232 List<RouteOrigin> originsToConsider) {
233 String srcVpnRd = VpnUtil.getVpnRd(dataBroker, srcVpnUuid);
234 String dstVpnRd = VpnUtil.getVpnRd(dataBroker, dstVpnUuid);
235 List<VrfEntry> srcVpnRemoteVrfEntries = VpnUtil.getVrfEntriesByOrigin(dataBroker, srcVpnRd, originsToConsider);
236 for ( VrfEntry vrfEntry : srcVpnRemoteVrfEntries ) {
237 long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
238 VpnUtil.getNextHopLabelKey(dstVpnRd, vrfEntry.getDestPrefix()));
240 VpnUtil.leakRoute(dataBroker, bgpManager, vpnLink, srcVpnUuid, dstVpnUuid,
241 vrfEntry.getDestPrefix(), label);
246 * Checks if there are static routes in Vpn1 whose nexthop is Vpn2's endpoint. Those routes must be leaked to Vpn1.
252 private void leakExtraRoutesToVpnEndpoint(InterVpnLink vpnLink, String vpn1Uuid, String vpn2Uuid) {
254 String vpn1Rd = VpnUtil.getVpnRd(dataBroker, vpn1Uuid);
255 String vpn2Endpoint = vpnLink.getSecondEndpoint().getIpAddress().getValue();
256 List<VrfEntry> allVpnVrfEntries = VpnUtil.getAllVrfEntries(dataBroker, vpn1Rd);
257 for ( VrfEntry vrfEntry : allVpnVrfEntries ) {
258 if ( vrfEntry.getNextHopAddressList() != null
259 && vrfEntry.getNextHopAddressList().contains(vpn2Endpoint) ) {
260 // Vpn1 has a route pointing to Vpn2's endpoint. Forcing the leaking of the route will update the
262 long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
263 VpnUtil.getNextHopLabelKey(vpn1Rd, vrfEntry.getDestPrefix()));
265 VpnUtil.leakRoute(dataBroker, bgpManager, vpnLink, vpn2Uuid, vpn1Uuid, vrfEntry.getDestPrefix(),
266 label, RouteOrigin.value(vrfEntry.getOrigin()));
272 private boolean checkVpnAvailability(InterVpnLinkKey key, Uuid vpnId) {
273 Preconditions.checkNotNull(vpnId);
275 List<InterVpnLink> interVpnLinks = VpnUtil.getAllInterVpnLinks(dataBroker);
276 if ( interVpnLinks != null ) {
277 for (InterVpnLink interVpnLink : interVpnLinks) {
278 if (!key.equals(interVpnLink.getKey())
279 && (vpnId.equals(interVpnLink.getFirstEndpoint().getVpnUuid())
280 || vpnId.equals(interVpnLink.getSecondEndpoint().getVpnUuid()))) {
290 protected void remove(InstanceIdentifier<InterVpnLink> identifier, InterVpnLink del) {
292 // Remove learnt routes
293 // Remove entries in the LPortDispatcher table
294 // Remove the corresponding entries in InterVpnLinkState
296 // For each endpoint, remove all routes that have been learnt by intervpnLink
297 String vpn1Uuid = del.getFirstEndpoint().getVpnUuid().getValue();
298 String rd1 = VpnUtil.getVpnRdFromVpnInstanceConfig(dataBroker, vpn1Uuid);
299 VpnUtil.removeVrfEntriesByOrigin(dataBroker, rd1, RouteOrigin.INTERVPN);
300 VpnUtil.removeVrfEntriesByNexthop(dataBroker, rd1, del.getSecondEndpoint().getIpAddress().getValue());
302 String vpn2Uuid = del.getSecondEndpoint().getVpnUuid().getValue();
303 String rd2 = VpnUtil.getVpnRdFromVpnInstanceConfig(dataBroker, vpn2Uuid);
304 VpnUtil.removeVrfEntriesByOrigin(dataBroker, rd2, RouteOrigin.INTERVPN);
305 VpnUtil.removeVrfEntriesByNexthop(dataBroker, rd2, del.getFirstEndpoint().getIpAddress().getValue());
307 InterVpnLinkState interVpnLinkState = VpnUtil.getInterVpnLinkState(dataBroker, del.getName());
308 Integer firstEndpointLportTag = interVpnLinkState.getFirstEndpointState().getLportTag();
310 Integer secondEndpointLportTag = interVpnLinkState.getSecondEndpointState().getLportTag();
312 // Remmoving the flow entries in LPortDispatcher table in 1st Endpoint DPNs
313 for ( BigInteger dpnId : interVpnLinkState.getFirstEndpointState().getDpId() ) {
314 String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(del.getName(), secondEndpointLportTag);
315 FlowKey flowKey = new FlowKey(new FlowId(flowRef));
316 Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
317 .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
319 mdsalManager.removeFlow(dpnId, flow);
321 // Also remove the 'fake' iface from the VpnToDpn map
322 VpnUtil.removeIfaceFromVpnToDpnMap(dataBroker, rd1, dpnId, getInterVpnLinkIfaceName(vpn1Uuid, dpnId));
325 // Removing the flow entries in 2nd Endpoint DPNs
326 for ( BigInteger dpnId : interVpnLinkState.getSecondEndpointState().getDpId() ) {
327 String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(del.getName(), firstEndpointLportTag);
328 FlowKey flowKey = new FlowKey(new FlowId(flowRef));
329 Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
330 .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
332 mdsalManager.removeFlow(dpnId, flow);
334 // Also remove the 'fake' iface from the VpnToDpn map
335 VpnUtil.removeIfaceFromVpnToDpnMap(dataBroker, rd2, dpnId, getInterVpnLinkIfaceName(vpn2Uuid, dpnId));
338 // Release idManager wit LPortTag associated to endpoints
339 InterVpnLinkKey key = del.getKey();
340 Uuid firstEndpointVpnUuid = del.getFirstEndpoint().getVpnUuid();
341 Uuid secondEndpointVpnUuid = del.getSecondEndpoint().getVpnUuid();
342 releaseVpnLinkLPortTag(key.getName() + firstEndpointVpnUuid.getValue());
343 releaseVpnLinkLPortTag(key.getName() + secondEndpointVpnUuid.getValue());
345 // Routes with nextHop pointing to an end-point of the inter-vpn-link are populated into FIB table.
346 // The action in that case is a nx_resubmit to LPortDispatcher table. This is done in FibManager.
347 // At this point. we need to check if is there any entry in FIB table pointing to LPortDispatcher table.
348 // Remove it in that case.
351 for ( BigInteger dpnId : interVpnLinkState.getFirstEndpointState().getDpId() ) {
352 removeRouteFromInterVpnLink(dpnId, del.getName(), del.getSecondEndpoint().getIpAddress().getValue());
356 for ( BigInteger dpnId : interVpnLinkState.getSecondEndpointState().getDpId() ) {
357 removeRouteFromInterVpnLink(dpnId, del.getName(), del.getFirstEndpoint().getIpAddress().getValue());
360 // Removing the InterVpnLinkState
361 InstanceIdentifier<InterVpnLinkState> interVpnLinkStateIid = VpnUtil.getInterVpnLinkStateIid(del.getName());
362 VpnUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid);
365 private void releaseVpnLinkLPortTag(String idKey) {
366 ReleaseIdInput releaseIdInput =
367 new ReleaseIdInputBuilder().setPoolName(VpnConstants.PSEUDO_LPORT_TAG_ID_POOL_NAME).setIdKey(idKey).build();
368 idManager.releaseId(releaseIdInput);
372 protected void update(InstanceIdentifier<InterVpnLink> identifier, InterVpnLink original, InterVpnLink update) {
376 private String getInterVpnFibFlowRef(BigInteger dpnId, short tableId, String interVpnLinkName, String nextHop ) {
377 return new StringBuilder(64).append(VpnConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
378 .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
379 .append(interVpnLinkName).append(NwConstants.FLOWID_SEPARATOR)
380 .append(nextHop).toString();
383 private void removeRouteFromInterVpnLink(BigInteger dpnId, String interVpnLinkName, final String nextHop) {
384 String flowRef = getInterVpnFibFlowRef(dpnId, NwConstants.L3_FIB_TABLE, interVpnLinkName, nextHop);
385 FlowKey flowKey = new FlowKey(new FlowId(flowRef));
386 Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
387 .setTableId(NwConstants.L3_FIB_TABLE).setFlowName(flowRef)
389 mdsalManager.removeFlow(dpnId, flow);
393 private Integer allocateVpnLinkLportTag(String idKey) {
394 AllocateIdInput getIdInput =
395 new AllocateIdInputBuilder().setPoolName(VpnConstants.PSEUDO_LPORT_TAG_ID_POOL_NAME)
399 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
400 RpcResult<AllocateIdOutput> rpcResult = result.get();
401 if (rpcResult.isSuccessful()) {
402 return rpcResult.getResult().getIdValue().intValue();
404 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
406 } catch (InterruptedException | ExecutionException e) {
407 LOG.warn("Exception when getting Unique Id",e);
412 protected void setInError(final InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid,
413 final InterVpnLinkState vpnLinkState,
415 // Setting InterVPNLink in error state in MDSAL
416 InterVpnLinkState vpnLinkErrorState =
417 new InterVpnLinkStateBuilder(vpnLinkState).setState(InterVpnLinkState.State.Error)
418 .setErrorDescription(errorMsg)
420 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
421 tx.put(LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkErrorState, true);
424 // Sending out an error Notification
425 InterVpnLinkCreationErrorMessage errMsg =
426 new InterVpnLinkCreationErrorMessageBuilder().setErrorMessage(errorMsg).build();
427 InterVpnLinkCreationError notif =
428 new InterVpnLinkCreationErrorBuilder().setInterVpnLinkCreationErrorMessage(errMsg).build();
429 final ListenableFuture<? extends Object> eventFuture = this.notificationsService.offerNotification(notif);
430 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
432 public void onFailure(Throwable error) {
433 LOG.warn("Error when sending notification about InterVpnLink creation issue. InterVpnLink name={}. Error={}",
434 vpnLinkState.getInterVpnLinkName(), vpnLinkState, error);
438 public void onSuccess(Object arg) {
439 LOG.trace("Error notification for InterVpnLink successfully sent. VpnLink={} error={}",
440 vpnLinkState.getInterVpnLinkName(), vpnLinkState);