2 * Copyright (c) 2016, 2017 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.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.stream.Collectors;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.genius.mdsalutil.MDSALUtil;
21 import org.opendaylight.genius.mdsalutil.MatchInfo;
22 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
23 import org.opendaylight.genius.mdsalutil.NwConstants;
24 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
25 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
26 import org.opendaylight.genius.utils.ServiceIndex;
27 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
28 import org.opendaylight.netvirt.fibmanager.api.FibHelper;
29 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
30 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
31 import org.opendaylight.netvirt.vpnmanager.VpnConstants;
32 import org.opendaylight.netvirt.vpnmanager.VpnFootprintService;
33 import org.opendaylight.netvirt.vpnmanager.VpnUtil;
34 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
35 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkCache;
36 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkDataComposite;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkStateBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkStateKey;
50 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;
51 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;
52 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;
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.SecondEndpointStateBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLinkKey;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
61 * This class contains methods to be used as utilities related with inter-vpn-link.
63 public final class InterVpnLinkUtil {
65 private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkUtil.class);
67 private InterVpnLinkUtil() { }
70 * Retrieves the Instance Identifier that points to an InterVpnLink object
73 * @param interVpnLinkName The name of the InterVpnLink
74 * @return The requested InstanceIdentifier
76 public static InstanceIdentifier<InterVpnLink> getInterVpnLinkPath(String interVpnLinkName) {
77 return InstanceIdentifier.builder(InterVpnLinks.class)
78 .child(InterVpnLink.class, new InterVpnLinkKey(interVpnLinkName))
83 * Retrieves the Instance Identifier that points to an InterVpnLinkState object
86 * @param vpnLinkName The name of the InterVpnLink
87 * @return The requested InstanceIdentifier
89 public static InstanceIdentifier<InterVpnLinkState> getInterVpnLinkStateIid(String vpnLinkName) {
90 return InstanceIdentifier.builder(InterVpnLinkStates.class)
91 .child(InterVpnLinkState.class, new InterVpnLinkStateKey(vpnLinkName))
95 public static String buildInterVpnLinkIfaceName(String vpnName, BigInteger dpnId) {
96 return String.format("InterVpnLink.%s.%s", vpnName, dpnId.toString());
100 * Updates VpnToDpn map by adding a fake VpnInterface related to an
101 * InterVpnLink in the corresponding DPNs. If the fake iface is the
102 * first one on the any of the specified DPNs, the installation of
103 * Fib flows on that DPN will be triggered.
105 * @param vpnFootprintService VpnFootprintService service reference
106 * @param vpnName Name of the VPN to which the fake interfaces belong
107 * @param dpnList List of DPNs where the fake InterVpnLink interface must be added
109 public static void updateVpnFootprint(VpnFootprintService vpnFootprintService, String vpnName,
110 String primaryRd, List<BigInteger> dpnList) {
111 LOG.debug("updateVpnFootprint (add): vpn={} dpnList={}", vpnName, dpnList);
112 // Note: when a set of DPNs is calculated for Vpn1, these DPNs are added to the VpnToDpn map of Vpn2. Why?
113 // because we do the handover from Vpn1 to Vpn2 in those DPNs, so in those DPNs we must know how to reach
114 // to Vpn2 targets. If new Vpn2 targets are added later, the Fib will be maintained in these DPNs even if
115 // Vpn2 is not physically present there.
116 for (BigInteger dpnId : dpnList) {
117 String ifaceName = buildInterVpnLinkIfaceName(vpnName, dpnId);
118 vpnFootprintService.updateVpnToDpnMapping(dpnId, vpnName, primaryRd, ifaceName,
119 null/*ipAddressSourceValuePair*/, true /* addition */);
124 * Updates VpnToDpn map by removing the fake VpnInterface related to an
125 * InterVpnLink in the corresponding DPNs.
127 * @param vpnFootprintService VpnFootprintService service reference
128 * @param vpnName Name of the VPN to which the fake interfaces belong
129 * @param dpnId DPN where the fake InterVpnLink interface must be removed from
131 public static void removeIVpnLinkIfaceFromVpnFootprint(VpnFootprintService vpnFootprintService,
132 String vpnName, String rd, BigInteger dpnId) {
133 String ifaceName = buildInterVpnLinkIfaceName(vpnName, dpnId);
134 LOG.debug("updateVpnFootprint (remove): vpn={} dpn={} ifaceName={}", vpnName, dpnId, ifaceName);
135 vpnFootprintService.updateVpnToDpnMapping(dpnId, vpnName, rd, ifaceName,
136 null/*ipAddressSourceValuePair*/, false /* removal */);
140 public static FirstEndpointState buildFirstEndpointState(FirstEndpointState original,
141 Optional<List<BigInteger>> new1stEndpointDpns,
142 Optional<Long> new1stEndpointLportTag) {
143 FirstEndpointStateBuilder builder = new FirstEndpointStateBuilder(original);
144 if (new1stEndpointDpns.isPresent()) {
145 builder.setDpId(new1stEndpointDpns.get());
147 if (new1stEndpointLportTag.isPresent()) {
148 builder.setLportTag(new1stEndpointLportTag.get());
150 return builder.build();
153 public static FirstEndpointState buildFirstEndpointState(String vpnName, List<BigInteger> dpnList, long lportTag) {
154 return new FirstEndpointStateBuilder().setVpnUuid(new Uuid(vpnName)).setDpId(dpnList).setLportTag(lportTag)
158 public static SecondEndpointState buildSecondEndpointState(SecondEndpointState original,
159 Optional<List<BigInteger>> new2ndEndpointDpns,
160 Optional<Long> new2ndEndpointLportTag) {
161 SecondEndpointStateBuilder builder = new SecondEndpointStateBuilder(original);
162 if (new2ndEndpointDpns.isPresent()) {
163 builder.setDpId(new2ndEndpointDpns.get());
165 if (new2ndEndpointLportTag.isPresent()) {
166 builder.setLportTag(new2ndEndpointLportTag.get());
168 return builder.build();
171 public static SecondEndpointState buildSecondEndpointState(String vpnName, List<BigInteger> dpnList,
173 return new SecondEndpointStateBuilder().setVpnUuid(new Uuid(vpnName)).setDpId(dpnList).setLportTag(lportTag)
178 * Creates an InterVpnLinkState out of an existing one and modifying only the desired attributes.
180 * @param original InterVpnLinkState to start from.
181 * @param new1stEndpointState Sets this FirstEndpointState if present
182 * @param new2ndEndpointState Sets this SecondEndpointState if present
183 * @param errDescription Sets this ErrorDescription if present
184 * @return the newly build InterVpnLinkState
186 public static InterVpnLinkState buildIvlStateFromOriginal(InterVpnLinkState original,
187 Optional<FirstEndpointState> new1stEndpointState,
188 Optional<SecondEndpointState> new2ndEndpointState,
189 Optional<String> errDescription) {
190 InterVpnLinkStateBuilder ivlStateBuilder = new InterVpnLinkStateBuilder(original);
191 if (new1stEndpointState.isPresent()) {
192 ivlStateBuilder.setFirstEndpointState(new1stEndpointState.get());
194 if (new2ndEndpointState.isPresent()) {
195 ivlStateBuilder.setSecondEndpointState(new2ndEndpointState.get());
197 if (errDescription.isPresent()) {
198 ivlStateBuilder.setErrorDescription(errDescription.get());
200 return ivlStateBuilder.build();
204 * Updates inter-VPN link state.
206 * @param broker dataBroker service reference
207 * @param vpnLinkName The name of the InterVpnLink
208 * @param state Sets the state of the InterVpnLink to Active or Error
209 * @param newFirstEndpointState Updates the lportTag and/or DPNs of the 1st endpoint of the InterVpnLink
210 * @param newSecondEndpointState Updates the lportTag and/or DPNs of the 2nd endpoint of the InterVpnLink
211 * @param interVpnLinkCache the InterVpnLinkCache
213 public static void updateInterVpnLinkState(DataBroker broker, String vpnLinkName, InterVpnLinkState.State state,
214 FirstEndpointState newFirstEndpointState, SecondEndpointState newSecondEndpointState,
215 InterVpnLinkCache interVpnLinkCache) {
216 Optional<InterVpnLinkState> optOldVpnLinkState = getInterVpnLinkState(broker, vpnLinkName);
217 if (optOldVpnLinkState.isPresent()) {
218 InterVpnLinkState newVpnLinkState =
219 new InterVpnLinkStateBuilder(optOldVpnLinkState.get()).setState(state)
220 .setFirstEndpointState(newFirstEndpointState)
221 .setSecondEndpointState(newSecondEndpointState)
223 VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION,
224 InterVpnLinkUtil.getInterVpnLinkStateIid(vpnLinkName), newVpnLinkState);
225 interVpnLinkCache.addInterVpnLinkStateToCaches(newVpnLinkState);
227 InterVpnLinkState newIVpnLinkState =
228 new InterVpnLinkStateBuilder().setKey(new InterVpnLinkStateKey(vpnLinkName))
229 .setInterVpnLinkName(vpnLinkName)
230 .setFirstEndpointState(newFirstEndpointState)
231 .setSecondEndpointState(newSecondEndpointState)
232 .setState(InterVpnLinkState.State.Active)
234 VpnUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
235 InterVpnLinkUtil.getInterVpnLinkStateIid(vpnLinkName), newIVpnLinkState);
236 interVpnLinkCache.addInterVpnLinkStateToCaches(newIVpnLinkState);
241 * Installs a Flow in LPortDispatcher table that matches on SI=2 and
242 * the lportTag of one InterVpnLink's endpoint and sets the vrfTag of the
243 * other endpoint and sends to FIB table.
245 * @param broker dataBroker service reference
246 * @param mdsalManager MDSAL API accessor
247 * @param interVpnLinkName Name of the InterVpnLink.
248 * @param dpnList The list of DPNs where this flow must be installed
249 * @param vpnUuidOtherEndpoint UUID of the other endpoint of the InterVpnLink
250 * @param lportTagOfOtherEndpoint Dataplane identifier of the other endpoint of the InterVpnLink
251 * @return the list of Futures for each and every flow that has been installed
253 public static List<ListenableFuture<Void>> installLPortDispatcherTableFlow(DataBroker broker,
254 IMdsalApiManager mdsalManager,
255 String interVpnLinkName,
256 List<BigInteger> dpnList,
257 String vpnUuidOtherEndpoint,
258 Long lportTagOfOtherEndpoint) {
259 List<ListenableFuture<Void>> result = new ArrayList<>();
260 long vpnId = VpnUtil.getVpnId(broker, vpnUuidOtherEndpoint);
261 for (BigInteger dpnId : dpnList) {
262 // insert into LPortDispatcher table
263 Flow lportDispatcherFlow = buildLPortDispatcherFlow(interVpnLinkName, vpnId,
264 lportTagOfOtherEndpoint.intValue());
265 result.add(mdsalManager.installFlow(dpnId, lportDispatcherFlow));
272 * Builds a Flow to be installed into LPortDispatcher table, that matches on
273 * SI=2 + vpnLinkEndpointPseudoPortTag and sends to FIB.
275 * @param interVpnLinkName The name of the InterVpnLink
276 * @param vpnId Dataplane identifier of the VPN, the Vrf Tag.
277 * @param lportTag DataPlane identifier of the LogicalPort.
278 * @return the Flow ready to be installed
280 public static Flow buildLPortDispatcherFlow(String interVpnLinkName, long vpnId, int lportTag) {
281 LOG.info("Inter-vpn-link : buildLPortDispatcherFlow. vpnId {} lportTag {} ", vpnId, lportTag);
282 List<MatchInfo> matches = Collections.singletonList(new MatchMetadata(
283 MetaDataUtil.getMetaDataForLPortDispatcher(lportTag,
284 ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)),
285 MetaDataUtil.getMetaDataMaskForLPortDispatcher()));
286 String flowRef = getLportDispatcherFlowRef(interVpnLinkName, lportTag);
288 return MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef,
289 VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY, flowRef,
290 0, 0, VpnUtil.getCookieL3((int) vpnId), matches,
291 buildLportDispatcherTableInstructions(vpnId));
295 * Builds a flowRef to be assigned to the flow to be installed into
296 * LPortDispatcher table.
298 * @param interVpnLinkName The name of the InterVpnLink
299 * @param lportTag Dataplane identifier of the LogicalPort
300 * @return the flow reference string
302 public static String getLportDispatcherFlowRef(String interVpnLinkName, Integer lportTag) {
303 return VpnConstants.FLOWID_PREFIX + "INTERVPNLINK" + NwConstants.FLOWID_SEPARATOR + interVpnLinkName
304 + NwConstants.FLOWID_SEPARATOR + lportTag
305 + NwConstants.FLOWID_SEPARATOR + ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
306 NwConstants.L3VPN_SERVICE_INDEX)
307 + NwConstants.FLOWID_SEPARATOR + VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY;
311 public static List<Instruction> buildLportDispatcherTableInstructions(long vpnId) {
312 int instructionKey = 0;
313 List<Instruction> instructions = new ArrayList<>();
314 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(MetaDataUtil.getVpnIdMetadata(vpnId),
315 MetaDataUtil.METADATA_MASK_VRFID,
317 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey));
323 * Retrieves the States of all InterVpnLinks.
325 * @param broker dataBroker service reference
326 * @return the list of objects that holds the InterVpnLink state information
328 public static List<InterVpnLinkState> getAllInterVpnLinkState(DataBroker broker) {
329 InstanceIdentifier<InterVpnLinkStates> interVpnLinkStateIid =
330 InstanceIdentifier.builder(InterVpnLinkStates.class).build();
332 Optional<InterVpnLinkStates> interVpnLinkStateOpData =
333 MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid);
335 return interVpnLinkStateOpData.isPresent() ? interVpnLinkStateOpData.get().getInterVpnLinkState()
340 * Retrieves the State of an InterVpnLink.
342 * @param broker dataBroker service reference
343 * @param interVpnLinkName The name of the InterVpnLink
344 * @return the object that contains the State of the specified InterVpnLink or Optional.absent() if it doesnt exist
346 public static Optional<InterVpnLinkState> getInterVpnLinkState(DataBroker broker, String interVpnLinkName) {
347 return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, getInterVpnLinkStateIid(interVpnLinkName));
351 * Retrieves all configured InterVpnLinks.
353 * @param broker dataBroker service reference
354 * @return the list of InterVpnLinks
356 public static List<InterVpnLink> getAllInterVpnLinks(DataBroker broker) {
357 InstanceIdentifier<InterVpnLinks> interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build();
359 Optional<InterVpnLinks> interVpnLinksOpData =
360 MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinksIid);
362 return interVpnLinksOpData.isPresent() ? interVpnLinksOpData.get().getInterVpnLink()
367 * Leaks a route from one VPN to another. By default, the origin for this leaked route is INTERVPN.
369 * @param broker dataBroker service reference
370 * @param bgpManager Used to advertise routes to the BGP Router
371 * @param interVpnLink Reference to the object that holds the info about the link between the 2 VPNs
372 * @param srcVpnUuid UUID of the VPN that has the route that is going to be leaked to the other VPN
373 * @param dstVpnUuid UUID of the VPN that is going to receive the route
374 * @param prefix Prefix of the route
375 * @param label Label of the route in the original VPN
377 // TODO Clean up the exception handling
378 @SuppressWarnings("checkstyle:IllegalCatch")
379 public static void leakRoute(DataBroker broker, IBgpManager bgpManager, InterVpnLink interVpnLink,
380 String srcVpnUuid, String dstVpnUuid, String prefix, Long label) {
381 Preconditions.checkNotNull(interVpnLink);
383 // The source VPN must participate in the InterVpnLink
384 Preconditions.checkArgument(interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(srcVpnUuid)
385 || interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(srcVpnUuid),
386 "The source VPN {} does not participate in the interVpnLink {}",
387 srcVpnUuid, interVpnLink.getName());
388 // The destination VPN must participate in the InterVpnLink
389 Preconditions.checkArgument(interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(dstVpnUuid)
390 || interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(dstVpnUuid),
391 "The destination VPN {} does not participate in the interVpnLink {}",
392 dstVpnUuid, interVpnLink.getName());
394 boolean destinationIs1stEndpoint = interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(dstVpnUuid);
396 String endpointIp = destinationIs1stEndpoint ? interVpnLink.getSecondEndpoint().getIpAddress().getValue()
397 : interVpnLink.getFirstEndpoint().getIpAddress().getValue();
399 VrfEntry newVrfEntry = FibHelper.getVrfEntryBuilder(prefix, label, endpointIp, RouteOrigin.INTERVPN,
400 null /* parentVpnRd */).build();
402 String dstVpnRd = VpnUtil.getVpnRd(broker, dstVpnUuid);
403 InstanceIdentifier<VrfEntry> newVrfEntryIid =
404 InstanceIdentifier.builder(FibEntries.class)
405 .child(VrfTables.class, new VrfTablesKey(dstVpnRd))
406 .child(VrfEntry.class, new VrfEntryKey(newVrfEntry.getDestPrefix()))
408 VpnUtil.asyncWrite(broker, LogicalDatastoreType.CONFIGURATION, newVrfEntryIid, newVrfEntry);
410 // Finally, route is advertised it to the DC-GW. But while in the FibEntries the nexthop is the other
411 // endpoint's IP, in the DC-GW the nexthop for those prefixes are the IPs of those DPNs where the target
412 // VPN has been instantiated
413 Optional<InterVpnLinkState> optVpnLinkState = getInterVpnLinkState(broker, interVpnLink.getName());
414 if (optVpnLinkState.isPresent()) {
415 InterVpnLinkState vpnLinkState = optVpnLinkState.get();
416 List<BigInteger> dpnIdList = destinationIs1stEndpoint ? vpnLinkState.getFirstEndpointState().getDpId()
417 : vpnLinkState.getSecondEndpointState().getDpId();
418 List<String> nexthops = new ArrayList<>();
419 for (BigInteger dpnId : dpnIdList) {
420 nexthops.add(InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId));
423 LOG.debug("Advertising route in VPN={} [prefix={} label={} nexthops={}] to DC-GW",
424 dstVpnRd, newVrfEntry.getDestPrefix(), label.intValue(), nexthops);
425 bgpManager.advertisePrefix(dstVpnRd, null /*macAddress*/, newVrfEntry.getDestPrefix(), nexthops,
426 VrfEntry.EncapType.Mplsgre, label.intValue(), 0 /*l3vni*/, 0 /*l2vni*/,
427 null /*gatewayMacAddress*/);
428 } catch (Exception ex) {
429 LOG.error("Could not advertise prefix {} with label {} to VPN rd={}",
430 newVrfEntry.getDestPrefix(), label.intValue(), dstVpnRd, ex);
433 LOG.warn("Error when advertising leaked routes: Could not find State for InterVpnLink={}",
434 interVpnLink.getName());
438 public static void handleStaticRoute(InterVpnLinkDataComposite interVpnLink, String vpnName,
439 String destination, String nexthop, int label,
440 DataBroker dataBroker, IFibManager fibManager, IBgpManager bgpManager) throws Exception {
442 LOG.debug("handleStaticRoute [vpnLink={} srcVpn={} destination={} nextHop={} label={}]",
443 interVpnLink.getInterVpnLinkName(), vpnName, destination, nexthop, label);
445 String vpnRd = VpnUtil.getVpnRd(dataBroker, vpnName);
447 LOG.warn("Could not find Route-Distinguisher for VpnName {}", vpnName);
450 LOG.debug("Writing FibEntry to DS: vpnRd={}, prefix={}, label={}, nexthop={} (interVpnLink)",
451 vpnRd, destination, label, nexthop);
452 fibManager.addOrUpdateFibEntry(vpnRd, null /*macAddress*/, destination,
453 Collections.singletonList(nexthop), VrfEntry.EncapType.Mplsgre, label,
454 0 /*l3vni*/, null /*gatewayMacAddress*/, null /*parentVpnRd*/, RouteOrigin.STATIC, null /*writeTxn*/);
456 // Now advertise to BGP. The nexthop that must be advertised to BGP are the IPs of the DPN where the
457 // VPN's endpoint have been instantiated
458 // List<String> nexthopList = new ArrayList<>(); // The nexthops to be advertised to BGP
459 List<BigInteger> endpointDpns = interVpnLink.getEndpointDpnsByVpnName(vpnName);
460 List<String> nexthopList =
461 endpointDpns.stream().map(dpnId -> InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, dpnId))
462 .collect(Collectors.toList());
463 LOG.debug("advertising IVpnLink route to BGP: vpnRd={}, prefix={}, label={}, nexthops={}",
464 vpnRd, destination, label, nexthopList);
465 bgpManager.advertisePrefix(vpnRd, null /*macAddress*/, destination, nexthopList,
466 VrfEntry.EncapType.Mplsgre, label, 0 /*l3vni*/, 0 /*l2vni*/,
467 null /*gatewayMacAddress*/);