use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class EncoderSlice method addExportConstraint.
/*
* Creates the transfer function to represent export filters
* between two symbolic records. The import filter depends
* heavily on the protocol.
*/
private void addExportConstraint(LogicalEdge e, SymbolicRoute varsOther, @Nullable SymbolicRoute ospfRedistribVars, @Nullable SymbolicRoute overallBest, Configuration conf, Protocol proto, GraphEdge ge, String router, boolean usedExport, Set<Prefix> originations) {
SymbolicRoute vars = e.getSymbolicRecord();
Interface iface = ge.getStart();
ArithExpr failed = getSymbolicFailures().getFailedVariable(e.getEdge());
assert (failed != null);
BoolExpr notFailed = mkEq(failed, mkInt(0));
// only add constraints once when using a single copy of export variables
if (!_optimizations.getSliceCanKeepSingleExportVar().get(router).get(proto) || !usedExport) {
if (proto.isConnected()) {
BoolExpr val = mkNot(vars.getPermitted());
add(val);
}
if (proto.isStatic()) {
BoolExpr val = mkNot(vars.getPermitted());
add(val);
}
if (proto.isOspf() || proto.isBgp()) {
// BGP cost based on export
Integer cost = proto.isBgp() ? addedCost(proto, ge) : 0;
BoolExpr val = mkNot(vars.getPermitted());
BoolExpr active = interfaceActive(iface, proto);
// Apply BGP export policy and cost based on peer type
// (1) EBGP --> ALL
// (2) CLIENT --> ALL
// (3) NONCLIENT --> EBGP, CLIENT
boolean isNonClientEdge = proto.isBgp() && getGraph().peerType(ge) != Graph.BgpSendType.TO_EBGP;
boolean isClientEdge = proto.isBgp() && getGraph().peerType(ge) == Graph.BgpSendType.TO_CLIENT;
boolean isInternalExport = varsOther.isBest() && _optimizations.getNeedBgpInternal().contains(router);
BoolExpr doExport = mkTrue();
if (isInternalExport && proto.isBgp() && isNonClientEdge) {
if (isClientEdge) {
cost = 0;
} else {
// Lookup if we learned from iBGP, and if so, don't export the route
SymbolicRoute other = getBestNeighborPerProtocol(router, proto);
assert other != null;
assert other.getBgpInternal() != null;
if (other.getBgpInternal() != null) {
doExport = mkNot(other.getBgpInternal());
cost = 0;
}
}
}
BoolExpr acc;
RoutingPolicy pol = getGraph().findExportRoutingPolicy(router, proto, e.getEdge());
if (Encoder.ENABLE_DEBUGGING && pol != null) {
System.out.println("Export policy (" + _sliceName + "," + ge + "): " + pol.getName());
}
// We have to wrap this with the right thing for some reason
List<Statement> statements;
Statements.StaticStatement s1 = new Statements.StaticStatement(Statements.ExitAccept);
Statements.StaticStatement s2 = new Statements.StaticStatement(Statements.ExitReject);
if (proto.isOspf()) {
If i = new If();
List<Statement> stmts = (pol == null ? Collections.singletonList(s2) : pol.getStatements());
i.setTrueStatements(Collections.singletonList(s1));
i.setFalseStatements(stmts);
BooleanExpr expr = new MatchProtocol(RoutingProtocol.OSPF);
i.setGuard(expr);
statements = Collections.singletonList(i);
} else {
statements = (pol == null ? Collections.singletonList(s1) : pol.getStatements());
}
TransferSSA f = new TransferSSA(this, conf, varsOther, vars, proto, statements, cost, ge, true);
acc = f.compute();
BoolExpr usable = mkAnd(active, doExport, varsOther.getPermitted(), notFailed);
// will maintain the same preference when adding to the cost.
if (ospfRedistribVars != null) {
assert overallBest != null;
f = new TransferSSA(this, conf, overallBest, ospfRedistribVars, proto, statements, cost, ge, true);
BoolExpr acc2 = f.compute();
// System.out.println("ADDING: \n" + acc2.simplify());
add(acc2);
BoolExpr usable2 = mkAnd(active, doExport, ospfRedistribVars.getPermitted(), notFailed);
BoolExpr geq = greaterOrEqual(conf, proto, ospfRedistribVars, varsOther, e);
BoolExpr isBetter = mkNot(mkAnd(ospfRedistribVars.getPermitted(), geq));
BoolExpr usesOspf = mkAnd(varsOther.getPermitted(), isBetter);
BoolExpr eq = equal(conf, proto, ospfRedistribVars, vars, e, false);
BoolExpr eqPer = mkEq(ospfRedistribVars.getPermitted(), vars.getPermitted());
acc = mkIf(usesOspf, mkIf(usable, acc, val), mkIf(usable2, mkAnd(eq, eqPer), val));
} else {
acc = mkIf(usable, acc, val);
}
for (Prefix p : originations) {
// For OSPF, we need to explicitly initiate a route
if (proto.isOspf()) {
BoolExpr ifaceUp = interfaceActive(iface, proto);
BoolExpr relevantPrefix = isRelevantFor(p, _symbolicPacket.getDstIp());
BoolExpr relevant = mkAnd(ifaceUp, relevantPrefix);
int adminDistance = defaultAdminDistance(conf, proto);
int prefixLength = p.getPrefixLength();
BoolExpr per = vars.getPermitted();
BoolExpr lp = safeEq(vars.getLocalPref(), mkInt(0));
BoolExpr ad = safeEq(vars.getAdminDist(), mkInt(adminDistance));
BoolExpr met = safeEq(vars.getMetric(), mkInt(cost));
BoolExpr med = safeEq(vars.getMed(), mkInt(100));
BoolExpr len = safeEq(vars.getPrefixLength(), mkInt(prefixLength));
BoolExpr type = safeEqEnum(vars.getOspfType(), OspfType.O);
BoolExpr area = safeEqEnum(vars.getOspfArea(), iface.getOspfAreaName());
BoolExpr internal = safeEq(vars.getBgpInternal(), mkFalse());
BoolExpr igpMet = safeEq(vars.getIgpMetric(), mkInt(0));
BoolExpr comms = mkTrue();
for (Map.Entry<CommunityVar, BoolExpr> entry : vars.getCommunities().entrySet()) {
comms = mkAnd(comms, mkNot(entry.getValue()));
}
BoolExpr values = mkAnd(per, lp, ad, met, med, len, type, area, internal, igpMet, comms);
// Don't originate OSPF route when there is a better redistributed route
if (ospfRedistribVars != null) {
BoolExpr betterLen = mkGt(ospfRedistribVars.getPrefixLength(), mkInt(prefixLength));
BoolExpr equalLen = mkEq(ospfRedistribVars.getPrefixLength(), mkInt(prefixLength));
BoolExpr betterAd = mkLt(ospfRedistribVars.getAdminDist(), mkInt(110));
BoolExpr better = mkOr(betterLen, mkAnd(equalLen, betterAd));
BoolExpr betterRedistributed = mkAnd(ospfRedistribVars.getPermitted(), better);
relevant = mkAnd(relevant, mkNot(betterRedistributed));
}
acc = mkIf(relevant, values, acc);
}
}
add(acc);
if (Encoder.ENABLE_DEBUGGING) {
System.out.println("EXPORT: " + router + " " + varsOther.getName() + " " + ge);
System.out.println(acc.simplify());
System.out.println("\n\n");
}
}
}
}
use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class EncoderSlice method addImportConstraint.
/*
* Creates the transfer function to represent import filters
* between two symbolic records. The import filter depends
* heavily on the protocol.
*/
private void addImportConstraint(LogicalEdge e, SymbolicRoute varsOther, Configuration conf, Protocol proto, GraphEdge ge, String router) {
SymbolicRoute vars = e.getSymbolicRecord();
Interface iface = ge.getStart();
ArithExpr failed = getSymbolicFailures().getFailedVariable(e.getEdge());
assert (failed != null);
BoolExpr notFailed = mkEq(failed, mkInt(0));
if (vars.getIsUsed()) {
if (proto.isConnected()) {
Prefix p = iface.getAddress().getPrefix();
BoolExpr relevant = mkAnd(interfaceActive(iface, proto), isRelevantFor(p, _symbolicPacket.getDstIp()), notFailed);
BoolExpr per = vars.getPermitted();
BoolExpr len = safeEq(vars.getPrefixLength(), mkInt(p.getPrefixLength()));
BoolExpr ad = safeEq(vars.getAdminDist(), mkInt(1));
BoolExpr lp = safeEq(vars.getLocalPref(), mkInt(0));
BoolExpr met = safeEq(vars.getMetric(), mkInt(0));
BoolExpr values = mkAnd(per, len, ad, lp, met);
add(mkIf(relevant, values, mkNot(vars.getPermitted())));
}
if (proto.isStatic()) {
List<StaticRoute> srs = getGraph().getStaticRoutes().get(router, iface.getName());
assert (srs != null);
BoolExpr acc = mkNot(vars.getPermitted());
for (StaticRoute sr : srs) {
Prefix p = sr.getNetwork();
BoolExpr relevant = mkAnd(interfaceActive(iface, proto), isRelevantFor(p, _symbolicPacket.getDstIp()), notFailed);
BoolExpr per = vars.getPermitted();
BoolExpr len = safeEq(vars.getPrefixLength(), mkInt(p.getPrefixLength()));
BoolExpr ad = safeEq(vars.getAdminDist(), mkInt(sr.getAdministrativeCost()));
BoolExpr lp = safeEq(vars.getLocalPref(), mkInt(0));
BoolExpr met = safeEq(vars.getMetric(), mkInt(0));
BoolExpr values = mkAnd(per, len, ad, lp, met);
acc = mkIf(relevant, values, acc);
}
add(acc);
}
if (proto.isOspf() || proto.isBgp()) {
BoolExpr val = mkNot(vars.getPermitted());
if (varsOther != null) {
// BoolExpr isRoot = relevantOrigination(originations);
BoolExpr active = interfaceActive(iface, proto);
// Handle iBGP by checking reachability to the next hop to send messages
boolean isNonClient = (proto.isBgp()) && (getGraph().peerType(ge) != Graph.BgpSendType.TO_EBGP);
boolean isClient = (proto.isBgp()) && (getGraph().peerType(ge) == Graph.BgpSendType.TO_RR);
BoolExpr receiveMessage;
String currentRouter = ge.getRouter();
String peerRouter = ge.getPeer();
if (_encoder.getModelIgp() && isNonClient) {
// Lookup reachabilty based on peer next-hop
receiveMessage = _encoder.getSliceReachability().get(currentRouter).get(peerRouter);
/* EncoderSlice peerSlice = _encoder.getSlice(peerRouter);
BoolExpr srcPort = mkEq(peerSlice.getSymbolicPacket().getSrcPort(), mkInt(179));
BoolExpr srcIp = mkEq(peerSlice.getSymbolicPacket().getSrcIp(), mkInt(0));
BoolExpr tcpAck = mkEq(peerSlice.getSymbolicPacket().getTcpAck(), mkFalse());
BoolExpr tcpCwr = mkEq(peerSlice.getSymbolicPacket().getTcpCwr(), mkFalse());
BoolExpr tcpEce = mkEq(peerSlice.getSymbolicPacket().getTcpEce(), mkFalse());
BoolExpr tcpFin = mkEq(peerSlice.getSymbolicPacket().getTcpFin(), mkFalse());
BoolExpr tcpPsh = mkEq(peerSlice.getSymbolicPacket().getTcpPsh(), mkFalse());
BoolExpr tcpRst = mkEq(peerSlice.getSymbolicPacket().getTcpRst(), mkFalse());
BoolExpr tcpSyn = mkEq(peerSlice.getSymbolicPacket().getTcpSyn(), mkFalse());
BoolExpr tcpUrg = mkEq(peerSlice.getSymbolicPacket().getTcpUrg(), mkFalse());
BoolExpr icmpCode = mkEq(peerSlice.getSymbolicPacket().getIcmpCode(), mkInt(0));
BoolExpr icmpType = mkEq(peerSlice.getSymbolicPacket().getIcmpType(), mkInt(0));
BoolExpr all =
mkAnd(srcPort, srcIp, tcpAck,
tcpCwr, tcpEce, tcpFin, tcpPsh, tcpRst, tcpSyn, tcpUrg, icmpCode, icmpType);
receiveMessage = mkImplies(all, receiveMessage); */
} else if (_encoder.getModelIgp() && isClient) {
// Lookup reachability based on client id tag to find next hop
BoolExpr acc = mkTrue();
for (Map.Entry<String, Integer> entry : getGraph().getOriginatorId().entrySet()) {
String r = entry.getKey();
Integer id = entry.getValue();
if (!r.equals(currentRouter)) {
BoolExpr reach = _encoder.getSliceReachability().get(currentRouter).get(r);
/* EncoderSlice peerSlice = _encoder.getSlice(r);
BoolExpr srcPort = mkEq(peerSlice.getSymbolicPacket().getSrcPort(), mkInt(179));
BoolExpr srcIp = mkEq(peerSlice.getSymbolicPacket().getSrcIp(), mkInt(0));
BoolExpr tcpAck = mkEq(peerSlice.getSymbolicPacket().getTcpAck(), mkFalse());
BoolExpr tcpCwr = mkEq(peerSlice.getSymbolicPacket().getTcpCwr(), mkFalse());
BoolExpr tcpEce = mkEq(peerSlice.getSymbolicPacket().getTcpEce(), mkFalse());
BoolExpr tcpFin = mkEq(peerSlice.getSymbolicPacket().getTcpFin(), mkFalse());
BoolExpr tcpPsh = mkEq(peerSlice.getSymbolicPacket().getTcpPsh(), mkFalse());
BoolExpr tcpRst = mkEq(peerSlice.getSymbolicPacket().getTcpRst(), mkFalse());
BoolExpr tcpSyn = mkEq(peerSlice.getSymbolicPacket().getTcpSyn(), mkFalse());
BoolExpr tcpUrg = mkEq(peerSlice.getSymbolicPacket().getTcpUrg(), mkFalse());
BoolExpr icmpCode = mkEq(peerSlice.getSymbolicPacket().getIcmpCode(), mkInt(0));
BoolExpr icmpType = mkEq(peerSlice.getSymbolicPacket().getIcmpType(), mkInt(0));
BoolExpr all =
mkAnd(srcPort, srcIp, tcpAck,
tcpCwr, tcpEce, tcpFin, tcpPsh, tcpRst, tcpSyn, tcpUrg, icmpCode, icmpType);
reach = mkImplies(all, reach); */
acc = mkAnd(acc, mkImplies(varsOther.getClientId().checkIfValue(id), reach));
}
}
receiveMessage = acc;
// Just check if the link is failed
} else {
receiveMessage = notFailed;
}
// Take into account BGP loop prevention
// The path length will prevent any isolated loops
BoolExpr loop = mkFalse();
if (proto.isBgp() && ge.getPeer() != null) {
String peer = ge.getPeer();
GraphEdge gePeer = getGraph().getOtherEnd().get(ge);
loop = getSymbolicDecisions().getControlForwarding().get(peer, gePeer);
}
assert (loop != null);
BoolExpr usable = mkAnd(mkNot(loop), active, varsOther.getPermitted(), receiveMessage);
BoolExpr importFunction;
RoutingPolicy pol = getGraph().findImportRoutingPolicy(router, proto, e.getEdge());
if (Encoder.ENABLE_DEBUGGING && pol != null) {
System.out.println("Import Policy: " + pol.getName());
}
List<Statement> statements;
if (pol == null) {
Statements.StaticStatement s = new Statements.StaticStatement(Statements.ExitAccept);
statements = Collections.singletonList(s);
} else {
statements = pol.getStatements();
}
// OSPF cost calculated based on incoming interface
Integer cost = proto.isOspf() ? addedCost(proto, ge) : 0;
TransferSSA f = new TransferSSA(this, conf, varsOther, vars, proto, statements, cost, ge, false);
importFunction = f.compute();
BoolExpr acc = mkIf(usable, importFunction, val);
if (Encoder.ENABLE_DEBUGGING) {
System.out.println("IMPORT FUNCTION: " + router + " " + varsOther.getName());
System.out.println(importFunction.simplify());
System.out.println("\n\n");
}
add(acc);
} else {
add(val);
}
}
}
}
use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class TransferBDD method compute.
/*
* Convert a Batfish AST boolean expression to a symbolic Z3 boolean expression
* by performing inlining of stateful side effects.
*/
private TransferResult<TransferReturn, BDD> compute(BooleanExpr expr, TransferParam<BDDRoute> p) {
// TODO: right now everything is IPV4
if (expr instanceof MatchIpv4) {
p.debug("MatchIpv4");
TransferReturn ret = new TransferReturn(p.getData(), factory.one());
p.debug("MatchIpv4 Result: " + ret);
return fromExpr(ret);
}
if (expr instanceof MatchIpv6) {
p.debug("MatchIpv6");
TransferReturn ret = new TransferReturn(p.getData(), factory.zero());
return fromExpr(ret);
}
if (expr instanceof Conjunction) {
p.debug("Conjunction");
Conjunction c = (Conjunction) expr;
BDD acc = factory.one();
TransferResult<TransferReturn, BDD> result = new TransferResult<>();
for (BooleanExpr be : c.getConjuncts()) {
TransferResult<TransferReturn, BDD> r = compute(be, p.indent());
acc = acc.and(r.getReturnValue().getSecond());
}
TransferReturn ret = new TransferReturn(p.getData(), acc);
p.debug("Conjunction return: " + acc);
return result.setReturnValue(ret);
}
if (expr instanceof Disjunction) {
p.debug("Disjunction");
Disjunction d = (Disjunction) expr;
BDD acc = factory.zero();
TransferResult<TransferReturn, BDD> result = new TransferResult<>();
for (BooleanExpr be : d.getDisjuncts()) {
TransferResult<TransferReturn, BDD> r = compute(be, p.indent());
result = result.addChangedVariables(r);
acc = acc.or(r.getReturnValue().getSecond());
}
TransferReturn ret = new TransferReturn(p.getData(), acc);
p.debug("Disjunction return: " + acc);
return result.setReturnValue(ret);
}
// TODO: thread the BDDRecord through calls
if (expr instanceof ConjunctionChain) {
p.debug("ConjunctionChain");
ConjunctionChain d = (ConjunctionChain) expr;
List<BooleanExpr> conjuncts = new ArrayList<>(d.getSubroutines());
if (p.getDefaultPolicy() != null) {
BooleanExpr be = new CallExpr(p.getDefaultPolicy().getDefaultPolicy());
conjuncts.add(be);
}
if (conjuncts.size() == 0) {
TransferReturn ret = new TransferReturn(p.getData(), factory.one());
return fromExpr(ret);
} else {
TransferResult<TransferReturn, BDD> result = new TransferResult<>();
TransferParam<BDDRoute> record = p;
BDD acc = factory.zero();
for (int i = conjuncts.size() - 1; i >= 0; i--) {
BooleanExpr conjunct = conjuncts.get(i);
TransferParam<BDDRoute> param = record.setDefaultPolicy(null).setChainContext(TransferParam.ChainContext.CONJUNCTION).indent();
TransferResult<TransferReturn, BDD> r = compute(conjunct, param);
record = record.setData(r.getReturnValue().getFirst());
acc = ite(r.getFallthroughValue(), acc, r.getReturnValue().getSecond());
}
TransferReturn ret = new TransferReturn(record.getData(), acc);
return result.setReturnValue(ret);
}
}
if (expr instanceof DisjunctionChain) {
p.debug("DisjunctionChain");
DisjunctionChain d = (DisjunctionChain) expr;
List<BooleanExpr> disjuncts = new ArrayList<>(d.getSubroutines());
if (p.getDefaultPolicy() != null) {
BooleanExpr be = new CallExpr(p.getDefaultPolicy().getDefaultPolicy());
disjuncts.add(be);
}
if (disjuncts.size() == 0) {
TransferReturn ret = new TransferReturn(p.getData(), factory.zero());
return fromExpr(ret);
} else {
TransferResult<TransferReturn, BDD> result = new TransferResult<>();
TransferParam<BDDRoute> record = p;
BDD acc = factory.zero();
for (int i = disjuncts.size() - 1; i >= 0; i--) {
BooleanExpr disjunct = disjuncts.get(i);
TransferParam<BDDRoute> param = record.setDefaultPolicy(null).setChainContext(TransferParam.ChainContext.CONJUNCTION).indent();
TransferResult<TransferReturn, BDD> r = compute(disjunct, param);
record = record.setData(r.getReturnValue().getFirst());
acc = ite(r.getFallthroughValue(), acc, r.getReturnValue().getSecond());
}
TransferReturn ret = new TransferReturn(record.getData(), acc);
return result.setReturnValue(ret);
}
}
if (expr instanceof Not) {
p.debug("mkNot");
Not n = (Not) expr;
TransferResult<TransferReturn, BDD> result = compute(n.getExpr(), p);
TransferReturn r = result.getReturnValue();
TransferReturn ret = new TransferReturn(r.getFirst(), r.getSecond().not());
return result.setReturnValue(ret);
}
if (expr instanceof MatchProtocol) {
MatchProtocol mp = (MatchProtocol) expr;
Protocol proto = Protocol.fromRoutingProtocol(mp.getProtocol());
if (proto == null) {
p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): false");
TransferReturn ret = new TransferReturn(p.getData(), factory.zero());
return fromExpr(ret);
}
BDD protoMatch = p.getData().getProtocolHistory().value(proto);
p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): " + protoMatch);
TransferReturn ret = new TransferReturn(p.getData(), protoMatch);
return fromExpr(ret);
}
if (expr instanceof MatchPrefixSet) {
p.debug("MatchPrefixSet");
MatchPrefixSet m = (MatchPrefixSet) expr;
BDD r = matchPrefixSet(p.indent(), _conf, m.getPrefixSet(), p.getData());
TransferReturn ret = new TransferReturn(p.getData(), r);
return fromExpr(ret);
// TODO: implement me
} else if (expr instanceof MatchPrefix6Set) {
p.debug("MatchPrefix6Set");
TransferReturn ret = new TransferReturn(p.getData(), factory.zero());
return fromExpr(ret);
} else if (expr instanceof CallExpr) {
p.debug("CallExpr");
CallExpr c = (CallExpr) expr;
String router = _conf.getName();
String name = c.getCalledPolicyName();
TransferResult<TransferReturn, BDD> r = CACHE.get(router, name);
if (r != null) {
return r;
}
RoutingPolicy pol = _conf.getRoutingPolicies().get(name);
p = p.setCallContext(TransferParam.CallContext.EXPR_CALL);
r = compute(pol.getStatements(), p.indent().enterScope(name));
CACHE.put(router, name, r);
return r;
} else if (expr instanceof WithEnvironmentExpr) {
p.debug("WithEnvironmentExpr");
// TODO: this is not correct
WithEnvironmentExpr we = (WithEnvironmentExpr) expr;
// TODO: postStatements() and preStatements()
return compute(we.getExpr(), p.deepCopy());
} else if (expr instanceof MatchCommunitySet) {
p.debug("MatchCommunitySet");
MatchCommunitySet mcs = (MatchCommunitySet) expr;
BDD c = matchCommunitySet(p.indent(), _conf, mcs.getExpr(), p.getData());
TransferReturn ret = new TransferReturn(p.getData(), c);
return fromExpr(ret);
} else if (expr instanceof BooleanExprs.StaticBooleanExpr) {
BooleanExprs.StaticBooleanExpr b = (BooleanExprs.StaticBooleanExpr) expr;
TransferReturn ret;
switch(b.getType()) {
case CallExprContext:
p.debug("CallExprContext");
BDD x1 = mkBDD(p.getCallContext() == TransferParam.CallContext.EXPR_CALL);
ret = new TransferReturn(p.getData(), x1);
return fromExpr(ret);
case CallStatementContext:
p.debug("CallStmtContext");
BDD x2 = mkBDD(p.getCallContext() == TransferParam.CallContext.STMT_CALL);
ret = new TransferReturn(p.getData(), x2);
return fromExpr(ret);
case True:
p.debug("True");
ret = new TransferReturn(p.getData(), factory.one());
return fromExpr(ret);
case False:
p.debug("False");
ret = new TransferReturn(p.getData(), factory.zero());
return fromExpr(ret);
default:
throw new BatfishException("Unhandled " + BooleanExprs.class.getCanonicalName() + ": " + b.getType());
}
} else if (expr instanceof MatchAsPath) {
p.debug("MatchAsPath");
// System.out.println("Warning: use of unimplemented feature MatchAsPath");
TransferReturn ret = new TransferReturn(p.getData(), factory.one());
return fromExpr(ret);
}
throw new BatfishException("TODO: compute expr transfer function: " + expr);
}
use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class RouteReflectionTest method generateRoutesTwoReflectors.
private SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>> generateRoutesTwoReflectors(boolean useSameClusterIds) {
Ip as1PeeringIp = new Ip("10.12.11.1");
Ip edge1EbgpIfaceIp = new Ip("10.12.11.2");
Ip edge1IbgpIfaceIp = new Ip("10.1.12.1");
Ip edge1LoopbackIp = new Ip("2.0.0.1");
Ip rr1Edge1IfaceIp = new Ip("10.1.12.2");
Ip rr1Rr2IfaceIp = new Ip("10.1.23.2");
Ip rr1LoopbackIp = new Ip("2.0.0.2");
Ip rr2IbgpIfaceIp = new Ip("10.1.23.3");
Ip rr2LoopbackIp = new Ip("2.0.0.3");
StaticRoute.Builder sb = StaticRoute.builder();
Configuration edge1 = _cb.setHostname(EDGE1_NAME).build();
Vrf vEdge1 = _vb.setOwner(edge1).build();
_ib.setOwner(edge1).setVrf(vEdge1);
_ib.setAddress(new InterfaceAddress(edge1EbgpIfaceIp, EDGE_PREFIX_LENGTH)).build();
_ib.setAddress(new InterfaceAddress(edge1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build();
_ib.setAddress(new InterfaceAddress(edge1IbgpIfaceIp, EDGE_PREFIX_LENGTH)).build();
vEdge1.setStaticRoutes(ImmutableSortedSet.of(sb.setNextHopIp(rr1Edge1IfaceIp).setNetwork(new Prefix(rr1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build()));
BgpProcess edge1Proc = _pb.setRouterId(edge1LoopbackIp).setVrf(vEdge1).build();
RoutingPolicy edge1EbgpExportPolicy = _nullExportPolicyBuilder.setOwner(edge1).build();
_nb.setOwner(edge1).setVrf(vEdge1).setBgpProcess(edge1Proc).setClusterId(edge1LoopbackIp.asLong()).setRemoteAs(1).setLocalIp(edge1EbgpIfaceIp).setPeerAddress(as1PeeringIp).setExportPolicy(edge1EbgpExportPolicy.getName()).build();
RoutingPolicy edge1IbgpExportPolicy = _defaultExportPolicyBuilder.setOwner(edge1).build();
_nb.setRemoteAs(2).setLocalIp(edge1LoopbackIp).setPeerAddress(rr1LoopbackIp).setExportPolicy(edge1IbgpExportPolicy.getName()).build();
Configuration rr1 = _cb.setHostname(RR1_NAME).build();
Vrf vRr1 = _vb.setOwner(rr1).build();
_ib.setOwner(rr1).setVrf(vRr1);
_ib.setAddress(new InterfaceAddress(rr1Edge1IfaceIp, EDGE_PREFIX_LENGTH)).build();
_ib.setAddress(new InterfaceAddress(rr1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build();
_ib.setAddress(new InterfaceAddress(rr1Rr2IfaceIp, EDGE_PREFIX_LENGTH)).build();
vRr1.setStaticRoutes(ImmutableSortedSet.of(sb.setNextHopIp(edge1IbgpIfaceIp).setNetwork(new Prefix(edge1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build(), sb.setNextHopIp(rr2IbgpIfaceIp).setNetwork(new Prefix(rr2LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build()));
BgpProcess rr1Proc = _pb.setRouterId(rr1LoopbackIp).setVrf(vRr1).build();
RoutingPolicy rr1ExportPolicy = _defaultExportPolicyBuilder.setOwner(rr1).build();
_nb.setOwner(rr1).setVrf(vRr1).setBgpProcess(rr1Proc).setClusterId(rr1LoopbackIp.asLong()).setRemoteAs(2).setLocalIp(rr1LoopbackIp).setExportPolicy(rr1ExportPolicy.getName()).setRouteReflectorClient(true).setPeerAddress(edge1LoopbackIp).build();
_nb.setRouteReflectorClient(false).setPeerAddress(rr2LoopbackIp).build();
Configuration rr2 = _cb.setHostname(RR2_NAME).build();
Vrf vRr2 = _vb.setOwner(rr2).build();
_ib.setOwner(rr2).setVrf(vRr2);
_ib.setAddress(new InterfaceAddress(rr2LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build();
_ib.setAddress(new InterfaceAddress(rr2IbgpIfaceIp, EDGE_PREFIX_LENGTH)).build();
BgpProcess rr2Proc = _pb.setRouterId(rr2LoopbackIp).setVrf(vRr2).build();
RoutingPolicy edge2IbgpExportPolicy = _defaultExportPolicyBuilder.setOwner(rr2).build();
vRr2.setStaticRoutes(ImmutableSortedSet.of(sb.setNextHopIp(rr1Rr2IfaceIp).setNetwork(new Prefix(rr1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build()));
Ip rr2ClusterIdForRr1 = useSameClusterIds ? rr1LoopbackIp : rr2LoopbackIp;
_nb.setOwner(rr2).setVrf(vRr2).setBgpProcess(rr2Proc).setClusterId(rr2ClusterIdForRr1.asLong()).setLocalIp(rr2LoopbackIp).setPeerAddress(rr1LoopbackIp).setRouteReflectorClient(true).setExportPolicy(edge2IbgpExportPolicy.getName()).build();
SortedMap<String, Configuration> configurations = new ImmutableSortedMap.Builder<String, Configuration>(String::compareTo).put(edge1.getName(), edge1).put(rr1.getName(), rr1).put(rr2.getName(), rr2).build();
BdpEngine engine = new BdpEngine(new MockBdpSettings(), new BatfishLogger(BatfishLogger.LEVELSTR_OUTPUT, false), (s, i) -> new AtomicInteger());
Topology topology = CommonUtil.synthesizeTopology(configurations);
BdpDataPlane dp = engine.computeDataPlane(false, configurations, topology, ImmutableSet.of(_ab.setAsPath(AsPath.ofSingletonAsSets(1)).setDstIp(edge1EbgpIfaceIp).setDstNode(edge1.getName()).setNetwork(AS1_PREFIX).setNextHopIp(as1PeeringIp).setOriginatorIp(as1PeeringIp).setSrcIp(as1PeeringIp).setSrcNode("as1Edge").build()), new BdpAnswerElement());
return engine.getRoutes(dp);
}
use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.
the class VirtualRouterTest method computeBgpAdvertisementsSTOIbgpAdvertiseExternal.
@Test
public void computeBgpAdvertisementsSTOIbgpAdvertiseExternal() {
RoutingPolicy exportPolicy = _routingPolicyBuilder.setStatements(ImmutableList.of(_exitAcceptStatement)).build();
_bgpNeighborBuilder.setRemoteAs(TEST_AS1).setExportPolicy(exportPolicy.getName()).setAdvertiseExternal(true).build();
_testVirtualRouter._ebgpBestPathRib.mergeRoute(_bgpRouteBuilder.setNextHopIp(TEST_NEXT_HOP_IP1).setReceivedFromIp(TEST_NEXT_HOP_IP1).build());
/* checking that the route in EBGP Best Path Rib got advertised */
assertThat(_testVirtualRouter.computeBgpAdvertisementsToOutside(_ipOwners), equalTo(1));
BgpAdvertisement bgpAdvertisement = _testVirtualRouter._sentBgpAdvertisements.iterator().next();
// checking the attributes of the bgp advertisement
assertThat(bgpAdvertisement, hasDestinationIp(TEST_DEST_IP));
assertThat(bgpAdvertisement, hasNetwork(TEST_NETWORK));
assertThat(bgpAdvertisement, hasOriginatorIp(TEST_SRC_IP));
assertThat(bgpAdvertisement, hasType(BgpAdvertisementType.IBGP_SENT));
assertThat(bgpAdvertisement, hasSourceIp(TEST_SRC_IP));
}
Aggregations