package org.batfish.bdp;
import org.batfish.common.BatfishException;
import org.batfish.datamodel.BgpRoute;
import org.batfish.datamodel.RoutingProtocol;
public class BgpRib extends AbstractRib<BgpRoute> {
/**
*
*/
private static final long serialVersionUID = 1L;
public BgpRib(VirtualRouter owner) {
super(owner);
}
@Override
public int comparePreference(BgpRoute lhs, BgpRoute rhs) {
// first compare local preference
int res;
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(rhs.getProtocol()),
getAggregatePreference(lhs.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;
}
// TODO: origin type (IGP better than EGP, which is better than
// INCOMPLETE)
// 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 = Integer.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 only apply in non-multipath (or limited
// multipath) environments, which we do not yet support. So we end here.
return res;
}
private int getAggregatePreference(RoutingProtocol protocol) {
if (protocol == RoutingProtocol.AGGREGATE) {
return 0;
}
else {
return 1;
}
}
private int getTypeCost(RoutingProtocol protocol) {
switch (protocol) {
case AGGREGATE:
return 0;
case BGP: // eBGP
return 1;
case IBGP:
return 2;
// $CASES-OMITTED$
default:
throw new BatfishException(
"Invalid BGP protocol: '" + protocol.toString() + "'");
}
}
}