use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class VirtualRouterTest method computeBgpAdvertisementsSTOIbgpAdditionalPaths.
@Test
public void computeBgpAdvertisementsSTOIbgpAdditionalPaths() {
RoutingPolicy exportPolicy = _routingPolicyBuilder.setStatements(ImmutableList.of(_exitAcceptStatement)).build();
_bgpNeighborBuilder.setRemoteAs(TEST_AS1).setExportPolicy(exportPolicy.getName()).setAdditionalPathSend(true).setAdditionalPathSelectAll(true).build();
_testVirtualRouter._bgpMultipathRib.mergeRoute(_bgpRouteBuilder.setReceivedFromIp(TEST_NEXT_HOP_IP1).setNextHopIp(TEST_NEXT_HOP_IP1).build());
// adding second similar route in the Multipath rib with a different Next Hop IP
_testVirtualRouter._bgpMultipathRib.mergeRoute(_bgpRouteBuilder.setReceivedFromIp(TEST_NEXT_HOP_IP2).setNextHopIp(TEST_NEXT_HOP_IP2).build());
// checking that both the routes in BGP Multipath Rib got advertised
assertThat(_testVirtualRouter.computeBgpAdvertisementsToOutside(_ipOwners), equalTo(2));
// checking that both bgp advertisements have the same network and the supplied next hop IPs
Set<Ip> nextHopIps = new HashSet<>();
_testVirtualRouter._sentBgpAdvertisements.stream().forEach(bgpAdvertisement -> {
assertThat(bgpAdvertisement, hasNetwork(TEST_NETWORK));
nextHopIps.add(bgpAdvertisement.getNextHopIp());
});
assertThat("Next Hop IPs not valid in BGP advertisements", nextHopIps, containsInAnyOrder(TEST_NEXT_HOP_IP1, TEST_NEXT_HOP_IP2));
}
use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class VirtualRouter method propagateBgpRoutes.
int propagateBgpRoutes(Map<Ip, Set<String>> ipOwners, int dependentRoutesIterations, SortedSet<Prefix> oscillatingPrefixes, Map<String, Node> nodes) {
int numRoutes = 0;
_receivedBgpAdvertisements = new LinkedHashSet<>();
_prevSentBgpAdvertisements = _sentBgpAdvertisements != null ? _sentBgpAdvertisements : new LinkedHashSet<>();
_sentBgpAdvertisements = new LinkedHashSet<>();
// If we have no BGP process, nothing to do
if (_vrf.getBgpProcess() == null) {
return numRoutes;
}
int ebgpAdminCost = RoutingProtocol.BGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
int ibgpAdminCost = RoutingProtocol.IBGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
for (BgpNeighbor neighbor : _vrf.getBgpProcess().getNeighbors().values()) {
Ip localIp = neighbor.getLocalIp();
Set<String> localIpOwners = ipOwners.get(localIp);
String hostname = _c.getHostname();
if (localIpOwners == null || !localIpOwners.contains(hostname)) {
continue;
}
BgpNeighbor remoteBgpNeighbor = neighbor.getRemoteBgpNeighbor();
if (remoteBgpNeighbor == null) {
continue;
}
int localAs = neighbor.getLocalAs();
int remoteAs = neighbor.getRemoteAs();
Configuration remoteConfig = remoteBgpNeighbor.getOwner();
String remoteHostname = remoteConfig.getHostname();
String remoteVrfName = remoteBgpNeighbor.getVrf();
Vrf remoteVrf = remoteConfig.getVrfs().get(remoteVrfName);
VirtualRouter remoteVirtualRouter = nodes.get(remoteHostname)._virtualRouters.get(remoteVrfName);
RoutingPolicy remoteExportPolicy = remoteConfig.getRoutingPolicies().get(remoteBgpNeighbor.getExportPolicy());
boolean ebgpSession = localAs != remoteAs;
BgpMultipathRib targetRib = ebgpSession ? _ebgpStagingRib : _ibgpStagingRib;
RoutingProtocol targetProtocol = ebgpSession ? RoutingProtocol.BGP : RoutingProtocol.IBGP;
Set<AbstractRoute> remoteCandidateRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
// Add IGP routes
Set<AbstractRoute> activeRemoteRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
activeRemoteRoutes.addAll(remoteVirtualRouter._prevMainRib.getRoutes());
for (AbstractRoute remoteCandidateRoute : activeRemoteRoutes) {
if (remoteCandidateRoute.getProtocol() != RoutingProtocol.BGP && remoteCandidateRoute.getProtocol() != RoutingProtocol.IBGP) {
remoteCandidateRoutes.add(remoteCandidateRoute);
}
}
/*
* bgp advertise-external
*
* When this is set, add best eBGP path independently of whether
* it is preempted by an iBGP or IGP route. Only applicable to
* iBGP sessions.
*/
boolean advertiseExternal = !ebgpSession && remoteBgpNeighbor.getAdvertiseExternal();
if (advertiseExternal) {
remoteCandidateRoutes.addAll(remoteVirtualRouter._prevEbgpBestPathRib.getRoutes());
}
/*
* bgp advertise-inactive
*
* When this is set, add best BGP path independently of whether
* it is preempted by an IGP route. Only applicable to eBGP
* sessions.
*/
boolean advertiseInactive = ebgpSession && remoteBgpNeighbor.getAdvertiseInactive();
/* Add best bgp paths if they are active, or if advertise-inactive */
for (AbstractRoute remoteCandidateRoute : remoteVirtualRouter._prevBgpBestPathRib.getRoutes()) {
if (advertiseInactive || activeRemoteRoutes.contains(remoteCandidateRoute)) {
remoteCandidateRoutes.add(remoteCandidateRoute);
}
}
/* Add all bgp paths if additional-paths active for this session */
boolean additionalPaths = !ebgpSession && neighbor.getAdditionalPathsReceive() && remoteBgpNeighbor.getAdditionalPathsSend() && remoteBgpNeighbor.getAdditionalPathsSelectAll();
if (additionalPaths) {
remoteCandidateRoutes.addAll(remoteVirtualRouter._prevBgpMultipathRib.getRoutes());
}
for (AbstractRoute remoteRoute : remoteCandidateRoutes) {
BgpRoute.Builder transformedOutgoingRouteBuilder = new BgpRoute.Builder();
transformedOutgoingRouteBuilder.setReceivedFromIp(remoteBgpNeighbor.getLocalIp());
RoutingProtocol remoteRouteProtocol = remoteRoute.getProtocol();
boolean remoteRouteIsBgp = remoteRouteProtocol == RoutingProtocol.IBGP || remoteRouteProtocol == RoutingProtocol.BGP;
// originatorIP
Ip originatorIp;
if (!ebgpSession && remoteRouteProtocol.equals(RoutingProtocol.IBGP)) {
BgpRoute bgpRemoteRoute = (BgpRoute) remoteRoute;
originatorIp = bgpRemoteRoute.getOriginatorIp();
} else {
originatorIp = remoteVrf.getBgpProcess().getRouterId();
}
transformedOutgoingRouteBuilder.setOriginatorIp(originatorIp);
// note whether new route is received from route reflector client
transformedOutgoingRouteBuilder.setReceivedFromRouteReflectorClient(!ebgpSession && neighbor.getRouteReflectorClient());
// for bgp remote route)
if (remoteRouteIsBgp) {
BgpRoute bgpRemoteRoute = (BgpRoute) remoteRoute;
transformedOutgoingRouteBuilder.setOriginType(bgpRemoteRoute.getOriginType());
if (ebgpSession && bgpRemoteRoute.getAsPath().containsAs(remoteBgpNeighbor.getRemoteAs()) && !remoteBgpNeighbor.getAllowRemoteAsOut()) {
// disable-peer-as-check (getAllowRemoteAsOut) is set
continue;
}
/*
* route reflection: reflect everything received from
* clients to clients and non-clients. reflect everything
* received from non-clients to clients. Do not reflect to
* originator
*/
Ip remoteOriginatorIp = bgpRemoteRoute.getOriginatorIp();
/*
* iBGP speaker should not send out routes to iBGP neighbor whose router-id is
* same as originator id of advertisement
*/
if (!ebgpSession && remoteOriginatorIp != null && _vrf.getBgpProcess().getRouterId().equals(remoteOriginatorIp)) {
continue;
}
if (remoteRouteProtocol.equals(RoutingProtocol.IBGP) && !ebgpSession) {
/*
* The remote route is iBGP. The session is iBGP. We consider whether to reflect, and
* modify the outgoing route as appropriate.
*/
boolean remoteRouteReceivedFromRouteReflectorClient = bgpRemoteRoute.getReceivedFromRouteReflectorClient();
boolean sendingToRouteReflectorClient = remoteBgpNeighbor.getRouteReflectorClient();
Ip remoteReceivedFromIp = bgpRemoteRoute.getReceivedFromIp();
boolean remoteRouteOriginatedByRemoteNeighbor = remoteReceivedFromIp.equals(Ip.ZERO);
if (!remoteRouteReceivedFromRouteReflectorClient && !sendingToRouteReflectorClient && !remoteRouteOriginatedByRemoteNeighbor) {
/*
* Neither reflecting nor originating this iBGP route, so don't send
*/
continue;
}
transformedOutgoingRouteBuilder.getClusterList().addAll(bgpRemoteRoute.getClusterList());
if (!remoteRouteOriginatedByRemoteNeighbor) {
// we are reflecting, so we need to get the clusterid associated with the remoteRoute
BgpNeighbor remoteReceivedFromSession = remoteVrf.getBgpProcess().getNeighbors().get(new Prefix(remoteReceivedFromIp, Prefix.MAX_PREFIX_LENGTH));
long newClusterId = remoteReceivedFromSession.getClusterId();
transformedOutgoingRouteBuilder.getClusterList().add(newClusterId);
}
Set<Long> localClusterIds = _vrf.getBgpProcess().getClusterIds();
Set<Long> outgoingClusterList = transformedOutgoingRouteBuilder.getClusterList();
if (localClusterIds.stream().anyMatch(outgoingClusterList::contains)) {
/*
* receiver will reject new route if it contains any of its local cluster ids
*/
continue;
}
}
}
// Outgoing communities
if (remoteRouteIsBgp) {
BgpRoute bgpRemoteRoute = (BgpRoute) remoteRoute;
transformedOutgoingRouteBuilder.setAsPath(bgpRemoteRoute.getAsPath().getAsSets());
if (remoteBgpNeighbor.getSendCommunity()) {
transformedOutgoingRouteBuilder.getCommunities().addAll(bgpRemoteRoute.getCommunities());
}
}
if (ebgpSession) {
SortedSet<Integer> newAsPathElement = new TreeSet<>();
newAsPathElement.add(remoteAs);
transformedOutgoingRouteBuilder.getAsPath().add(0, newAsPathElement);
}
// Outgoing protocol
transformedOutgoingRouteBuilder.setProtocol(targetProtocol);
transformedOutgoingRouteBuilder.setNetwork(remoteRoute.getNetwork());
// Outgoing metric
if (remoteRouteIsBgp) {
transformedOutgoingRouteBuilder.setMetric(remoteRoute.getMetric());
}
// Outgoing nextHopIp
// Outgoing localPreference
Ip nextHopIp;
int localPreference;
if (ebgpSession || !remoteRouteIsBgp) {
nextHopIp = remoteBgpNeighbor.getLocalIp();
localPreference = BgpRoute.DEFAULT_LOCAL_PREFERENCE;
} else {
nextHopIp = remoteRoute.getNextHopIp();
BgpRoute remoteIbgpRoute = (BgpRoute) remoteRoute;
localPreference = remoteIbgpRoute.getLocalPreference();
}
if (nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) {
// should only happen for ibgp
String nextHopInterface = remoteRoute.getNextHopInterface();
InterfaceAddress nextHopAddress = remoteVrf.getInterfaces().get(nextHopInterface).getAddress();
if (nextHopAddress == null) {
throw new BatfishException("remote route's nextHopInterface has no address");
}
nextHopIp = nextHopAddress.getIp();
}
transformedOutgoingRouteBuilder.setNextHopIp(nextHopIp);
transformedOutgoingRouteBuilder.setLocalPreference(localPreference);
// Outgoing srcProtocol
transformedOutgoingRouteBuilder.setSrcProtocol(remoteRoute.getProtocol());
/*
* CREATE OUTGOING ROUTE
*/
boolean acceptOutgoing = remoteExportPolicy.process(remoteRoute, transformedOutgoingRouteBuilder, localIp, remoteVrfName, Direction.OUT);
if (acceptOutgoing) {
BgpRoute transformedOutgoingRoute = transformedOutgoingRouteBuilder.build();
// Record sent advertisement
BgpAdvertisementType sentType = ebgpSession ? BgpAdvertisementType.EBGP_SENT : BgpAdvertisementType.IBGP_SENT;
Ip sentReceivedFromIp = transformedOutgoingRoute.getReceivedFromIp();
Ip sentOriginatorIp = transformedOutgoingRoute.getOriginatorIp();
SortedSet<Long> sentClusterList = transformedOutgoingRoute.getClusterList();
boolean sentReceivedFromRouteReflectorClient = transformedOutgoingRoute.getReceivedFromRouteReflectorClient();
AsPath sentAsPath = transformedOutgoingRoute.getAsPath();
SortedSet<Long> sentCommunities = transformedOutgoingRoute.getCommunities();
Prefix sentNetwork = remoteRoute.getNetwork();
Ip sentNextHopIp;
String sentSrcNode = remoteHostname;
String sentSrcVrf = remoteVrfName;
Ip sentSrcIp = remoteBgpNeighbor.getLocalIp();
String sentDstNode = hostname;
String sentDstVrf = _vrf.getName();
Ip sentDstIp = neighbor.getLocalIp();
int sentWeight = -1;
if (ebgpSession) {
sentNextHopIp = nextHopIp;
} else {
sentNextHopIp = transformedOutgoingRoute.getNextHopIp();
}
int sentLocalPreference = transformedOutgoingRoute.getLocalPreference();
long sentMed = transformedOutgoingRoute.getMetric();
OriginType sentOriginType = transformedOutgoingRoute.getOriginType();
RoutingProtocol sentSrcProtocol = targetProtocol;
BgpRoute.Builder transformedIncomingRouteBuilder = new BgpRoute.Builder();
// Incoming originatorIp
transformedIncomingRouteBuilder.setOriginatorIp(sentOriginatorIp);
// Incoming receivedFromIp
transformedIncomingRouteBuilder.setReceivedFromIp(sentReceivedFromIp);
// Incoming clusterList
transformedIncomingRouteBuilder.getClusterList().addAll(sentClusterList);
// Incoming receivedFromRouteReflectorClient
transformedIncomingRouteBuilder.setReceivedFromRouteReflectorClient(sentReceivedFromRouteReflectorClient);
// Incoming asPath
transformedIncomingRouteBuilder.setAsPath(sentAsPath.getAsSets());
// Incoming communities
transformedIncomingRouteBuilder.getCommunities().addAll(sentCommunities);
// Incoming protocol
transformedIncomingRouteBuilder.setProtocol(targetProtocol);
// Incoming network
transformedIncomingRouteBuilder.setNetwork(sentNetwork);
// Incoming nextHopIp
transformedIncomingRouteBuilder.setNextHopIp(sentNextHopIp);
// Incoming localPreference
transformedIncomingRouteBuilder.setLocalPreference(sentLocalPreference);
// Incoming admin
int admin = ebgpSession ? ebgpAdminCost : ibgpAdminCost;
transformedIncomingRouteBuilder.setAdmin(admin);
// Incoming metric
transformedIncomingRouteBuilder.setMetric(sentMed);
// Incoming originType
transformedIncomingRouteBuilder.setOriginType(sentOriginType);
// Incoming srcProtocol
transformedIncomingRouteBuilder.setSrcProtocol(sentSrcProtocol);
String importPolicyName = neighbor.getImportPolicy();
if (transformedOutgoingRoute.getAsPath().containsAs(neighbor.getLocalAs()) && !neighbor.getAllowLocalAsIn()) {
// disable-peer-as-check (getAllowRemoteAsOut) is set
continue;
}
BgpAdvertisement sentAdvert = new BgpAdvertisement(sentType, sentNetwork, sentNextHopIp, sentSrcNode, sentSrcVrf, sentSrcIp, sentDstNode, sentDstVrf, sentDstIp, sentSrcProtocol, sentOriginType, sentLocalPreference, sentMed, sentOriginatorIp, sentAsPath, sentCommunities, sentClusterList, sentWeight);
Prefix prefix = remoteRoute.getNetwork();
boolean isOscillatingPrefix = oscillatingPrefixes.contains(prefix);
boolean hasAdvertisementPriorityDuringRecovery = hasAdvertisementPriorityDuringRecovery(remoteRoute, dependentRoutesIterations, oscillatingPrefixes, neighbor, remoteBgpNeighbor);
if (isOscillatingPrefix && !hasAdvertisementPriorityDuringRecovery && !_prevSentBgpAdvertisements.contains(sentAdvert)) {
continue;
}
_sentBgpAdvertisements.add(sentAdvert);
/*
* CREATE INCOMING ROUTE
*/
boolean acceptIncoming = true;
if (importPolicyName != null) {
RoutingPolicy importPolicy = _c.getRoutingPolicies().get(importPolicyName);
if (importPolicy != null) {
acceptIncoming = importPolicy.process(transformedOutgoingRoute, transformedIncomingRouteBuilder, remoteBgpNeighbor.getLocalIp(), _key, Direction.IN);
}
}
if (acceptIncoming) {
BgpRoute transformedIncomingRoute = transformedIncomingRouteBuilder.build();
BgpAdvertisementType receivedType = ebgpSession ? BgpAdvertisementType.EBGP_RECEIVED : BgpAdvertisementType.IBGP_RECEIVED;
Prefix receivedNetwork = sentNetwork;
Ip receivedNextHopIp = sentNextHopIp;
String receivedSrcNode = sentSrcNode;
String receivedSrcVrf = sentSrcVrf;
Ip receivedSrcIp = sentSrcIp;
String receivedDstNode = sentDstNode;
String receivedDstVrf = sentDstVrf;
Ip receivedDstIp = sentDstIp;
RoutingProtocol receivedSrcProtocol = sentSrcProtocol;
OriginType receivedOriginType = transformedIncomingRoute.getOriginType();
int receivedLocalPreference = transformedIncomingRoute.getLocalPreference();
long receivedMed = transformedIncomingRoute.getMetric();
Ip receivedOriginatorIp = sentOriginatorIp;
AsPath receivedAsPath = transformedIncomingRoute.getAsPath();
SortedSet<Long> receivedCommunities = transformedIncomingRoute.getCommunities();
SortedSet<Long> receivedClusterList = sentClusterList;
int receivedWeight = transformedIncomingRoute.getWeight();
BgpAdvertisement receivedAdvert = new BgpAdvertisement(receivedType, receivedNetwork, receivedNextHopIp, receivedSrcNode, receivedSrcVrf, receivedSrcIp, receivedDstNode, receivedDstVrf, receivedDstIp, receivedSrcProtocol, receivedOriginType, receivedLocalPreference, receivedMed, receivedOriginatorIp, receivedAsPath, receivedCommunities, receivedClusterList, receivedWeight);
if (targetRib.mergeRoute(transformedIncomingRoute)) {
numRoutes++;
}
_receivedBgpAdvertisements.add(receivedAdvert);
}
}
}
}
return numRoutes;
}
use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class VirtualRouter method initOspfExports.
void initOspfExports() {
OspfProcess proc = _vrf.getOspfProcess();
// Nothing to do
if (proc == null) {
return;
}
// get OSPF export policy name
String exportPolicyName = _vrf.getOspfProcess().getExportPolicy();
if (exportPolicyName == null) {
// nothing to export
return;
}
RoutingPolicy exportPolicy = _c.getRoutingPolicies().get(exportPolicyName);
if (exportPolicy == null) {
// nothing to export
return;
}
// RIB.
for (AbstractRoute potentialExport : _prevMainRib.getRoutes()) {
OspfExternalRoute outputRoute = computeOspfExportRoute(potentialExport, exportPolicy, proc);
if (outputRoute == null) {
// no need to export
continue;
}
if (outputRoute.getOspfMetricType() == OspfMetricType.E1) {
_ospfExternalType1Rib.mergeRoute((OspfExternalType1Route) outputRoute);
} else {
// assuming here that MetricType exists. Or E2 is the default
_ospfExternalType2Rib.mergeRoute((OspfExternalType2Route) outputRoute);
}
}
}
use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class VirtualRouter method activateGeneratedRoutes.
boolean activateGeneratedRoutes() {
boolean changed = false;
for (GeneratedRoute gr : _vrf.getGeneratedRoutes()) {
boolean active = true;
String generationPolicyName = gr.getGenerationPolicy();
GeneratedRoute.Builder grb = new GeneratedRoute.Builder();
grb.setNetwork(gr.getNetwork());
grb.setAdmin(gr.getAdministrativeCost());
grb.setMetric(gr.getMetric() != null ? gr.getMetric() : 0);
grb.setAttributePolicy(gr.getAttributePolicy());
grb.setGenerationPolicy(gr.getGenerationPolicy());
boolean discard = gr.getDiscard();
grb.setDiscard(discard);
if (discard) {
grb.setNextHopInterface(Interface.NULL_INTERFACE_NAME);
}
if (generationPolicyName != null) {
RoutingPolicy generationPolicy = _c.getRoutingPolicies().get(generationPolicyName);
if (generationPolicy != null) {
active = false;
for (AbstractRoute contributingRoute : _prevMainRib.getRoutes()) {
boolean accept = generationPolicy.process(contributingRoute, grb, null, _key, Direction.OUT);
if (accept) {
if (!discard) {
grb.setNextHopIp(contributingRoute.getNextHopIp());
}
active = true;
break;
}
}
}
}
if (active) {
GeneratedRoute newGr = grb.build();
if (_generatedRib.mergeRoute(newGr)) {
changed = true;
}
}
}
return changed;
}
use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class CiscoConfiguration method toRoutingPolicy.
private RoutingPolicy toRoutingPolicy(Configuration c, RoutePolicy routePolicy) {
String name = routePolicy.getName();
RoutingPolicy rp = new RoutingPolicy(name, c);
List<Statement> statements = rp.getStatements();
for (RoutePolicyStatement routePolicyStatement : routePolicy.getStatements()) {
routePolicyStatement.applyTo(statements, this, c, _w);
}
If endPolicy = new If();
If nonBoolean = new If();
endPolicy.setGuard(BooleanExprs.CallExprContext.toStaticBooleanExpr());
endPolicy.setTrueStatements(Collections.singletonList(Statements.ReturnLocalDefaultAction.toStaticStatement()));
endPolicy.setFalseStatements(Collections.singletonList(nonBoolean));
nonBoolean.setGuard(BooleanExprs.CallStatementContext.toStaticBooleanExpr());
nonBoolean.setTrueStatements(Collections.singletonList(Statements.Return.toStaticStatement()));
nonBoolean.setFalseStatements(Collections.singletonList(Statements.DefaultAction.toStaticStatement()));
return rp;
}
Aggregations