Skip to content

Commit

Permalink
BDP: do not chain leak bgp routes (#6574)
Browse files Browse the repository at this point in the history
Keep local state such that BGP routes imported from other vrfs are not considered for later export to leak to other VRFs
  • Loading branch information
progwriter committed Jan 19, 2021
1 parent 8334de4 commit 5f3a9b4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
Expand Down Expand Up @@ -146,6 +147,11 @@ final class BgpRoutingProcess implements RoutingProcess<BgpTopology, BgpRoute<?,
@Nonnull private Builder<Bgpv4Route> _bgpv4DeltaBuilder = RibDelta.builder();
/** {@link RibDelta} representing changes to {@link #_ebgpv4Rib} in the current iteration */
@Nonnull private Builder<Bgpv4Route> _ebgpv4DeltaBuilder = RibDelta.builder();
/**
* Keep track of routes we had imported from other VRF during leaking, to avoid exporting them
* again (chain leaking).
*/
@Nonnull private final Set<Bgpv4Route> _importedFromOtherVrfs = new HashSet<>(0);
/**
* Keep track of redistributed routes that we have merged into our local RIB.
*
Expand Down Expand Up @@ -1701,12 +1707,15 @@ Once the route is leaked to a new VRF it can become routing again (it could have
getRib(
Bgpv4Route.class,
route.getProtocol() == RoutingProtocol.IBGP ? RibType.IBGP : RibType.EBGP);
Bgpv4Route transformedRoute = builder.build();
if (ra.isWithdrawn()) {
ribDeltaBuilders.get(targetRib).remove(builder.build(), Reason.WITHDRAW);
ribDeltaBuilders.get(targetRib).remove(transformedRoute, Reason.WITHDRAW);
_importedFromOtherVrfs.remove(transformedRoute);
} else {
RibDelta<Bgpv4Route> d = targetRib.mergeRouteGetDelta(builder.build());
RibDelta<Bgpv4Route> d = targetRib.mergeRouteGetDelta(transformedRoute);
LOGGER.debug("Node {}, VRF {}, route {} leaked", _hostname, _vrfName, d);
ribDeltaBuilders.get(targetRib).from(d);
_importedFromOtherVrfs.add(transformedRoute);
}
} else {
LOGGER.trace(
Expand Down Expand Up @@ -1804,8 +1813,9 @@ void removeAggregate(AbstractRoute route) {
* locally-generated and received routes.
*/
Stream<RouteAdvertisement<Bgpv4Route>> getRoutesToLeak() {
// TODO: in the fullness of time this is what getV4Routes should return.
return Stream.concat(_localDeltaPrev.getActions(), _bgpv4DeltaPrev.getActions());
return Stream.concat(
_localDeltaPrev.getActions(),
_bgpv4DeltaPrev.getActions().filter(r -> !_importedFromOtherVrfs.contains(r.getRoute())));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -672,5 +672,10 @@ public void testCrossVrfImport() {
hasNextHop(NextHopVrf.of(otherVrf)),
isNonRouting(false),
hasCommunities(contains(routeTarget))))));

// Finally check that routes imported from other vrfs won't be exported for leaking.
// Fake up end of round
_routingProcess.endOfRound();
assertThat(_routingProcess.getRoutesToLeak().collect(Collectors.toList()), empty());
}
}

0 comments on commit 5f3a9b4

Please sign in to comment.