- private boolean originMustBeLeaked(InterVpnLink ivpnLink, RouteOrigin routeOrigin) {
- return routeOrigin == RouteOrigin.BGP && ivpnLink.isBgpRoutesLeaking()
- || routeOrigin == RouteOrigin.STATIC && ivpnLink.isStaticRoutesLeaking()
- || routeOrigin == RouteOrigin.CONNECTED && ivpnLink.isConnectedRoutesLeaking();
- }
-
- // FIXME: Refactoring needed here.
- // This kind of logic must be taken to an 'upper' layer like BgpManager or VpnManager
- private void leakRouteIfNeeded(final InstanceIdentifier<VrfEntry> vrfEntryIid, final VrfEntry vrfEntry,
- int addOrRemove) {
- Preconditions.checkNotNull(vrfEntry, "VrfEntry cannot be null or empty!");
- final VrfTablesKey vrfTableKey = vrfEntryIid.firstKeyOf(VrfTables.class);
-
- String rd = vrfTableKey.getRouteDistinguisher();
- VpnInstanceOpDataEntry vpnInstance = getVpnInstance(rd);
- if (vpnInstance == null) {
- LOG.error("VPN Instance not available for route with prefix {} label {} nextHop {} RD {}. Returning...",
- vrfEntry.getDestPrefix(), vrfEntry.getLabel(), vrfEntry.getNextHopAddressList(), rd);
- return;
- }
- String vpnUuid = vpnInstance.getVpnInstanceName();
- Preconditions.checkArgument(vpnUuid != null && !vpnUuid.isEmpty(),
- "Could not find suitable VPN UUID for Route-Distinguisher=" + rd);
-
- // if the new vrfEntry has been learned by Quagga BGP, its necessary to check if it's
- // there an interVpnLink for the involved vpn in order to make learn the new route to
- // the other part of the inter-vpn-link.
-
- // For leaking, we need the InterVpnLink to be active. For removal, we just need a InterVpnLink.
- Optional<InterVpnLink> interVpnLink =
- (addOrRemove == NwConstants.ADD_FLOW) ? FibUtil.getActiveInterVpnLinkFromRd(dataBroker, rd)
- : FibUtil.getInterVpnLinkByRd(dataBroker, rd);
- if ( !interVpnLink.isPresent() ) {
- LOG.debug("Could not find an InterVpnLink for Route-Distinguisher={}", rd);
- return;
- }
-
- // Ok, at this point everything is ready for the leaking/removal... but should it be performed?
- // For removal, we remove all leaked routes, but we only leak a route if the corresponding flag is enabled.
- boolean proceed =
- addOrRemove == NwConstants.DEL_FLOW || originMustBeLeaked(interVpnLink.get(),
- RouteOrigin.value(vrfEntry.getOrigin()));
-
- if ( proceed ) {
- boolean isVpnFirstEndpoint = interVpnLink.get().getFirstEndpoint().getVpnUuid().getValue().equals(vpnUuid);
-
- String theOtherVpnId = isVpnFirstEndpoint ? interVpnLink.get().getSecondEndpoint().getVpnUuid().getValue()
- : interVpnLink.get().getFirstEndpoint().getVpnUuid().getValue();
- String dstVpnRd = FibUtil.getVpnRd(dataBroker, theOtherVpnId);
- String endpointIp = isVpnFirstEndpoint ? interVpnLink.get().getFirstEndpoint().getIpAddress().getValue()
- : interVpnLink.get().getSecondEndpoint().getIpAddress().getValue();
-
- InstanceIdentifier<VrfEntry> vrfEntryIidInOtherVpn =
- InstanceIdentifier.builder(FibEntries.class)
- .child(VrfTables.class, new VrfTablesKey(dstVpnRd))
- .child(VrfEntry.class, new VrfEntryKey(vrfEntry.getDestPrefix()))
- .build();
- if ( addOrRemove == NwConstants.ADD_FLOW ) {
- LOG.debug("Leaking route (destination={}, nexthop={}) from Vrf={} to Vrf={}",
- vrfEntry.getDestPrefix(), vrfEntry.getNextHopAddressList(), rd, dstVpnRd);
- String key = rd + FibConstants.SEPARATOR + vrfEntry.getDestPrefix();
- long label = FibUtil.getUniqueId(idManager, FibConstants.VPN_IDPOOL_NAME, key);
- VrfEntry newVrfEntry = new VrfEntryBuilder(vrfEntry).setNextHopAddressList(Arrays.asList(endpointIp))
- .setLabel(label)
- .setOrigin(RouteOrigin.INTERVPN.getValue())
- .build();
- MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryIidInOtherVpn, newVrfEntry);
- } else {
- LOG.debug("Removing leaked vrfEntry={}", vrfEntryIidInOtherVpn.toString());
- MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryIidInOtherVpn);
- }