use of org.batfish.common.BatfishException in project batfish by batfish.
the class BgpBestPathRib method comparePreference.
@Override
public int comparePreference(BgpRoute lhs, BgpRoute rhs) {
int res;
/*
* first compare local preference
*/
res = Integer.compare(lhs.getLocalPreference(), rhs.getLocalPreference());
if (res != 0) {
return res;
}
/*
* on non-juniper, prefer aggregates (these routes won't appear on
* juniper)
*/
res = Integer.compare(getAggregatePreference(lhs.getProtocol()), getAggregatePreference(rhs.getProtocol()));
if (res != 0) {
return res;
}
/*
* then compare as path size (shorter is better, hence reversal)
*/
res = Integer.compare(rhs.getAsPath().size(), lhs.getAsPath().size());
if (res != 0) {
return res;
}
/*
* origin type (IGP better than EGP, which is better than INCOMPLETE)
*/
res = Integer.compare(lhs.getOriginType().getPreference(), rhs.getOriginType().getPreference());
if (res != 0) {
return res;
}
/*
* then compare MED
*
* TODO: handle presence/absence of always-compare-med, noting that
* normally we only do this comparison if the first AS is the same in the
* paths for both routes
*/
res = Long.compare(rhs.getMetric(), lhs.getMetric());
if (res != 0) {
return res;
}
/*
* next prefer eBGP over iBGP
*/
res = Integer.compare(getTypeCost(rhs.getProtocol()), getTypeCost(lhs.getProtocol()));
if (res != 0) {
return res;
}
/*
* The remaining criteria are used for tie-breaking to end up with a
* single best-path.
*/
/*
* Break tie with process's chosen tie-breaking mechanism
*/
BgpTieBreaker tieBreaker = _owner._vrf.getBgpProcess().getTieBreaker();
boolean bothEbgp = lhs.getProtocol() == RoutingProtocol.BGP && rhs.getProtocol() == RoutingProtocol.BGP;
switch(tieBreaker) {
case ARRIVAL_ORDER:
if (!bothEbgp) {
break;
}
boolean lhsOld = _prev.containsRoute(lhs);
boolean rhsOld = _prev.containsRoute(rhs);
if (lhsOld && !rhsOld) {
return 1;
} else if (!lhsOld && rhsOld) {
return -1;
}
break;
case ROUTER_ID:
if (!bothEbgp) {
break;
}
/**
* Prefer the route that comes from the BGP router with the lowest router ID.
*/
res = rhs.getOriginatorIp().compareTo(lhs.getOriginatorIp());
if (res != 0) {
return res;
}
break;
case CLUSTER_LIST_LENGTH:
default:
throw new BatfishException("Unhandled tie-breaker: " + tieBreaker);
}
/**
* Prefer the route that comes from the BGP router with the lowest router ID.
*/
res = rhs.getOriginatorIp().compareTo(lhs.getOriginatorIp());
if (res != 0) {
return res;
}
/**
* Prefer the path with the minimum cluster list length.
*/
res = Integer.compare(rhs.getClusterList().size(), lhs.getClusterList().size());
if (res != 0) {
return res;
}
/**
* TODO: Prefer the path that comes from the lowest neighbor address.
*/
return res;
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class VirtualRouter method initBaseBgpRibs.
public void initBaseBgpRibs(Set<BgpAdvertisement> externalAdverts, Map<Ip, Set<String>> ipOwners) {
if (_vrf.getBgpProcess() != null) {
int ebgpAdmin = RoutingProtocol.BGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
int ibgpAdmin = RoutingProtocol.IBGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
for (BgpAdvertisement advert : externalAdverts) {
if (advert.getDstNode().equals(_c.getHostname())) {
Ip dstIp = advert.getDstIp();
Set<String> dstIpOwners = ipOwners.get(dstIp);
String hostname = _c.getHostname();
if (dstIpOwners == null || !dstIpOwners.contains(hostname)) {
continue;
}
Ip srcIp = advert.getSrcIp();
// TODO: support passive bgp connections
Prefix srcPrefix = new Prefix(srcIp, Prefix.MAX_PREFIX_LENGTH);
BgpNeighbor neighbor = _vrf.getBgpProcess().getNeighbors().get(srcPrefix);
if (neighbor != null) {
BgpAdvertisementType type = advert.getType();
BgpRoute.Builder outgoingRouteBuilder = new BgpRoute.Builder();
boolean ebgp;
boolean received;
switch(type) {
case EBGP_RECEIVED:
ebgp = true;
received = true;
break;
case EBGP_SENT:
ebgp = true;
received = false;
break;
case IBGP_RECEIVED:
ebgp = false;
received = true;
break;
case IBGP_SENT:
ebgp = false;
received = false;
break;
case EBGP_ORIGINATED:
case IBGP_ORIGINATED:
default:
throw new BatfishException("Missing or invalid bgp advertisement type");
}
BgpMultipathRib targetRib = ebgp ? _baseEbgpRib : _baseIbgpRib;
RoutingProtocol targetProtocol = ebgp ? RoutingProtocol.BGP : RoutingProtocol.IBGP;
if (received) {
int admin = ebgp ? ebgpAdmin : ibgpAdmin;
AsPath asPath = advert.getAsPath();
SortedSet<Long> clusterList = advert.getClusterList();
SortedSet<Long> communities = new TreeSet<>(advert.getCommunities());
int localPreference = advert.getLocalPreference();
long metric = advert.getMed();
Prefix network = advert.getNetwork();
Ip nextHopIp = advert.getNextHopIp();
Ip originatorIp = advert.getOriginatorIp();
OriginType originType = advert.getOriginType();
RoutingProtocol srcProtocol = advert.getSrcProtocol();
int weight = advert.getWeight();
BgpRoute.Builder builder = new BgpRoute.Builder();
builder.setAdmin(admin);
builder.setAsPath(asPath.getAsSets());
builder.setClusterList(clusterList);
builder.setCommunities(communities);
builder.setLocalPreference(localPreference);
builder.setMetric(metric);
builder.setNetwork(network);
builder.setNextHopIp(nextHopIp);
builder.setOriginatorIp(originatorIp);
builder.setOriginType(originType);
builder.setProtocol(targetProtocol);
// TODO: support external route reflector clients
builder.setReceivedFromIp(advert.getSrcIp());
builder.setReceivedFromRouteReflectorClient(false);
builder.setSrcProtocol(srcProtocol);
// TODO: possibly suppport setting tag
builder.setWeight(weight);
BgpRoute route = builder.build();
targetRib.mergeRoute(route);
} else {
int localPreference;
if (ebgp) {
localPreference = BgpRoute.DEFAULT_LOCAL_PREFERENCE;
} else {
localPreference = advert.getLocalPreference();
}
outgoingRouteBuilder.setAsPath(advert.getAsPath().getAsSets());
outgoingRouteBuilder.setCommunities(new TreeSet<>(advert.getCommunities()));
outgoingRouteBuilder.setLocalPreference(localPreference);
outgoingRouteBuilder.setMetric(advert.getMed());
outgoingRouteBuilder.setNetwork(advert.getNetwork());
outgoingRouteBuilder.setNextHopIp(advert.getNextHopIp());
outgoingRouteBuilder.setOriginatorIp(advert.getOriginatorIp());
outgoingRouteBuilder.setOriginType(advert.getOriginType());
outgoingRouteBuilder.setProtocol(targetProtocol);
outgoingRouteBuilder.setReceivedFromIp(advert.getSrcIp());
// TODO:
// outgoingRouteBuilder.setReceivedFromRouteReflectorClient(...);
outgoingRouteBuilder.setSrcProtocol(advert.getSrcProtocol());
BgpRoute transformedOutgoingRoute = outgoingRouteBuilder.build();
BgpRoute.Builder transformedIncomingRouteBuilder = new BgpRoute.Builder();
// Incoming originatorIp
transformedIncomingRouteBuilder.setOriginatorIp(transformedOutgoingRoute.getOriginatorIp());
// Incoming receivedFromIp
transformedIncomingRouteBuilder.setReceivedFromIp(transformedOutgoingRoute.getReceivedFromIp());
// Incoming clusterList
transformedIncomingRouteBuilder.getClusterList().addAll(transformedOutgoingRoute.getClusterList());
// Incoming receivedFromRouteReflectorClient
transformedIncomingRouteBuilder.setReceivedFromRouteReflectorClient(transformedOutgoingRoute.getReceivedFromRouteReflectorClient());
// Incoming asPath
transformedIncomingRouteBuilder.setAsPath(transformedOutgoingRoute.getAsPath().getAsSets());
// Incoming communities
transformedIncomingRouteBuilder.getCommunities().addAll(transformedOutgoingRoute.getCommunities());
// Incoming protocol
transformedIncomingRouteBuilder.setProtocol(targetProtocol);
// Incoming network
transformedIncomingRouteBuilder.setNetwork(transformedOutgoingRoute.getNetwork());
// Incoming nextHopIp
transformedIncomingRouteBuilder.setNextHopIp(transformedOutgoingRoute.getNextHopIp());
// Incoming originType
transformedIncomingRouteBuilder.setOriginType(transformedOutgoingRoute.getOriginType());
// Incoming localPreference
transformedIncomingRouteBuilder.setLocalPreference(transformedOutgoingRoute.getLocalPreference());
// Incoming admin
int admin = ebgp ? ebgpAdmin : ibgpAdmin;
transformedIncomingRouteBuilder.setAdmin(admin);
// Incoming metric
transformedIncomingRouteBuilder.setMetric(transformedOutgoingRoute.getMetric());
// Incoming srcProtocol
transformedIncomingRouteBuilder.setSrcProtocol(targetProtocol);
String importPolicyName = neighbor.getImportPolicy();
if (ebgp && transformedOutgoingRoute.getAsPath().containsAs(neighbor.getLocalAs()) && !neighbor.getAllowLocalAsIn()) {
// disable-peer-as-check (getAllowRemoteAsOut) is set
continue;
}
/*
* CREATE INCOMING ROUTE
*/
boolean acceptIncoming = true;
if (importPolicyName != null) {
RoutingPolicy importPolicy = _c.getRoutingPolicies().get(importPolicyName);
if (importPolicy != null) {
acceptIncoming = importPolicy.process(transformedOutgoingRoute, transformedIncomingRouteBuilder, advert.getSrcIp(), _key, Direction.IN);
}
}
if (acceptIncoming) {
BgpRoute transformedIncomingRoute = transformedIncomingRouteBuilder.build();
targetRib.mergeRoute(transformedIncomingRoute);
}
}
}
}
}
}
importRib(_ebgpMultipathRib, _baseEbgpRib);
importRib(_ebgpBestPathRib, _baseEbgpRib);
importRib(_bgpBestPathRib, _baseEbgpRib);
importRib(_ibgpMultipathRib, _baseIbgpRib);
importRib(_ibgpBestPathRib, _baseIbgpRib);
importRib(_bgpBestPathRib, _baseIbgpRib);
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class VirtualRouter method computeBgpAdvertisementsToOutside.
int computeBgpAdvertisementsToOutside(Map<Ip, Set<String>> ipOwners) {
int numAdvertisements = 0;
// If we have no BGP process, nothing to do
if (_vrf.getBgpProcess() == null) {
return numAdvertisements;
}
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;
}
Prefix remotePrefix = neighbor.getPrefix();
if (remotePrefix.getPrefixLength() != Prefix.MAX_PREFIX_LENGTH) {
// Do not support dynamic outside neighbors
continue;
}
Ip remoteIp = remotePrefix.getStartIp();
if (ipOwners.get(remoteIp) != null) {
// Skip if neighbor is not outside the network
continue;
}
int localAs = neighbor.getLocalAs();
int remoteAs = neighbor.getRemoteAs();
String remoteHostname = remoteIp.toString();
String remoteVrfName = Configuration.DEFAULT_VRF_NAME;
RoutingPolicy exportPolicy = _c.getRoutingPolicies().get(neighbor.getExportPolicy());
boolean ebgpSession = localAs != remoteAs;
RoutingProtocol targetProtocol = ebgpSession ? RoutingProtocol.BGP : RoutingProtocol.IBGP;
Set<AbstractRoute> candidateRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
// Add IGP routes
Set<AbstractRoute> activeRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
activeRoutes.addAll(_mainRib.getRoutes());
for (AbstractRoute candidateRoute : activeRoutes) {
if (candidateRoute.getProtocol() != RoutingProtocol.BGP && candidateRoute.getProtocol() != RoutingProtocol.IBGP) {
candidateRoutes.add(candidateRoute);
}
}
/*
* 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 && neighbor.getAdvertiseExternal();
if (advertiseExternal) {
candidateRoutes.addAll(_ebgpBestPathRib.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 && neighbor.getAdvertiseInactive();
/* Add best bgp paths if they are active, or if advertise-inactive */
for (AbstractRoute candidateRoute : _bgpBestPathRib.getRoutes()) {
if (advertiseInactive || activeRoutes.contains(candidateRoute)) {
candidateRoutes.add(candidateRoute);
}
}
/* Add all bgp paths if additional-paths active for this session */
boolean additionalPaths = !ebgpSession && neighbor.getAdditionalPathsSend() && neighbor.getAdditionalPathsSelectAll();
if (additionalPaths) {
candidateRoutes.addAll(_bgpMultipathRib.getRoutes());
}
for (AbstractRoute route : candidateRoutes) {
BgpRoute.Builder transformedOutgoingRouteBuilder = new BgpRoute.Builder();
RoutingProtocol routeProtocol = route.getProtocol();
boolean routeIsBgp = routeProtocol == RoutingProtocol.IBGP || routeProtocol == RoutingProtocol.BGP;
// originatorIP
Ip originatorIp;
if (!ebgpSession && routeProtocol.equals(RoutingProtocol.IBGP)) {
BgpRoute bgpRoute = (BgpRoute) route;
originatorIp = bgpRoute.getOriginatorIp();
} else {
originatorIp = _vrf.getBgpProcess().getRouterId();
}
transformedOutgoingRouteBuilder.setOriginatorIp(originatorIp);
transformedOutgoingRouteBuilder.setReceivedFromIp(neighbor.getLocalIp());
// for bgp remote route)
if (routeIsBgp) {
BgpRoute bgpRoute = (BgpRoute) route;
transformedOutgoingRouteBuilder.setOriginType(bgpRoute.getOriginType());
if (ebgpSession && bgpRoute.getAsPath().containsAs(neighbor.getRemoteAs()) && !neighbor.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 routeOriginatorIp = bgpRoute.getOriginatorIp();
/*
* iBGP speaker should not send out routes to iBGP neighbor whose router-id is
* same as originator id of advertisement
*/
if (!ebgpSession && routeOriginatorIp != null && remoteIp.equals(routeOriginatorIp)) {
continue;
}
if (routeProtocol.equals(RoutingProtocol.IBGP) && !ebgpSession) {
boolean routeReceivedFromRouteReflectorClient = bgpRoute.getReceivedFromRouteReflectorClient();
boolean sendingToRouteReflectorClient = neighbor.getRouteReflectorClient();
transformedOutgoingRouteBuilder.getClusterList().addAll(bgpRoute.getClusterList());
if (!routeReceivedFromRouteReflectorClient && !sendingToRouteReflectorClient) {
continue;
}
if (sendingToRouteReflectorClient) {
// sender adds its local cluster id to clusterlist of
// new route
transformedOutgoingRouteBuilder.getClusterList().add(neighbor.getClusterId());
}
}
}
// Outgoing communities
if (routeIsBgp) {
BgpRoute bgpRoute = (BgpRoute) route;
transformedOutgoingRouteBuilder.setAsPath(bgpRoute.getAsPath().getAsSets());
if (neighbor.getSendCommunity()) {
transformedOutgoingRouteBuilder.getCommunities().addAll(bgpRoute.getCommunities());
}
}
if (ebgpSession) {
SortedSet<Integer> newAsPathElement = new TreeSet<>();
newAsPathElement.add(localAs);
transformedOutgoingRouteBuilder.getAsPath().add(0, newAsPathElement);
}
// Outgoing protocol
transformedOutgoingRouteBuilder.setProtocol(targetProtocol);
transformedOutgoingRouteBuilder.setNetwork(route.getNetwork());
// Outgoing metric
if (routeIsBgp) {
transformedOutgoingRouteBuilder.setMetric(route.getMetric());
}
// Outgoing nextHopIp
// Outgoing localPreference
Ip nextHopIp;
int localPreference;
if (ebgpSession || !routeIsBgp) {
nextHopIp = neighbor.getLocalIp();
localPreference = BgpRoute.DEFAULT_LOCAL_PREFERENCE;
} else {
nextHopIp = route.getNextHopIp();
BgpRoute ibgpRoute = (BgpRoute) route;
localPreference = ibgpRoute.getLocalPreference();
}
if (nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) {
// should only happen for ibgp
String nextHopInterface = route.getNextHopInterface();
InterfaceAddress nextHopAddress = _c.getInterfaces().get(nextHopInterface).getAddress();
if (nextHopAddress == null) {
throw new BatfishException("route's nextHopInterface has no address");
}
nextHopIp = nextHopAddress.getIp();
}
transformedOutgoingRouteBuilder.setNextHopIp(nextHopIp);
transformedOutgoingRouteBuilder.setLocalPreference(localPreference);
// Outgoing srcProtocol
transformedOutgoingRouteBuilder.setSrcProtocol(route.getProtocol());
/*
* CREATE OUTGOING ROUTE
*/
boolean acceptOutgoing = exportPolicy.process(route, transformedOutgoingRouteBuilder, remoteIp, remoteVrfName, Direction.OUT);
if (acceptOutgoing) {
BgpRoute transformedOutgoingRoute = transformedOutgoingRouteBuilder.build();
// Record sent advertisement
BgpAdvertisementType sentType = ebgpSession ? BgpAdvertisementType.EBGP_SENT : BgpAdvertisementType.IBGP_SENT;
Ip sentOriginatorIp = transformedOutgoingRoute.getOriginatorIp();
SortedSet<Long> sentClusterList = transformedOutgoingRoute.getClusterList();
AsPath sentAsPath = transformedOutgoingRoute.getAsPath();
SortedSet<Long> sentCommunities = transformedOutgoingRoute.getCommunities();
Prefix sentNetwork = route.getNetwork();
Ip sentNextHopIp;
String sentSrcNode = hostname;
String sentSrcVrf = _vrf.getName();
Ip sentSrcIp = neighbor.getLocalIp();
String sentDstNode = remoteHostname;
String sentDstVrf = remoteVrfName;
Ip sentDstIp = remoteIp;
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;
BgpAdvertisement sentAdvert = new BgpAdvertisement(sentType, sentNetwork, sentNextHopIp, sentSrcNode, sentSrcVrf, sentSrcIp, sentDstNode, sentDstVrf, sentDstIp, sentSrcProtocol, sentOriginType, sentLocalPreference, sentMed, sentOriginatorIp, sentAsPath, sentCommunities, sentClusterList, sentWeight);
_sentBgpAdvertisements.add(sentAdvert);
numAdvertisements++;
}
}
}
return numAdvertisements;
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class JsonExternalBgpAdvertisementPlugin method loadExternalBgpAdvertisements.
@Override
public Set<BgpAdvertisement> loadExternalBgpAdvertisements() {
Set<BgpAdvertisement> advertSet = new LinkedHashSet<>();
String externalBgpAnnouncementsFileContents = _batfish.readExternalBgpAnnouncementsFile();
if (externalBgpAnnouncementsFileContents != null) {
try {
JSONObject jsonObj = new JSONObject(externalBgpAnnouncementsFileContents);
JSONArray announcements = jsonObj.getJSONArray(BfConsts.PROP_BGP_ANNOUNCEMENTS);
for (int index = 0; index < announcements.length(); index++) {
JSONObject announcement = new JSONObject();
JSONObject announcementSrc = announcements.getJSONObject(index);
for (Iterator<?> i = announcementSrc.keys(); i.hasNext(); ) {
String key = (String) i.next();
announcement.put(key, announcementSrc.get(key));
}
BgpAdvertisement bgpAdvertisement = BatfishObjectMapper.mapper().readValue(announcement.toString(), BgpAdvertisement.class);
advertSet.add(bgpAdvertisement);
}
} catch (JSONException | IOException e) {
throw new BatfishException("Error processing external BGP advertisements file", e);
}
}
return advertSet;
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class ConvertConfigurationAnswerElementTest method testSetErrors.
@Test
public void testSetErrors() {
BatfishException exception = new BatfishException("sample exception");
BatfishStackTrace stackTrace = new BatfishStackTrace(exception);
SortedMap<String, BatfishStackTrace> errors = new TreeMap<>();
errors.put("error", stackTrace);
_element.setErrors(errors);
assertThat(_element.getErrors().get("error"), is(stackTrace));
}
Aggregations