use of org.batfish.datamodel.routing_policy.expr.CallExpr in project batfish by batfish.
the class RoutingPolicyTests method testRoutingPolicyCircularReferenceExpr.
/**
* Policy with actual circular reference as expr
*/
@Test
public void testRoutingPolicyCircularReferenceExpr() {
String parentPolicyName = "parent";
CallExpr callExpr = new CallExpr(parentPolicyName);
If ifStatement = new If();
ifStatement.setGuard(callExpr);
_rpb.setName(parentPolicyName).setStatements(ImmutableList.of(ifStatement)).build();
_c.computeRoutingPolicySources(_w);
/*
* A circular reference warning should be emitted containing the name of the circularly
* referenced policy.
*/
assertThat(_w.getRedFlagWarnings(), not(empty()));
assertThat(_w.getRedFlagWarnings().iterator().next().getText(), containsString(parentPolicyName));
}
use of org.batfish.datamodel.routing_policy.expr.CallExpr 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;
}
use of org.batfish.datamodel.routing_policy.expr.CallExpr in project batfish by batfish.
the class CiscoConfiguration method toBgpProcess.
private org.batfish.datamodel.BgpProcess toBgpProcess(final Configuration c, BgpProcess proc, String vrfName) {
org.batfish.datamodel.BgpProcess newBgpProcess = new org.batfish.datamodel.BgpProcess();
org.batfish.datamodel.Vrf v = c.getVrfs().get(vrfName);
BgpTieBreaker tieBreaker = proc.getTieBreaker();
if (tieBreaker != null) {
newBgpProcess.setTieBreaker(tieBreaker);
}
MultipathEquivalentAsPathMatchMode multipathEquivalentAsPathMatchMode = proc.getAsPathMultipathRelax() ? MultipathEquivalentAsPathMatchMode.PATH_LENGTH : MultipathEquivalentAsPathMatchMode.EXACT_PATH;
newBgpProcess.setMultipathEquivalentAsPathMatchMode(multipathEquivalentAsPathMatchMode);
Integer maximumPaths = proc.getMaximumPaths();
Integer maximumPathsEbgp = proc.getMaximumPathsEbgp();
Integer maximumPathsIbgp = proc.getMaximumPathsIbgp();
boolean multipathEbgp = false;
boolean multipathIbgp = false;
if (maximumPaths != null && maximumPaths > 1) {
multipathEbgp = true;
multipathIbgp = true;
}
if (maximumPathsEbgp != null && maximumPathsEbgp > 1) {
multipathEbgp = true;
}
if (maximumPathsIbgp != null && maximumPathsIbgp > 1) {
multipathIbgp = true;
}
newBgpProcess.setMultipathEbgp(multipathEbgp);
newBgpProcess.setMultipathIbgp(multipathIbgp);
Map<Prefix, BgpNeighbor> newBgpNeighbors = newBgpProcess.getNeighbors();
int defaultMetric = proc.getDefaultMetric();
Ip bgpRouterId = getBgpRouterId(c, vrfName, proc);
MatchPrefixSet matchDefaultRoute = new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(new PrefixSpace(Collections.singleton(new PrefixRange(Prefix.ZERO, new SubRange(0, 0))))));
matchDefaultRoute.setComment("match default route");
MatchPrefix6Set matchDefaultRoute6 = new MatchPrefix6Set(new DestinationNetwork6(), new ExplicitPrefix6Set(new Prefix6Space(Collections.singleton(new Prefix6Range(Prefix6.ZERO, new SubRange(0, 0))))));
matchDefaultRoute.setComment("match default route");
newBgpProcess.setRouterId(bgpRouterId);
Set<BgpAggregateIpv4Network> summaryOnlyNetworks = new HashSet<>();
Set<BgpAggregateIpv6Network> summaryOnlyIpv6Networks = new HashSet<>();
List<BooleanExpr> attributeMapPrefilters = new ArrayList<>();
// add generated routes for aggregate ipv4 addresses
for (Entry<Prefix, BgpAggregateIpv4Network> e : proc.getAggregateNetworks().entrySet()) {
Prefix prefix = e.getKey();
BgpAggregateIpv4Network aggNet = e.getValue();
boolean summaryOnly = aggNet.getSummaryOnly();
int prefixLength = prefix.getPrefixLength();
SubRange prefixRange = new SubRange(prefixLength + 1, Prefix.MAX_PREFIX_LENGTH);
if (summaryOnly) {
summaryOnlyNetworks.add(aggNet);
}
// create generation policy for aggregate network
String generationPolicyName = "~AGGREGATE_ROUTE_GEN:" + vrfName + ":" + prefix + "~";
RoutingPolicy currentGeneratedRoutePolicy = new RoutingPolicy(generationPolicyName, c);
If currentGeneratedRouteConditional = new If();
currentGeneratedRoutePolicy.getStatements().add(currentGeneratedRouteConditional);
currentGeneratedRouteConditional.setGuard(new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(new PrefixSpace(Collections.singleton(new PrefixRange(prefix, prefixRange))))));
currentGeneratedRouteConditional.getTrueStatements().add(Statements.ReturnTrue.toStaticStatement());
c.getRoutingPolicies().put(generationPolicyName, currentGeneratedRoutePolicy);
GeneratedRoute.Builder gr = new GeneratedRoute.Builder();
gr.setNetwork(prefix);
gr.setAdmin(CISCO_AGGREGATE_ROUTE_ADMIN_COST);
gr.setGenerationPolicy(generationPolicyName);
gr.setDiscard(true);
// set attribute map for aggregate network
String attributeMapName = aggNet.getAttributeMap();
Conjunction applyCurrentAggregateAttributesConditions = new Conjunction();
applyCurrentAggregateAttributesConditions.getConjuncts().add(new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(new PrefixSpace(Collections.singleton(PrefixRange.fromPrefix(prefix))))));
applyCurrentAggregateAttributesConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.AGGREGATE));
BooleanExpr weInterior = BooleanExprs.True.toStaticBooleanExpr();
if (attributeMapName != null) {
int attributeMapLine = aggNet.getAttributeMapLine();
RouteMap attributeMap = _routeMaps.get(attributeMapName);
if (attributeMap != null) {
// need to apply attribute changes if this specific route is
// matched
weInterior = new CallExpr(attributeMapName);
attributeMap.getReferers().put(aggNet, "attribute-map of aggregate route: " + prefix);
gr.setAttributePolicy(attributeMapName);
} else {
undefined(CiscoStructureType.ROUTE_MAP, attributeMapName, CiscoStructureUsage.BGP_AGGREGATE_ATTRIBUTE_MAP, attributeMapLine);
}
}
v.getGeneratedRoutes().add(gr.build());
BooleanExpr we = bgpRedistributeWithEnvironmentExpr(weInterior, OriginType.IGP);
applyCurrentAggregateAttributesConditions.getConjuncts().add(we);
attributeMapPrefilters.add(applyCurrentAggregateAttributesConditions);
}
// TODO: merge with above to make cleaner
for (Entry<Prefix6, BgpAggregateIpv6Network> e : proc.getAggregateIpv6Networks().entrySet()) {
Prefix6 prefix6 = e.getKey();
BgpAggregateIpv6Network aggNet = e.getValue();
boolean summaryOnly = aggNet.getSummaryOnly();
int prefixLength = prefix6.getPrefixLength();
SubRange prefixRange = new SubRange(prefixLength + 1, Prefix.MAX_PREFIX_LENGTH);
if (summaryOnly) {
summaryOnlyIpv6Networks.add(aggNet);
}
// create generation policy for aggregate network
String generationPolicyName = "~AGGREGATE_ROUTE6_GEN:" + vrfName + ":" + prefix6 + "~";
RoutingPolicy currentGeneratedRoutePolicy = new RoutingPolicy(generationPolicyName, c);
If currentGeneratedRouteConditional = new If();
currentGeneratedRoutePolicy.getStatements().add(currentGeneratedRouteConditional);
currentGeneratedRouteConditional.setGuard(new MatchPrefix6Set(new DestinationNetwork6(), new ExplicitPrefix6Set(new Prefix6Space(Collections.singleton(new Prefix6Range(prefix6, prefixRange))))));
currentGeneratedRouteConditional.getTrueStatements().add(Statements.ReturnTrue.toStaticStatement());
c.getRoutingPolicies().put(generationPolicyName, currentGeneratedRoutePolicy);
GeneratedRoute6 gr = new GeneratedRoute6(prefix6, CISCO_AGGREGATE_ROUTE_ADMIN_COST);
gr.setGenerationPolicy(generationPolicyName);
gr.setDiscard(true);
v.getGeneratedIpv6Routes().add(gr);
// set attribute map for aggregate network
String attributeMapName = aggNet.getAttributeMap();
if (attributeMapName != null) {
int attributeMapLine = aggNet.getAttributeMapLine();
RouteMap attributeMap = _routeMaps.get(attributeMapName);
if (attributeMap != null) {
attributeMap.getReferers().put(aggNet, "attribute-map of aggregate ipv6 route: " + prefix6);
gr.setAttributePolicy(attributeMapName);
} else {
undefined(CiscoStructureType.ROUTE_MAP, attributeMapName, CiscoStructureUsage.BGP_AGGREGATE_ATTRIBUTE_MAP, attributeMapLine);
}
}
}
/*
* Create common bgp export policy. This policy encompasses network
* statements, aggregate-address with/without summary-only, redistribution
* from other protocols, and default-origination
*/
String bgpCommonExportPolicyName = "~BGP_COMMON_EXPORT_POLICY:" + vrfName + "~";
RoutingPolicy bgpCommonExportPolicy = new RoutingPolicy(bgpCommonExportPolicyName, c);
c.getRoutingPolicies().put(bgpCommonExportPolicyName, bgpCommonExportPolicy);
List<Statement> bgpCommonExportStatements = bgpCommonExportPolicy.getStatements();
// create policy for denying suppressed summary-only networks
if (summaryOnlyNetworks.size() > 0) {
If suppressSummaryOnly = new If();
bgpCommonExportStatements.add(suppressSummaryOnly);
suppressSummaryOnly.setComment("Suppress summarized of summary-only aggregate-address networks");
String matchSuppressedSummaryOnlyRoutesName = "~MATCH_SUPPRESSED_SUMMARY_ONLY:" + vrfName + "~";
RouteFilterList matchSuppressedSummaryOnlyRoutes = new RouteFilterList(matchSuppressedSummaryOnlyRoutesName);
c.getRouteFilterLists().put(matchSuppressedSummaryOnlyRoutesName, matchSuppressedSummaryOnlyRoutes);
for (BgpAggregateIpv4Network summaryOnlyNetwork : summaryOnlyNetworks) {
Prefix prefix = summaryOnlyNetwork.getPrefix();
int prefixLength = prefix.getPrefixLength();
RouteFilterLine line = new RouteFilterLine(LineAction.ACCEPT, prefix, new SubRange(prefixLength + 1, Prefix.MAX_PREFIX_LENGTH));
matchSuppressedSummaryOnlyRoutes.addLine(line);
}
suppressSummaryOnly.setGuard(new MatchPrefixSet(new DestinationNetwork(), new NamedPrefixSet(matchSuppressedSummaryOnlyRoutesName)));
suppressSummaryOnly.getTrueStatements().add(Statements.ReturnFalse.toStaticStatement());
}
If preFilter = new If();
bgpCommonExportStatements.add(preFilter);
bgpCommonExportStatements.add(Statements.ReturnFalse.toStaticStatement());
Disjunction preFilterConditions = new Disjunction();
preFilter.setGuard(preFilterConditions);
preFilter.getTrueStatements().add(Statements.ReturnTrue.toStaticStatement());
preFilterConditions.getDisjuncts().addAll(attributeMapPrefilters);
// create redistribution origination policies
// redistribute rip
BgpRedistributionPolicy redistributeRipPolicy = proc.getRedistributionPolicies().get(RoutingProtocol.RIP);
if (redistributeRipPolicy != null) {
BooleanExpr weInterior = BooleanExprs.True.toStaticBooleanExpr();
Conjunction exportRipConditions = new Conjunction();
exportRipConditions.setComment("Redistribute RIP routes into BGP");
exportRipConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.RIP));
String mapName = redistributeRipPolicy.getRouteMap();
if (mapName != null) {
int mapLine = redistributeRipPolicy.getRouteMapLine();
RouteMap redistributeRipRouteMap = _routeMaps.get(mapName);
if (redistributeRipRouteMap != null) {
redistributeRipRouteMap.getReferers().put(proc, "RIP redistribution route-map");
weInterior = new CallExpr(mapName);
} else {
undefined(CiscoStructureType.ROUTE_MAP, mapName, CiscoStructureUsage.BGP_REDISTRIBUTE_RIP_MAP, mapLine);
}
}
BooleanExpr we = bgpRedistributeWithEnvironmentExpr(weInterior, OriginType.INCOMPLETE);
exportRipConditions.getConjuncts().add(we);
preFilterConditions.getDisjuncts().add(exportRipConditions);
}
// redistribute static
BgpRedistributionPolicy redistributeStaticPolicy = proc.getRedistributionPolicies().get(RoutingProtocol.STATIC);
if (redistributeStaticPolicy != null) {
BooleanExpr weInterior = BooleanExprs.True.toStaticBooleanExpr();
Conjunction exportStaticConditions = new Conjunction();
exportStaticConditions.setComment("Redistribute static routes into BGP");
exportStaticConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.STATIC));
String mapName = redistributeStaticPolicy.getRouteMap();
if (mapName != null) {
int mapLine = redistributeStaticPolicy.getRouteMapLine();
RouteMap redistributeStaticRouteMap = _routeMaps.get(mapName);
if (redistributeStaticRouteMap != null) {
redistributeStaticRouteMap.getReferers().put(proc, "static redistribution route-map");
weInterior = new CallExpr(mapName);
} else {
undefined(CiscoStructureType.ROUTE_MAP, mapName, CiscoStructureUsage.BGP_REDISTRIBUTE_STATIC_MAP, mapLine);
}
}
BooleanExpr we = bgpRedistributeWithEnvironmentExpr(weInterior, OriginType.INCOMPLETE);
exportStaticConditions.getConjuncts().add(we);
preFilterConditions.getDisjuncts().add(exportStaticConditions);
}
// redistribute connected
BgpRedistributionPolicy redistributeConnectedPolicy = proc.getRedistributionPolicies().get(RoutingProtocol.CONNECTED);
if (redistributeConnectedPolicy != null) {
BooleanExpr weInterior = BooleanExprs.True.toStaticBooleanExpr();
Conjunction exportConnectedConditions = new Conjunction();
exportConnectedConditions.setComment("Redistribute connected routes into BGP");
exportConnectedConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.CONNECTED));
String mapName = redistributeConnectedPolicy.getRouteMap();
if (mapName != null) {
int mapLine = redistributeConnectedPolicy.getRouteMapLine();
RouteMap redistributeConnectedRouteMap = _routeMaps.get(mapName);
if (redistributeConnectedRouteMap != null) {
redistributeConnectedRouteMap.getReferers().put(proc, "connected redistribution route-map");
weInterior = new CallExpr(mapName);
} else {
undefined(CiscoStructureType.ROUTE_MAP, mapName, CiscoStructureUsage.BGP_REDISTRIBUTE_CONNECTED_MAP, mapLine);
}
}
BooleanExpr we = bgpRedistributeWithEnvironmentExpr(weInterior, OriginType.INCOMPLETE);
exportConnectedConditions.getConjuncts().add(we);
preFilterConditions.getDisjuncts().add(exportConnectedConditions);
}
// redistribute ospf
BgpRedistributionPolicy redistributeOspfPolicy = proc.getRedistributionPolicies().get(RoutingProtocol.OSPF);
if (redistributeOspfPolicy != null) {
BooleanExpr weInterior = BooleanExprs.True.toStaticBooleanExpr();
Conjunction exportOspfConditions = new Conjunction();
exportOspfConditions.setComment("Redistribute OSPF routes into BGP");
exportOspfConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.OSPF));
String mapName = redistributeOspfPolicy.getRouteMap();
if (mapName != null) {
int mapLine = redistributeOspfPolicy.getRouteMapLine();
RouteMap redistributeOspfRouteMap = _routeMaps.get(mapName);
if (redistributeOspfRouteMap != null) {
redistributeOspfRouteMap.getReferers().put(proc, "ospf redistribution route-map");
weInterior = new CallExpr(mapName);
} else {
undefined(CiscoStructureType.ROUTE_MAP, mapName, CiscoStructureUsage.BGP_REDISTRIBUTE_OSPF_MAP, mapLine);
}
}
BooleanExpr we = bgpRedistributeWithEnvironmentExpr(weInterior, OriginType.INCOMPLETE);
exportOspfConditions.getConjuncts().add(we);
preFilterConditions.getDisjuncts().add(exportOspfConditions);
}
// cause ip peer groups to inherit unset fields from owning named peer
// group if it exists, and then always from process master peer group
Set<LeafBgpPeerGroup> leafGroups = new LinkedHashSet<>();
leafGroups.addAll(proc.getIpPeerGroups().values());
leafGroups.addAll(proc.getIpv6PeerGroups().values());
leafGroups.addAll(proc.getDynamicIpPeerGroups().values());
leafGroups.addAll(proc.getDynamicIpv6PeerGroups().values());
for (LeafBgpPeerGroup lpg : leafGroups) {
lpg.inheritUnsetFields(proc, this);
}
_unusedPeerGroups = new TreeMap<>();
int fakePeerCounter = -1;
// peer groups / peer templates
for (Entry<String, NamedBgpPeerGroup> e : proc.getNamedPeerGroups().entrySet()) {
String name = e.getKey();
NamedBgpPeerGroup namedPeerGroup = e.getValue();
if (!namedPeerGroup.getInherited()) {
_unusedPeerGroups.put(name, namedPeerGroup.getDefinitionLine());
Ip fakeIp = new Ip(fakePeerCounter);
IpBgpPeerGroup fakePg = new IpBgpPeerGroup(fakeIp);
fakePg.setGroupName(name);
fakePg.setActive(false);
fakePg.setShutdown(true);
leafGroups.add(fakePg);
fakePg.inheritUnsetFields(proc, this);
fakePeerCounter--;
}
namedPeerGroup.inheritUnsetFields(proc, this);
}
// separate because peer sessions can inherit from other peer sessions
_unusedPeerSessions = new TreeMap<>();
int fakeGroupCounter = 1;
for (NamedBgpPeerGroup namedPeerGroup : proc.getPeerSessions().values()) {
namedPeerGroup.getParentSession(proc, this).inheritUnsetFields(proc, this);
}
for (Entry<String, NamedBgpPeerGroup> e : proc.getPeerSessions().entrySet()) {
String name = e.getKey();
NamedBgpPeerGroup namedPeerGroup = e.getValue();
if (!namedPeerGroup.getInherited()) {
_unusedPeerSessions.put(name, namedPeerGroup.getDefinitionLine());
String fakeNamedPgName = "~FAKE_PG_" + fakeGroupCounter + "~";
NamedBgpPeerGroup fakeNamedPg = new NamedBgpPeerGroup(fakeNamedPgName, -1);
fakeNamedPg.setPeerSession(name);
proc.getNamedPeerGroups().put(fakeNamedPgName, fakeNamedPg);
Ip fakeIp = new Ip(fakePeerCounter);
IpBgpPeerGroup fakePg = new IpBgpPeerGroup(fakeIp);
fakePg.setGroupName(fakeNamedPgName);
fakePg.setActive(false);
fakePg.setShutdown(true);
leafGroups.add(fakePg);
fakePg.inheritUnsetFields(proc, this);
fakeGroupCounter++;
fakePeerCounter--;
}
}
// create origination prefilter from listed advertised networks
proc.getIpNetworks().forEach((prefix, bgpNetwork) -> {
String mapName = bgpNetwork.getRouteMapName();
BooleanExpr weExpr = BooleanExprs.True.toStaticBooleanExpr();
if (mapName != null) {
int mapLine = bgpNetwork.getRouteMapLine();
RouteMap routeMap = _routeMaps.get(mapName);
if (routeMap != null) {
weExpr = new CallExpr(mapName);
routeMap.getReferers().put(proc, "bgp ipv4 advertised network route-map");
} else {
undefined(CiscoStructureType.ROUTE_MAP, mapName, CiscoStructureUsage.BGP_NETWORK_ORIGINATION_ROUTE_MAP, mapLine);
}
}
BooleanExpr we = bgpRedistributeWithEnvironmentExpr(weExpr, OriginType.IGP);
Conjunction exportNetworkConditions = new Conjunction();
PrefixSpace space = new PrefixSpace();
space.addPrefix(prefix);
exportNetworkConditions.getConjuncts().add(new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(space)));
exportNetworkConditions.getConjuncts().add(new Not(new MatchProtocol(RoutingProtocol.BGP)));
exportNetworkConditions.getConjuncts().add(new Not(new MatchProtocol(RoutingProtocol.IBGP)));
// TODO: ban aggregates?
exportNetworkConditions.getConjuncts().add(new Not(new MatchProtocol(RoutingProtocol.AGGREGATE)));
exportNetworkConditions.getConjuncts().add(we);
preFilterConditions.getDisjuncts().add(exportNetworkConditions);
});
String localFilter6Name = "~BGP_NETWORK6_NETWORKS_FILTER:" + vrfName + "~";
Route6FilterList localFilter6 = new Route6FilterList(localFilter6Name);
proc.getIpv6Networks().forEach((prefix6, bgpNetwork6) -> {
int prefixLen = prefix6.getPrefixLength();
Route6FilterLine line = new Route6FilterLine(LineAction.ACCEPT, prefix6, new SubRange(prefixLen, prefixLen));
localFilter6.addLine(line);
String mapName = bgpNetwork6.getRouteMapName();
if (mapName != null) {
int mapLine = bgpNetwork6.getRouteMapLine();
RouteMap routeMap = _routeMaps.get(mapName);
if (routeMap != null) {
routeMap.getReferers().put(proc, "bgp ipv6 advertised network route-map");
BooleanExpr we = bgpRedistributeWithEnvironmentExpr(new CallExpr(mapName), OriginType.IGP);
Conjunction exportNetwork6Conditions = new Conjunction();
Prefix6Space space6 = new Prefix6Space();
space6.addPrefix6(prefix6);
exportNetwork6Conditions.getConjuncts().add(new MatchPrefix6Set(new DestinationNetwork6(), new ExplicitPrefix6Set(space6)));
exportNetwork6Conditions.getConjuncts().add(new Not(new MatchProtocol(RoutingProtocol.BGP)));
exportNetwork6Conditions.getConjuncts().add(new Not(new MatchProtocol(RoutingProtocol.IBGP)));
// TODO: ban aggregates?
exportNetwork6Conditions.getConjuncts().add(new Not(new MatchProtocol(RoutingProtocol.AGGREGATE)));
exportNetwork6Conditions.getConjuncts().add(we);
preFilterConditions.getDisjuncts().add(exportNetwork6Conditions);
} else {
undefined(CiscoStructureType.ROUTE_MAP, mapName, CiscoStructureUsage.BGP_NETWORK6_ORIGINATION_ROUTE_MAP, mapLine);
}
}
});
c.getRoute6FilterLists().put(localFilter6Name, localFilter6);
MatchProtocol isEbgp = new MatchProtocol(RoutingProtocol.BGP);
MatchProtocol isIbgp = new MatchProtocol(RoutingProtocol.IBGP);
preFilterConditions.getDisjuncts().add(isEbgp);
preFilterConditions.getDisjuncts().add(isIbgp);
for (LeafBgpPeerGroup lpg : leafGroups) {
// update source
String updateSourceInterface = lpg.getUpdateSource();
boolean ipv4 = lpg.getNeighborPrefix() != null;
Ip updateSource = getUpdateSource(c, vrfName, lpg, updateSourceInterface, ipv4);
RoutingPolicy importPolicy = null;
String inboundRouteMapName = lpg.getInboundRouteMap();
if (inboundRouteMapName != null) {
int inboundRouteMapLine = lpg.getInboundRouteMapLine();
importPolicy = c.getRoutingPolicies().get(inboundRouteMapName);
if (importPolicy == null) {
undefined(CiscoStructureType.ROUTE_MAP, inboundRouteMapName, CiscoStructureUsage.BGP_INBOUND_ROUTE_MAP, inboundRouteMapLine);
} else {
RouteMap inboundRouteMap = _routeMaps.get(inboundRouteMapName);
inboundRouteMap.getReferers().put(lpg, "inbound route-map for leaf peer-group: " + lpg.getName());
}
}
String inboundRoute6MapName = lpg.getInboundRoute6Map();
RoutingPolicy importPolicy6 = null;
if (inboundRoute6MapName != null) {
int inboundRoute6MapLine = lpg.getInboundRoute6MapLine();
importPolicy6 = c.getRoutingPolicies().get(inboundRoute6MapName);
if (importPolicy6 == null) {
undefined(CiscoStructureType.ROUTE_MAP, inboundRoute6MapName, CiscoStructureUsage.BGP_INBOUND_ROUTE6_MAP, inboundRoute6MapLine);
} else {
RouteMap inboundRouteMap = _routeMaps.get(inboundRoute6MapName);
inboundRouteMap.getReferers().put(lpg, "inbound route-map for leaf peer-group: " + lpg.getName());
}
}
String peerExportPolicyName = "~BGP_PEER_EXPORT_POLICY:" + vrfName + ":" + lpg.getName() + "~";
RoutingPolicy peerExportPolicy = new RoutingPolicy(peerExportPolicyName, c);
if (lpg.getActive() && !lpg.getShutdown()) {
c.getRoutingPolicies().put(peerExportPolicyName, peerExportPolicy);
}
if (lpg.getNextHopSelf() != null && lpg.getNextHopSelf()) {
peerExportPolicy.getStatements().add(new SetNextHop(new SelfNextHop(), false));
}
if (lpg.getRemovePrivateAs() != null && lpg.getRemovePrivateAs()) {
peerExportPolicy.getStatements().add(Statements.RemovePrivateAs.toStaticStatement());
}
If peerExportConditional = new If();
peerExportConditional.setComment("peer-export policy main conditional: exitAccept if true / exitReject if false");
peerExportPolicy.getStatements().add(peerExportConditional);
Conjunction peerExportConditions = new Conjunction();
peerExportConditional.setGuard(peerExportConditions);
peerExportConditional.getTrueStatements().add(Statements.ExitAccept.toStaticStatement());
peerExportConditional.getFalseStatements().add(Statements.ExitReject.toStaticStatement());
Disjunction localOrCommonOrigination = new Disjunction();
peerExportConditions.getConjuncts().add(localOrCommonOrigination);
localOrCommonOrigination.getDisjuncts().add(new CallExpr(bgpCommonExportPolicyName));
String outboundRouteMapName = lpg.getOutboundRouteMap();
if (outboundRouteMapName != null) {
int outboundRouteMapLine = lpg.getOutboundRouteMapLine();
RouteMap outboundRouteMap = _routeMaps.get(outboundRouteMapName);
if (outboundRouteMap == null) {
undefined(CiscoStructureType.ROUTE_MAP, outboundRouteMapName, CiscoStructureUsage.BGP_OUTBOUND_ROUTE_MAP, outboundRouteMapLine);
} else {
outboundRouteMap.getReferers().put(lpg, "outbound route-map for leaf peer-group: " + lpg.getName());
peerExportConditions.getConjuncts().add(new CallExpr(outboundRouteMapName));
}
}
String outboundRoute6MapName = lpg.getOutboundRoute6Map();
if (outboundRoute6MapName != null) {
int outboundRoute6MapLine = lpg.getOutboundRoute6MapLine();
RouteMap outboundRoute6Map = _routeMaps.get(outboundRoute6MapName);
if (outboundRoute6Map == null) {
undefined(CiscoStructureType.ROUTE_MAP, outboundRoute6MapName, CiscoStructureUsage.BGP_OUTBOUND_ROUTE6_MAP, outboundRoute6MapLine);
} else {
outboundRoute6Map.getReferers().put(lpg, "outbound ipv6 route-map for leaf peer-group: " + lpg.getName());
}
}
// set up default export policy for this peer group
GeneratedRoute.Builder defaultRoute = null;
GeneratedRoute6.Builder defaultRoute6 = null;
if (lpg.getDefaultOriginate()) {
if (ipv4) {
localOrCommonOrigination.getDisjuncts().add(matchDefaultRoute);
} else {
localOrCommonOrigination.getDisjuncts().add(matchDefaultRoute6);
}
defaultRoute = new GeneratedRoute.Builder();
defaultRoute.setNetwork(Prefix.ZERO);
defaultRoute.setAdmin(MAX_ADMINISTRATIVE_COST);
defaultRoute6 = new GeneratedRoute6.Builder();
defaultRoute6.setNetwork(Prefix6.ZERO);
defaultRoute6.setAdmin(MAX_ADMINISTRATIVE_COST);
String defaultOriginateMapName = lpg.getDefaultOriginateMap();
if (defaultOriginateMapName != null) {
// originate contingent on
// generation policy
int defaultOriginateMapLine = lpg.getDefaultOriginateMapLine();
RoutingPolicy defaultRouteGenerationPolicy = c.getRoutingPolicies().get(defaultOriginateMapName);
if (defaultRouteGenerationPolicy == null) {
undefined(CiscoStructureType.ROUTE_MAP, defaultOriginateMapName, CiscoStructureUsage.BGP_DEFAULT_ORIGINATE_ROUTE_MAP, defaultOriginateMapLine);
} else {
RouteMap defaultRouteGenerationRouteMap = _routeMaps.get(defaultOriginateMapName);
defaultRouteGenerationRouteMap.getReferers().put(lpg, "default route generation policy for leaf peer-group: " + lpg.getName());
defaultRoute.setGenerationPolicy(defaultOriginateMapName);
}
} else {
String defaultRouteGenerationPolicyName = "~BGP_DEFAULT_ROUTE_GENERATION_POLICY:" + vrfName + ":" + lpg.getName() + "~";
RoutingPolicy defaultRouteGenerationPolicy = new RoutingPolicy(defaultRouteGenerationPolicyName, c);
If defaultRouteGenerationConditional = new If();
defaultRouteGenerationPolicy.getStatements().add(defaultRouteGenerationConditional);
if (ipv4) {
defaultRouteGenerationConditional.setGuard(matchDefaultRoute);
} else {
defaultRouteGenerationConditional.setGuard(matchDefaultRoute6);
}
defaultRouteGenerationConditional.getTrueStatements().add(Statements.ReturnTrue.toStaticStatement());
if (lpg.getActive() && !lpg.getShutdown()) {
c.getRoutingPolicies().put(defaultRouteGenerationPolicyName, defaultRouteGenerationPolicy);
}
if (ipv4) {
defaultRoute.setGenerationPolicy(defaultRouteGenerationPolicyName);
} else {
defaultRoute6.setGenerationPolicy(defaultRouteGenerationPolicyName);
}
}
}
Ip clusterId = lpg.getClusterId();
if (clusterId == null) {
clusterId = bgpRouterId;
}
boolean routeReflectorClient = lpg.getRouteReflectorClient();
boolean sendCommunity = lpg.getSendCommunity();
boolean additionalPathsReceive = lpg.getAdditionalPathsReceive();
boolean additionalPathsSelectAll = lpg.getAdditionalPathsSelectAll();
boolean additionalPathsSend = lpg.getAdditionalPathsSend();
boolean advertiseInactive = lpg.getAdvertiseInactive();
boolean ebgpMultihop = lpg.getEbgpMultihop();
boolean allowasIn = lpg.getAllowAsIn();
boolean disablePeerAsCheck = lpg.getDisablePeerAsCheck();
String inboundPrefixListName = lpg.getInboundPrefixList();
if (inboundPrefixListName != null) {
int inboundPrefixListLine = lpg.getInboundPrefixListLine();
ReferenceCountedStructure inboundPrefixList;
if (ipv4) {
inboundPrefixList = _prefixLists.get(inboundPrefixListName);
} else {
inboundPrefixList = _prefix6Lists.get(inboundPrefixListName);
}
if (inboundPrefixList != null) {
inboundPrefixList.getReferers().put(lpg, "inbound prefix-list for neighbor: '" + lpg.getName() + "'");
} else {
if (ipv4) {
undefined(CiscoStructureType.PREFIX_LIST, inboundPrefixListName, CiscoStructureUsage.BGP_INBOUND_PREFIX_LIST, inboundPrefixListLine);
} else {
undefined(CiscoStructureType.PREFIX6_LIST, inboundPrefixListName, CiscoStructureUsage.BGP_INBOUND_PREFIX6_LIST, inboundPrefixListLine);
}
}
}
String outboundPrefixListName = lpg.getOutboundPrefixList();
if (outboundPrefixListName != null) {
int outboundPrefixListLine = lpg.getOutboundPrefixListLine();
ReferenceCountedStructure outboundPrefixList;
if (ipv4) {
outboundPrefixList = _prefixLists.get(outboundPrefixListName);
} else {
outboundPrefixList = _prefix6Lists.get(outboundPrefixListName);
}
if (outboundPrefixList != null) {
outboundPrefixList.getReferers().put(lpg, "outbound prefix-list for neighbor: '" + lpg.getName() + "'");
} else {
if (ipv4) {
undefined(CiscoStructureType.PREFIX_LIST, outboundPrefixListName, CiscoStructureUsage.BGP_OUTBOUND_PREFIX_LIST, outboundPrefixListLine);
} else {
undefined(CiscoStructureType.PREFIX6_LIST, outboundPrefixListName, CiscoStructureUsage.BGP_OUTBOUND_PREFIX6_LIST, outboundPrefixListLine);
}
}
}
String description = lpg.getDescription();
if (lpg.getActive() && !lpg.getShutdown()) {
if (lpg.getRemoteAs() == null) {
_w.redFlag("No remote-as set for peer: " + lpg.getName());
continue;
}
Integer pgLocalAs = lpg.getLocalAs();
int localAs = pgLocalAs != null ? pgLocalAs : proc.getName();
BgpNeighbor newNeighbor;
if (lpg instanceof IpBgpPeerGroup) {
IpBgpPeerGroup ipg = (IpBgpPeerGroup) lpg;
Ip neighborAddress = ipg.getIp();
newNeighbor = new BgpNeighbor(neighborAddress, c);
} else if (lpg instanceof DynamicIpBgpPeerGroup) {
DynamicIpBgpPeerGroup dpg = (DynamicIpBgpPeerGroup) lpg;
Prefix neighborAddressRange = dpg.getPrefix();
newNeighbor = new BgpNeighbor(neighborAddressRange, c);
} else if (lpg instanceof Ipv6BgpPeerGroup || lpg instanceof DynamicIpv6BgpPeerGroup) {
// TODO: implement ipv6 bgp neighbors
continue;
} else {
throw new VendorConversionException("Invalid BGP leaf neighbor type");
}
newBgpNeighbors.put(newNeighbor.getPrefix(), newNeighbor);
newNeighbor.setAdditionalPathsReceive(additionalPathsReceive);
newNeighbor.setAdditionalPathsSelectAll(additionalPathsSelectAll);
newNeighbor.setAdditionalPathsSend(additionalPathsSend);
newNeighbor.setAdvertiseInactive(advertiseInactive);
newNeighbor.setAllowLocalAsIn(allowasIn);
newNeighbor.setAllowRemoteAsOut(disablePeerAsCheck);
newNeighbor.setRouteReflectorClient(routeReflectorClient);
newNeighbor.setClusterId(clusterId.asLong());
newNeighbor.setDefaultMetric(defaultMetric);
newNeighbor.setDescription(description);
newNeighbor.setEbgpMultihop(ebgpMultihop);
if (defaultRoute != null) {
newNeighbor.getGeneratedRoutes().add(defaultRoute.build());
}
newNeighbor.setGroup(lpg.getGroupName());
if (importPolicy != null) {
newNeighbor.setImportPolicy(inboundRouteMapName);
}
newNeighbor.setLocalAs(localAs);
newNeighbor.setLocalIp(updateSource);
newNeighbor.setExportPolicy(peerExportPolicyName);
newNeighbor.setRemoteAs(lpg.getRemoteAs());
newNeighbor.setSendCommunity(sendCommunity);
newNeighbor.setVrf(vrfName);
}
}
return newBgpProcess;
}
use of org.batfish.datamodel.routing_policy.expr.CallExpr in project batfish by batfish.
the class Optimizations method isDefaultBgpExport.
/*
* Determine if a BGP neighbor uses the default export policy
*/
private boolean isDefaultBgpExport(Configuration conf, BgpNeighbor n) {
// Check if valid neighbor
if (n == null || n.getExportPolicy() == null) {
return true;
}
// Ensure a single if statement
RoutingPolicy pol = conf.getRoutingPolicies().get(n.getExportPolicy());
List<Statement> stmts = pol.getStatements();
if (stmts.size() != 1) {
return false;
}
Statement s = stmts.get(0);
if (!(s instanceof If)) {
return false;
}
// Ensure that the true branch accepts and the false branch rejects
If i = (If) s;
BooleanExpr be = i.getGuard();
List<Statement> trueStmts = i.getTrueStatements();
List<Statement> falseStmts = i.getFalseStatements();
if (trueStmts.size() != 1 || falseStmts.size() != 1) {
return false;
}
Statement s1 = trueStmts.get(0);
Statement s2 = falseStmts.get(0);
if (!(s1 instanceof Statements.StaticStatement) || !(s2 instanceof Statements.StaticStatement)) {
return false;
}
Statements.StaticStatement x = (Statements.StaticStatement) s1;
Statements.StaticStatement y = (Statements.StaticStatement) s2;
if (x.getType() != Statements.ExitAccept || y.getType() != Statements.ExitReject) {
return false;
}
// Ensure condition just hands off to the common export policy
if (!(be instanceof CallExpr)) {
return false;
}
CallExpr ce = (CallExpr) be;
return ce.getCalledPolicyName().contains(Graph.BGP_COMMON_FILTER_LIST_NAME);
}
use of org.batfish.datamodel.routing_policy.expr.CallExpr in project batfish by batfish.
the class TransferSSA method compute.
/*
* Convert a Batfish AST boolean expression to a symbolic Z3 boolean expression
* by performing inlining of stateful side effects.
*/
private TransferResult<BoolExpr, BoolExpr> compute(BooleanExpr expr, TransferParam<SymbolicRoute> p) {
// TODO: right now everything is IPV4
if (expr instanceof MatchIpv4) {
p.debug("MatchIpv4");
return fromExpr(_enc.mkTrue());
}
if (expr instanceof MatchIpv6) {
p.debug("MatchIpv6");
return fromExpr(_enc.mkFalse());
}
if (expr instanceof Conjunction) {
p.debug("Conjunction");
Conjunction c = (Conjunction) expr;
BoolExpr acc = _enc.mkTrue();
TransferResult<BoolExpr, BoolExpr> result = new TransferResult<>();
for (BooleanExpr be : c.getConjuncts()) {
TransferResult<BoolExpr, BoolExpr> r = compute(be, p.indent());
result = result.addChangedVariables(r);
acc = _enc.mkAnd(acc, r.getReturnValue());
}
p.debug("has changed variable");
return result.setReturnValue(acc);
}
if (expr instanceof Disjunction) {
p.debug("Disjunction");
Disjunction d = (Disjunction) expr;
BoolExpr acc = _enc.mkFalse();
TransferResult<BoolExpr, BoolExpr> result = new TransferResult<>();
for (BooleanExpr be : d.getDisjuncts()) {
TransferResult<BoolExpr, BoolExpr> r = compute(be, p.indent());
result = result.addChangedVariables(r);
acc = _enc.mkOr(acc, r.getReturnValue());
}
p.debug("has changed variable");
return result.setReturnValue(acc);
}
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) {
return fromExpr(_enc.mkTrue());
} else {
TransferResult<BoolExpr, BoolExpr> result = new TransferResult<>();
BoolExpr acc = _enc.mkFalse();
for (int i = conjuncts.size() - 1; i >= 0; i--) {
BooleanExpr conjunct = conjuncts.get(i);
TransferParam<SymbolicRoute> param = p.setDefaultPolicy(null).setChainContext(TransferParam.ChainContext.CONJUNCTION);
TransferResult<BoolExpr, BoolExpr> r = compute(conjunct, param);
result = result.addChangedVariables(r);
acc = _enc.mkIf(r.getFallthroughValue(), acc, r.getReturnValue());
}
p.debug("ConjunctionChain Result: " + acc);
return result.setReturnValue(acc);
}
}
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) {
return fromExpr(_enc.mkTrue());
} else {
TransferResult<BoolExpr, BoolExpr> result = new TransferResult<>();
BoolExpr acc = _enc.mkFalse();
for (int i = disjuncts.size() - 1; i >= 0; i--) {
BooleanExpr disjunct = disjuncts.get(i);
TransferParam<SymbolicRoute> param = p.setDefaultPolicy(null).setChainContext(TransferParam.ChainContext.CONJUNCTION);
TransferResult<BoolExpr, BoolExpr> r = compute(disjunct, param);
result.addChangedVariables(r);
acc = _enc.mkIf(r.getFallthroughValue(), acc, r.getReturnValue());
}
p.debug("DisjunctionChain Result: " + acc);
return result.setReturnValue(acc);
}
}
if (expr instanceof Not) {
p.debug("mkNot");
Not n = (Not) expr;
TransferResult<BoolExpr, BoolExpr> result = compute(n.getExpr(), p);
return result.setReturnValue(_enc.mkNot(result.getReturnValue()));
}
if (expr instanceof MatchProtocol) {
MatchProtocol mp = (MatchProtocol) expr;
Protocol proto = Protocol.fromRoutingProtocol(mp.getProtocol());
if (proto == null) {
p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): false");
return fromExpr(_enc.mkFalse());
}
if (_other.getProtocolHistory() == null) {
BoolExpr protoMatch = _enc.mkBool(proto.equals(_proto));
p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): " + protoMatch);
return fromExpr(protoMatch);
}
BoolExpr protoMatch = _other.getProtocolHistory().checkIfValue(proto);
p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): " + protoMatch);
return fromExpr(protoMatch);
}
if (expr instanceof MatchPrefixSet) {
p.debug("MatchPrefixSet");
MatchPrefixSet m = (MatchPrefixSet) expr;
// For BGP, may change prefix length
TransferResult<BoolExpr, BoolExpr> result = matchPrefixSet(_conf, m.getPrefixSet(), p.getData());
return result.setReturnAssignedValue(_enc.mkTrue());
// TODO: implement me
} else if (expr instanceof MatchPrefix6Set) {
p.debug("MatchPrefix6Set");
return fromExpr(_enc.mkFalse());
} else if (expr instanceof CallExpr) {
p.debug("CallExpr");
// TODO: the call can modify certain fields, need to keep track of these variables
CallExpr c = (CallExpr) expr;
String name = c.getCalledPolicyName();
RoutingPolicy pol = _conf.getRoutingPolicies().get(name);
p = p.setCallContext(TransferParam.CallContext.EXPR_CALL);
TransferResult<BoolExpr, BoolExpr> r = compute(pol.getStatements(), p.indent().enterScope(name), initialResult());
p.debug("CallExpr (return): " + r.getReturnValue());
p.debug("CallExpr (fallthrough): " + r.getFallthroughValue());
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);
} else if (expr instanceof MatchCommunitySet) {
p.debug("MatchCommunitySet");
MatchCommunitySet mcs = (MatchCommunitySet) expr;
return fromExpr(matchCommunitySet(_conf, mcs.getExpr(), p.getData()));
} else if (expr instanceof BooleanExprs.StaticBooleanExpr) {
BooleanExprs.StaticBooleanExpr b = (BooleanExprs.StaticBooleanExpr) expr;
switch(b.getType()) {
case CallExprContext:
p.debug("CallExprContext");
return fromExpr(_enc.mkBool(p.getCallContext() == TransferParam.CallContext.EXPR_CALL));
case CallStatementContext:
p.debug("CallStmtContext");
return fromExpr(_enc.mkBool(p.getCallContext() == TransferParam.CallContext.STMT_CALL));
case True:
p.debug("True");
return fromExpr(_enc.mkTrue());
case False:
p.debug("False");
return fromExpr(_enc.mkFalse());
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");
return fromExpr(_enc.mkFalse());
}
String s = (_isExport ? "export" : "import");
String msg = String.format("Unimplemented feature %s for %s transfer function on interface %s", expr.toString(), s, _graphEdge.toString());
throw new BatfishException(msg);
}
Aggregations