use of org.batfish.datamodel.routing_policy.expr.MatchPrefixSet in project batfish by batfish.
the class PsFromPrefixListFilterLonger method toBooleanExpr.
@Override
public BooleanExpr toBooleanExpr(JuniperConfiguration jc, Configuration c, Warnings warnings) {
PrefixList pl = jc.getPrefixLists().get(_prefixList);
if (pl != null) {
pl.getReferers().put(this, "from prefix-list-filter longer");
if (pl.getIpv6()) {
return BooleanExprs.False.toStaticBooleanExpr();
}
RouteFilterList rf = c.getRouteFilterLists().get(_prefixList);
String longerListName = "~" + _prefixList + "~LONGER~";
RouteFilterList longerList = c.getRouteFilterLists().get(longerListName);
if (longerList == null) {
longerList = new RouteFilterList(longerListName);
for (RouteFilterLine line : rf.getLines()) {
Prefix prefix = line.getPrefix();
LineAction action = line.getAction();
SubRange longerLineRange = new SubRange(line.getLengthRange().getStart() + 1, Prefix.MAX_PREFIX_LENGTH);
if (longerLineRange.getStart() > Prefix.MAX_PREFIX_LENGTH) {
warnings.redFlag("'prefix-list-filter " + _prefixList + " longer' cannot match more specific prefix than " + prefix);
continue;
}
RouteFilterLine orLongerLine = new RouteFilterLine(action, prefix, longerLineRange);
longerList.addLine(orLongerLine);
c.getRouteFilterLists().put(longerListName, longerList);
}
}
return new MatchPrefixSet(new DestinationNetwork(), new NamedPrefixSet(longerListName));
} else {
warnings.redFlag("Reference to undefined prefix-list: \"" + _prefixList + "\"");
return BooleanExprs.False.toStaticBooleanExpr();
}
}
use of org.batfish.datamodel.routing_policy.expr.MatchPrefixSet in project batfish by batfish.
the class PsFromPrefixListFilterOrLonger method toBooleanExpr.
@Override
public BooleanExpr toBooleanExpr(JuniperConfiguration jc, Configuration c, Warnings warnings) {
PrefixList pl = jc.getPrefixLists().get(_prefixList);
if (pl != null) {
pl.getReferers().put(this, "from prefix-list-filter or-longer");
if (pl.getIpv6()) {
return BooleanExprs.False.toStaticBooleanExpr();
}
RouteFilterList rf = c.getRouteFilterLists().get(_prefixList);
String orLongerListName = "~" + _prefixList + "~ORLONGER~";
RouteFilterList orLongerList = c.getRouteFilterLists().get(orLongerListName);
if (orLongerList == null) {
orLongerList = new RouteFilterList(orLongerListName);
for (RouteFilterLine line : rf.getLines()) {
Prefix prefix = line.getPrefix();
LineAction action = line.getAction();
SubRange orLongerLineRange = new SubRange(line.getLengthRange().getStart(), Prefix.MAX_PREFIX_LENGTH);
RouteFilterLine orLongerLine = new RouteFilterLine(action, prefix, orLongerLineRange);
orLongerList.addLine(orLongerLine);
c.getRouteFilterLists().put(orLongerListName, orLongerList);
}
}
return new MatchPrefixSet(new DestinationNetwork(), new NamedPrefixSet(orLongerListName));
} else {
warnings.redFlag("Reference to undefined prefix-list: \"" + _prefixList + "\"");
return BooleanExprs.False.toStaticBooleanExpr();
}
}
use of org.batfish.datamodel.routing_policy.expr.MatchPrefixSet in project batfish by batfish.
the class PsFromRouteFilter method toBooleanExpr.
@Override
public BooleanExpr toBooleanExpr(JuniperConfiguration jc, Configuration c, Warnings warnings) {
RouteFilterList rfl = c.getRouteFilterLists().get(_routeFilterName);
Route6FilterList rfl6 = c.getRoute6FilterLists().get(_routeFilterName);
BooleanExpr match4 = null;
BooleanExpr match6 = null;
if (rfl != null) {
match4 = new MatchPrefixSet(new DestinationNetwork(), new NamedPrefixSet(_routeFilterName));
}
if (rfl6 != null) {
match6 = new MatchPrefix6Set(new DestinationNetwork6(), new NamedPrefix6Set(_routeFilterName));
}
if (match4 != null && match6 == null) {
return match4;
} else if (rfl == null && rfl6 != null) {
return match6;
} else if (rfl != null && rfl6 != null) {
Disjunction d = new Disjunction();
d.getDisjuncts().add(match4);
d.getDisjuncts().add(match6);
return d;
} else {
throw new VendorConversionException("missing route filter list: \"" + _routeFilterName + "\"");
}
}
use of org.batfish.datamodel.routing_policy.expr.MatchPrefixSet 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.expr.MatchPrefixSet in project batfish by batfish.
the class CiscoConfiguration method toRipProcess.
private org.batfish.datamodel.RipProcess toRipProcess(RipProcess proc, String vrfName, Configuration c, CiscoConfiguration oldConfig) {
org.batfish.datamodel.RipProcess newProcess = new org.batfish.datamodel.RipProcess();
org.batfish.datamodel.Vrf vrf = c.getVrfs().get(vrfName);
// establish areas and associated interfaces
SortedSet<Prefix> networks = proc.getNetworks();
for (Entry<String, org.batfish.datamodel.Interface> e : vrf.getInterfaces().entrySet()) {
String ifaceName = e.getKey();
org.batfish.datamodel.Interface i = e.getValue();
InterfaceAddress interfaceAddress = i.getAddress();
if (interfaceAddress == null) {
continue;
}
Prefix interfaceNetwork = interfaceAddress.getPrefix();
if (networks.contains(interfaceNetwork)) {
newProcess.getInterfaces().add(ifaceName);
i.setRipEnabled(true);
boolean passive = proc.getPassiveInterfaceList().contains(i.getName()) || (proc.getPassiveInterfaceDefault() && !proc.getActiveInterfaceList().contains(ifaceName));
i.setOspfPassive(passive);
}
}
String ripExportPolicyName = "~RIP_EXPORT_POLICY:" + vrfName + "~";
RoutingPolicy ripExportPolicy = new RoutingPolicy(ripExportPolicyName, c);
c.getRoutingPolicies().put(ripExportPolicyName, ripExportPolicy);
List<Statement> ripExportStatements = ripExportPolicy.getStatements();
newProcess.setExportPolicy(ripExportPolicyName);
// policy map for default information
if (proc.getDefaultInformationOriginate()) {
If ripExportDefault = new If();
ripExportStatements.add(ripExportDefault);
ripExportDefault.setComment("RIP export default route");
Conjunction ripExportDefaultConditions = new Conjunction();
List<Statement> ripExportDefaultStatements = ripExportDefault.getTrueStatements();
ripExportDefaultConditions.getConjuncts().add(new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(new PrefixSpace(Collections.singleton(new PrefixRange(Prefix.ZERO, new SubRange(0, 0)))))));
long metric = proc.getDefaultInformationMetric();
ripExportDefaultStatements.add(new SetMetric(new LiteralLong(metric)));
// add default export map with metric
String defaultOriginateMapName = proc.getDefaultInformationOriginateMap();
if (defaultOriginateMapName != null) {
int defaultOriginateMapLine = proc.getDefaultInformationOriginateMapLine();
RoutingPolicy ripDefaultGenerationPolicy = c.getRoutingPolicies().get(defaultOriginateMapName);
if (ripDefaultGenerationPolicy == null) {
undefined(CiscoStructureType.ROUTE_MAP, defaultOriginateMapName, CiscoStructureUsage.RIP_DEFAULT_ORIGINATE_ROUTE_MAP, defaultOriginateMapLine);
} else {
RouteMap generationRouteMap = _routeMaps.get(defaultOriginateMapName);
generationRouteMap.getReferers().put(proc, "rip default-originate route-map");
GeneratedRoute.Builder route = new GeneratedRoute.Builder();
route.setNetwork(Prefix.ZERO);
route.setAdmin(MAX_ADMINISTRATIVE_COST);
route.setGenerationPolicy(defaultOriginateMapName);
newProcess.getGeneratedRoutes().add(route.build());
}
} else {
// add generated aggregate with no precondition
GeneratedRoute.Builder route = new GeneratedRoute.Builder();
route.setNetwork(Prefix.ZERO);
route.setAdmin(MAX_ADMINISTRATIVE_COST);
newProcess.getGeneratedRoutes().add(route.build());
}
ripExportDefaultConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.AGGREGATE));
ripExportDefaultStatements.add(Statements.ExitAccept.toStaticStatement());
ripExportDefault.setGuard(ripExportDefaultConditions);
}
// policy for redistributing connected routes
RipRedistributionPolicy rcp = proc.getRedistributionPolicies().get(RoutingProtocol.CONNECTED);
if (rcp != null) {
If ripExportConnected = new If();
ripExportConnected.setComment("RIP export connected routes");
Conjunction ripExportConnectedConditions = new Conjunction();
ripExportConnectedConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.CONNECTED));
List<Statement> ripExportConnectedStatements = ripExportConnected.getTrueStatements();
Long metric = rcp.getMetric();
boolean explicitMetric = metric != null;
if (!explicitMetric) {
metric = RipRedistributionPolicy.DEFAULT_REDISTRIBUTE_CONNECTED_METRIC;
}
ripExportStatements.add(new SetMetric(new LiteralLong(metric)));
ripExportStatements.add(ripExportConnected);
// add default export map with metric
String exportConnectedRouteMapName = rcp.getRouteMap();
if (exportConnectedRouteMapName != null) {
int exportConnectedRouteMapLine = rcp.getRouteMapLine();
RouteMap exportConnectedRouteMap = _routeMaps.get(exportConnectedRouteMapName);
if (exportConnectedRouteMap == null) {
undefined(CiscoStructureType.ROUTE_MAP, exportConnectedRouteMapName, CiscoStructureUsage.RIP_REDISTRIBUTE_CONNECTED_MAP, exportConnectedRouteMapLine);
} else {
exportConnectedRouteMap.getReferers().put(proc, "rip redistribute connected route-map");
ripExportConnectedConditions.getConjuncts().add(new CallExpr(exportConnectedRouteMapName));
}
}
ripExportConnectedStatements.add(Statements.ExitAccept.toStaticStatement());
ripExportConnected.setGuard(ripExportConnectedConditions);
}
// policy map for redistributing static routes
RipRedistributionPolicy rsp = proc.getRedistributionPolicies().get(RoutingProtocol.STATIC);
if (rsp != null) {
If ripExportStatic = new If();
ripExportStatic.setComment("RIP export static routes");
Conjunction ripExportStaticConditions = new Conjunction();
ripExportStaticConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.STATIC));
List<Statement> ripExportStaticStatements = ripExportStatic.getTrueStatements();
ripExportStaticConditions.getConjuncts().add(new Not(new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(new PrefixSpace(Collections.singleton(new PrefixRange(Prefix.ZERO, new SubRange(0, 0))))))));
Long metric = rsp.getMetric();
boolean explicitMetric = metric != null;
if (!explicitMetric) {
metric = RipRedistributionPolicy.DEFAULT_REDISTRIBUTE_STATIC_METRIC;
}
ripExportStatements.add(new SetMetric(new LiteralLong(metric)));
ripExportStatements.add(ripExportStatic);
// add export map with metric
String exportStaticRouteMapName = rsp.getRouteMap();
if (exportStaticRouteMapName != null) {
int exportStaticRouteMapLine = rsp.getRouteMapLine();
RouteMap exportStaticRouteMap = _routeMaps.get(exportStaticRouteMapName);
if (exportStaticRouteMap == null) {
undefined(CiscoStructureType.ROUTE_MAP, exportStaticRouteMapName, CiscoStructureUsage.RIP_REDISTRIBUTE_STATIC_MAP, exportStaticRouteMapLine);
} else {
exportStaticRouteMap.getReferers().put(proc, "rip redistribute static route-map");
ripExportStaticConditions.getConjuncts().add(new CallExpr(exportStaticRouteMapName));
}
}
ripExportStaticStatements.add(Statements.ExitAccept.toStaticStatement());
ripExportStatic.setGuard(ripExportStaticConditions);
}
// policy map for redistributing bgp routes
RipRedistributionPolicy rbp = proc.getRedistributionPolicies().get(RoutingProtocol.BGP);
if (rbp != null) {
If ripExportBgp = new If();
ripExportBgp.setComment("RIP export bgp routes");
Conjunction ripExportBgpConditions = new Conjunction();
ripExportBgpConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.BGP));
List<Statement> ripExportBgpStatements = ripExportBgp.getTrueStatements();
ripExportBgpConditions.getConjuncts().add(new Not(new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(new PrefixSpace(Collections.singleton(new PrefixRange(Prefix.ZERO, new SubRange(0, 0))))))));
Long metric = rbp.getMetric();
boolean explicitMetric = metric != null;
if (!explicitMetric) {
metric = RipRedistributionPolicy.DEFAULT_REDISTRIBUTE_BGP_METRIC;
}
ripExportStatements.add(new SetMetric(new LiteralLong(metric)));
ripExportStatements.add(ripExportBgp);
// add export map with metric
String exportBgpRouteMapName = rbp.getRouteMap();
if (exportBgpRouteMapName != null) {
int exportBgpRouteMapLine = rbp.getRouteMapLine();
RouteMap exportBgpRouteMap = _routeMaps.get(exportBgpRouteMapName);
if (exportBgpRouteMap == null) {
undefined(CiscoStructureType.ROUTE_MAP, exportBgpRouteMapName, CiscoStructureUsage.RIP_REDISTRIBUTE_BGP_MAP, exportBgpRouteMapLine);
} else {
exportBgpRouteMap.getReferers().put(proc, "rip redistribute bgp route-map");
ripExportBgpConditions.getConjuncts().add(new CallExpr(exportBgpRouteMapName));
}
}
ripExportBgpStatements.add(Statements.ExitAccept.toStaticStatement());
ripExportBgp.setGuard(ripExportBgpConditions);
}
return newProcess;
}
Aggregations