use of org.batfish.datamodel.RoutingProtocol 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.RoutingProtocol in project batfish by batfish.
the class ConfigurationBuilder method exitPopsf_protocol.
@Override
public void exitPopsf_protocol(Popsf_protocolContext ctx) {
RoutingProtocol protocol = toRoutingProtocol(ctx.protocol);
PsFromProtocol fromProtocol = new PsFromProtocol(protocol);
_currentPsTerm.getFroms().add(fromProtocol);
}
use of org.batfish.datamodel.RoutingProtocol in project batfish by batfish.
the class EosRoutingTableExtractor method exitRoute.
@Override
public void exitRoute(RouteContext ctx) {
if (_currentVrfName == null) {
_currentVrfName = Configuration.DEFAULT_VRF_NAME;
initVrf(_currentVrfName);
}
RoutingProtocol protocol = toProtocol(ctx.protocol());
Prefix prefix = Prefix.parse(ctx.IP_PREFIX().getText());
int admin;
int cost;
Ip nextHopIp;
for (int i = 0; i < ctx.nexthopifaces.size(); i++) {
String nextHopInterface = ctx.nexthopifaces.get(i).getText();
// TODO: support EOS route tags
int tag = Route.UNSET_ROUTE_TAG;
// TODO: support EOS next hop
if (ctx.IS_DIRECTLY_CONNECTED() != null) {
admin = 0;
cost = 0;
nextHopIp = Route.UNSET_ROUTE_NEXT_HOP_IP;
} else {
admin = toInteger(ctx.admin);
cost = toInteger(ctx.cost);
nextHopIp = new Ip(ctx.nexthops.get(i).getText());
}
RouteBuilder rb = new RouteBuilder();
rb.setNode(_hostname);
rb.setNetwork(prefix);
if (protocol == RoutingProtocol.CONNECTED || (protocol == RoutingProtocol.STATIC && nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) || Interface.NULL_INTERFACE_NAME.equals(nextHopInterface)) {
rb.setNextHop(Configuration.NODE_NONE_NAME);
}
if (!nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) {
rb.setNextHopIp(nextHopIp);
String nextHop = _ipOwners.get(nextHopIp);
if (nextHop != null) {
rb.setNextHop(nextHop);
}
}
if (nextHopInterface != null) {
rb.setNextHopInterface(nextHopInterface);
}
rb.setAdministrativeCost(admin);
rb.setCost(cost);
rb.setProtocol(protocol);
rb.setTag(tag);
rb.setVrf(_currentVrfName);
Route route = rb.build();
_currentVrfRoutes.add(route);
}
}
use of org.batfish.datamodel.RoutingProtocol in project batfish by batfish.
the class IosRoutingTableExtractor method exitRoute.
@Override
public void exitRoute(RouteContext ctx) {
if (_currentVrfName == null) {
_currentVrfName = Configuration.DEFAULT_VRF_NAME;
initVrf(_currentVrfName);
}
RoutingProtocol protocol = toProtocol(ctx.protocol());
if (protocol == RoutingProtocol.LOCAL) {
return;
}
Prefix prefix = Prefix.parse(ctx.IP_PREFIX().getText());
int admin;
int cost;
List<String> nextHopInterfaces = ctx.nexthopifaces.stream().map(nextHopIfaceCtx -> nextHopIfaceCtx.getText()).collect(Collectors.toList());
List<Ip> nextHopIps = ctx.nexthops.stream().map(nextHopIpCtx -> new Ip(nextHopIpCtx.getText())).collect(Collectors.toList());
int numIterations = Math.max(nextHopIps.size(), nextHopInterfaces.size());
for (int i = 0; i < numIterations; i++) {
String nextHopInterface;
Ip nextHopIp;
if (nextHopInterfaces.isEmpty()) {
nextHopInterface = Route.UNSET_NEXT_HOP_INTERFACE;
} else {
nextHopInterface = nextHopInterfaces.get(i);
}
if (ctx.IS_DIRECTLY_CONNECTED() != null) {
if (protocol == RoutingProtocol.STATIC) {
// static
if (ctx.admin != null) {
admin = toInteger(ctx.admin);
} else {
admin = 1;
}
if (ctx.cost != null) {
cost = toInteger(ctx.cost);
} else {
cost = 0;
}
} else {
// connected
admin = 0;
cost = 0;
}
nextHopIp = Route.UNSET_ROUTE_NEXT_HOP_IP;
} else {
admin = toInteger(ctx.admin);
cost = toInteger(ctx.cost);
nextHopIp = nextHopIps.get(i);
}
// TODO: support IOS route tags
int tag = Route.UNSET_ROUTE_TAG;
// TODO: support IOS next hop
if (protocol == RoutingProtocol.BGP && admin > RoutingProtocol.BGP.getDefaultAdministrativeCost(ConfigurationFormat.CISCO_IOS)) {
protocol = RoutingProtocol.IBGP;
}
RouteBuilder rb = new RouteBuilder();
rb.setNode(_hostname);
rb.setNetwork(prefix);
if (protocol == RoutingProtocol.CONNECTED || (protocol == RoutingProtocol.STATIC && nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) || Interface.NULL_INTERFACE_NAME.equals(nextHopInterface)) {
rb.setNextHop(Configuration.NODE_NONE_NAME);
}
if (!nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) {
rb.setNextHopIp(nextHopIp);
String nextHop = _ipOwners.get(nextHopIp);
if (nextHop != null) {
rb.setNextHop(nextHop);
}
}
if (nextHopInterface != null) {
rb.setNextHopInterface(nextHopInterface);
}
rb.setAdministrativeCost(admin);
rb.setCost(cost);
rb.setProtocol(protocol);
rb.setTag(tag);
rb.setVrf(_currentVrfName);
Route route = rb.build();
_currentVrfRoutes.add(route);
}
}
Aggregations