Search in sources :

Example 1 with SetMetric

use of org.batfish.datamodel.routing_policy.statement.SetMetric in project batfish by batfish.

the class CiscoConfiguration method toOspfProcess.

private org.batfish.datamodel.OspfProcess toOspfProcess(OspfProcess proc, String vrfName, Configuration c, CiscoConfiguration oldConfig) {
    org.batfish.datamodel.OspfProcess newProcess = new org.batfish.datamodel.OspfProcess();
    org.batfish.datamodel.Vrf vrf = c.getVrfs().get(vrfName);
    if (proc.getMaxMetricRouterLsa()) {
        newProcess.setMaxMetricTransitLinks(OspfProcess.MAX_METRIC_ROUTER_LSA);
        if (proc.getMaxMetricIncludeStub()) {
            newProcess.setMaxMetricStubNetworks(OspfProcess.MAX_METRIC_ROUTER_LSA);
        }
        newProcess.setMaxMetricExternalNetworks(proc.getMaxMetricExternalLsa());
        newProcess.setMaxMetricSummaryNetworks(proc.getMaxMetricSummaryLsa());
    }
    newProcess.setProcessId(proc.getName());
    // establish areas and associated interfaces
    Map<Long, OspfArea> areas = newProcess.getAreas();
    Map<Long, ImmutableSortedSet.Builder<String>> areaInterfacesBuilders = new HashMap<>();
    List<OspfNetwork> networks = new ArrayList<>();
    networks.addAll(proc.getNetworks());
    Collections.sort(networks, new Comparator<OspfNetwork>() {

        // sort so longest prefixes are first
        @Override
        public int compare(OspfNetwork lhs, OspfNetwork rhs) {
            int lhsPrefixLength = lhs.getPrefix().getPrefixLength();
            int rhsPrefixLength = rhs.getPrefix().getPrefixLength();
            // intentionally swapped
            int result = Integer.compare(rhsPrefixLength, lhsPrefixLength);
            if (result == 0) {
                long lhsIp = lhs.getPrefix().getStartIp().asLong();
                long rhsIp = rhs.getPrefix().getStartIp().asLong();
                result = Long.compare(lhsIp, rhsIp);
            }
            return result;
        }
    });
    // Set RFC 1583 compatibility
    newProcess.setRfc1583Compatible(proc.getRfc1583Compatible());
    for (Entry<String, org.batfish.datamodel.Interface> e : vrf.getInterfaces().entrySet()) {
        String ifaceName = e.getKey();
        org.batfish.datamodel.Interface iface = e.getValue();
        InterfaceAddress interfaceAddress = iface.getAddress();
        if (interfaceAddress == null) {
            continue;
        }
        for (OspfNetwork network : networks) {
            Prefix networkPrefix = network.getPrefix();
            Ip networkAddress = networkPrefix.getStartIp();
            Ip maskedInterfaceAddress = interfaceAddress.getIp().getNetworkAddress(networkPrefix.getPrefixLength());
            if (maskedInterfaceAddress.equals(networkAddress)) {
                // we have a longest prefix match
                long areaNum = network.getArea();
                OspfArea newArea = areas.computeIfAbsent(areaNum, OspfArea::new);
                ImmutableSortedSet.Builder<String> newAreaInterfacesBuilder = areaInterfacesBuilders.computeIfAbsent(areaNum, n -> ImmutableSortedSet.naturalOrder());
                newAreaInterfacesBuilder.add(ifaceName);
                iface.setOspfArea(newArea);
                iface.setOspfEnabled(true);
                boolean passive = proc.getPassiveInterfaceList().contains(iface.getName()) || (proc.getPassiveInterfaceDefault() && !proc.getActiveInterfaceList().contains(iface.getName()));
                iface.setOspfPassive(passive);
                break;
            }
        }
        areaInterfacesBuilders.forEach((areaNum, interfacesBuilder) -> areas.get(areaNum).setInterfaces(interfacesBuilder.build()));
    }
    // create summarization filters for inter-area routes
    for (Entry<Long, Map<Prefix, OspfAreaSummary>> e1 : proc.getSummaries().entrySet()) {
        long areaLong = e1.getKey();
        Map<Prefix, OspfAreaSummary> summaries = e1.getValue();
        OspfArea area = areas.get(areaLong);
        String summaryFilterName = "~OSPF_SUMMARY_FILTER:" + vrfName + ":" + areaLong + "~";
        RouteFilterList summaryFilter = new RouteFilterList(summaryFilterName);
        c.getRouteFilterLists().put(summaryFilterName, summaryFilter);
        if (area == null) {
            area = new OspfArea(areaLong);
            areas.put(areaLong, area);
        }
        area.setSummaryFilter(summaryFilterName);
        for (Entry<Prefix, OspfAreaSummary> e2 : summaries.entrySet()) {
            Prefix prefix = e2.getKey();
            OspfAreaSummary summary = e2.getValue();
            int prefixLength = prefix.getPrefixLength();
            int filterMinPrefixLength = summary.getAdvertised() ? Math.min(Prefix.MAX_PREFIX_LENGTH, prefixLength + 1) : prefixLength;
            summaryFilter.addLine(new RouteFilterLine(LineAction.REJECT, prefix, new SubRange(filterMinPrefixLength, Prefix.MAX_PREFIX_LENGTH)));
        }
        area.setSummaries(ImmutableSortedMap.copyOf(summaries));
        summaryFilter.addLine(new RouteFilterLine(LineAction.ACCEPT, Prefix.ZERO, new SubRange(0, Prefix.MAX_PREFIX_LENGTH)));
    }
    String ospfExportPolicyName = "~OSPF_EXPORT_POLICY:" + vrfName + "~";
    RoutingPolicy ospfExportPolicy = new RoutingPolicy(ospfExportPolicyName, c);
    c.getRoutingPolicies().put(ospfExportPolicyName, ospfExportPolicy);
    List<Statement> ospfExportStatements = ospfExportPolicy.getStatements();
    newProcess.setExportPolicy(ospfExportPolicyName);
    // policy map for default information
    if (proc.getDefaultInformationOriginate()) {
        If ospfExportDefault = new If();
        ospfExportStatements.add(ospfExportDefault);
        ospfExportDefault.setComment("OSPF export default route");
        Conjunction ospfExportDefaultConditions = new Conjunction();
        List<Statement> ospfExportDefaultStatements = ospfExportDefault.getTrueStatements();
        ospfExportDefaultConditions.getConjuncts().add(new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(new PrefixSpace(Collections.singleton(new PrefixRange(Prefix.ZERO, new SubRange(0, 0)))))));
        long metric = proc.getDefaultInformationMetric();
        ospfExportDefaultStatements.add(new SetMetric(new LiteralLong(metric)));
        OspfMetricType metricType = proc.getDefaultInformationMetricType();
        ospfExportDefaultStatements.add(new SetOspfMetricType(metricType));
        // add default export map with metric
        String defaultOriginateMapName = proc.getDefaultInformationOriginateMap();
        boolean useAggregateDefaultOnly;
        if (defaultOriginateMapName != null) {
            int defaultOriginateMapLine = proc.getDefaultInformationOriginateMapLine();
            useAggregateDefaultOnly = true;
            RoutingPolicy ospfDefaultGenerationPolicy = c.getRoutingPolicies().get(defaultOriginateMapName);
            if (ospfDefaultGenerationPolicy == null) {
                undefined(CiscoStructureType.ROUTE_MAP, defaultOriginateMapName, CiscoStructureUsage.OSPF_DEFAULT_ORIGINATE_ROUTE_MAP, defaultOriginateMapLine);
            } else {
                RouteMap generationRouteMap = _routeMaps.get(defaultOriginateMapName);
                generationRouteMap.getReferers().put(proc, "ospf 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 if (proc.getDefaultInformationOriginateAlways()) {
            useAggregateDefaultOnly = true;
            // 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());
        } else {
            // do not generate an aggregate default route;
            // just redistribute any existing default route with the new metric
            useAggregateDefaultOnly = false;
        }
        if (useAggregateDefaultOnly) {
            ospfExportDefaultConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.AGGREGATE));
        }
        ospfExportDefaultStatements.add(Statements.ExitAccept.toStaticStatement());
        ospfExportDefault.setGuard(ospfExportDefaultConditions);
    }
    // policy for redistributing connected routes
    // TODO: honor subnets option
    OspfRedistributionPolicy rcp = proc.getRedistributionPolicies().get(RoutingProtocol.CONNECTED);
    if (rcp != null) {
        If ospfExportConnected = new If();
        ospfExportConnected.setComment("OSPF export connected routes");
        Conjunction ospfExportConnectedConditions = new Conjunction();
        ospfExportConnectedConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.CONNECTED));
        List<Statement> ospfExportConnectedStatements = ospfExportConnected.getTrueStatements();
        Long metric = rcp.getMetric();
        OspfMetricType metricType = rcp.getMetricType();
        ospfExportConnectedStatements.add(new SetOspfMetricType(metricType));
        boolean explicitMetric = metric != null;
        if (!explicitMetric) {
            metric = proc.getDefaultMetric(_vendor, RoutingProtocol.CONNECTED);
        }
        ospfExportStatements.add(new SetMetric(new LiteralLong(metric)));
        ospfExportStatements.add(ospfExportConnected);
        // 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.OSPF_REDISTRIBUTE_CONNECTED_MAP, exportConnectedRouteMapLine);
            } else {
                exportConnectedRouteMap.getReferers().put(proc, "ospf redistribute connected route-map");
                ospfExportConnectedConditions.getConjuncts().add(new CallExpr(exportConnectedRouteMapName));
            }
        }
        ospfExportConnectedStatements.add(Statements.ExitAccept.toStaticStatement());
        ospfExportConnected.setGuard(ospfExportConnectedConditions);
    }
    // policy map for redistributing static routes
    // TODO: honor subnets option
    OspfRedistributionPolicy rsp = proc.getRedistributionPolicies().get(RoutingProtocol.STATIC);
    if (rsp != null) {
        If ospfExportStatic = new If();
        ospfExportStatic.setComment("OSPF export static routes");
        Conjunction ospfExportStaticConditions = new Conjunction();
        ospfExportStaticConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.STATIC));
        List<Statement> ospfExportStaticStatements = ospfExportStatic.getTrueStatements();
        ospfExportStaticConditions.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();
        OspfMetricType metricType = rsp.getMetricType();
        ospfExportStaticStatements.add(new SetOspfMetricType(metricType));
        boolean explicitMetric = metric != null;
        if (!explicitMetric) {
            metric = proc.getDefaultMetric(_vendor, RoutingProtocol.STATIC);
        }
        ospfExportStatements.add(new SetMetric(new LiteralLong(metric)));
        ospfExportStatements.add(ospfExportStatic);
        // 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.OSPF_REDISTRIBUTE_STATIC_MAP, exportStaticRouteMapLine);
            } else {
                exportStaticRouteMap.getReferers().put(proc, "ospf redistribute static route-map");
                ospfExportStaticConditions.getConjuncts().add(new CallExpr(exportStaticRouteMapName));
            }
        }
        ospfExportStaticStatements.add(Statements.ExitAccept.toStaticStatement());
        ospfExportStatic.setGuard(ospfExportStaticConditions);
    }
    // policy map for redistributing bgp routes
    // TODO: honor subnets option
    OspfRedistributionPolicy rbp = proc.getRedistributionPolicies().get(RoutingProtocol.BGP);
    if (rbp != null) {
        If ospfExportBgp = new If();
        ospfExportBgp.setComment("OSPF export bgp routes");
        Conjunction ospfExportBgpConditions = new Conjunction();
        ospfExportBgpConditions.getConjuncts().add(new MatchProtocol(RoutingProtocol.BGP));
        List<Statement> ospfExportBgpStatements = ospfExportBgp.getTrueStatements();
        ospfExportBgpConditions.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();
        OspfMetricType metricType = rbp.getMetricType();
        ospfExportBgpStatements.add(new SetOspfMetricType(metricType));
        boolean explicitMetric = metric != null;
        if (!explicitMetric) {
            metric = proc.getDefaultMetric(_vendor, RoutingProtocol.BGP);
        }
        ospfExportStatements.add(new SetMetric(new LiteralLong(metric)));
        ospfExportStatements.add(ospfExportBgp);
        // 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.OSPF_REDISTRIBUTE_BGP_MAP, exportBgpRouteMapLine);
            } else {
                exportBgpRouteMap.getReferers().put(proc, "ospf redistribute bgp route-map");
                ospfExportBgpConditions.getConjuncts().add(new CallExpr(exportBgpRouteMapName));
            }
        }
        ospfExportBgpStatements.add(Statements.ExitAccept.toStaticStatement());
        ospfExportBgp.setGuard(ospfExportBgpConditions);
    }
    newProcess.setReferenceBandwidth(proc.getReferenceBandwidth());
    Ip routerId = proc.getRouterId();
    if (routerId == null) {
        Map<String, Interface> interfacesToCheck;
        Map<String, Interface> allInterfaces = oldConfig.getInterfaces();
        Map<String, Interface> loopbackInterfaces = new HashMap<>();
        for (Entry<String, Interface> e : allInterfaces.entrySet()) {
            String ifaceName = e.getKey();
            Interface iface = e.getValue();
            if (ifaceName.toLowerCase().startsWith("loopback") && iface.getActive() && iface.getAddress() != null) {
                loopbackInterfaces.put(ifaceName, iface);
            }
        }
        if (loopbackInterfaces.isEmpty()) {
            interfacesToCheck = allInterfaces;
        } else {
            interfacesToCheck = loopbackInterfaces;
        }
        Ip highestIp = Ip.ZERO;
        for (Interface iface : interfacesToCheck.values()) {
            if (!iface.getActive()) {
                continue;
            }
            for (InterfaceAddress address : iface.getAllAddresses()) {
                Ip ip = address.getIp();
                if (highestIp.asLong() < ip.asLong()) {
                    highestIp = ip;
                }
            }
        }
        if (highestIp == Ip.ZERO) {
            _w.redFlag("No candidates for OSPF router-id");
            return null;
        }
        routerId = highestIp;
    }
    newProcess.setRouterId(routerId);
    return newProcess;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SetMetric(org.batfish.datamodel.routing_policy.statement.SetMetric) CallExpr(org.batfish.datamodel.routing_policy.expr.CallExpr) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) PrefixSpace(org.batfish.datamodel.PrefixSpace) LiteralLong(org.batfish.datamodel.routing_policy.expr.LiteralLong) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) Not(org.batfish.datamodel.routing_policy.expr.Not) ExplicitPrefixSet(org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet) OspfMetricType(org.batfish.datamodel.OspfMetricType) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) LiteralLong(org.batfish.datamodel.routing_policy.expr.LiteralLong) GeneratedRoute(org.batfish.datamodel.GeneratedRoute) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) TreeMap(java.util.TreeMap) ImmutableMap(com.google.common.collect.ImmutableMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) If(org.batfish.datamodel.routing_policy.statement.If) Ip(org.batfish.datamodel.Ip) Prefix(org.batfish.datamodel.Prefix) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) Conjunction(org.batfish.datamodel.routing_policy.expr.Conjunction) SubRange(org.batfish.datamodel.SubRange) RouteFilterLine(org.batfish.datamodel.RouteFilterLine) PrefixRange(org.batfish.datamodel.PrefixRange) OspfArea(org.batfish.datamodel.OspfArea) CallStatement(org.batfish.datamodel.routing_policy.statement.CallStatement) Statement(org.batfish.datamodel.routing_policy.statement.Statement) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) DestinationNetwork(org.batfish.datamodel.routing_policy.expr.DestinationNetwork) RouteFilterList(org.batfish.datamodel.RouteFilterList) OspfAreaSummary(org.batfish.datamodel.OspfAreaSummary) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType)

Example 2 with SetMetric

use of org.batfish.datamodel.routing_policy.statement.SetMetric in project batfish by batfish.

the class TransferBDD method compute.

/*
   * Convert a list of statements into a Z3 boolean expression for the transfer function.
   */
private TransferResult<TransferReturn, BDD> compute(List<Statement> statements, TransferParam<BDDRoute> p) {
    boolean doesReturn = false;
    TransferResult<TransferReturn, BDD> result = new TransferResult<>();
    result = result.setReturnValue(new TransferReturn(p.getData(), factory.zero())).setFallthroughValue(factory.zero()).setReturnAssignedValue(factory.zero());
    for (Statement stmt : statements) {
        if (stmt instanceof StaticStatement) {
            StaticStatement ss = (StaticStatement) stmt;
            switch(ss.getType()) {
                case ExitAccept:
                    doesReturn = true;
                    p.debug("ExitAccept");
                    result = returnValue(result, true);
                    break;
                case ReturnTrue:
                    doesReturn = true;
                    p.debug("ReturnTrue");
                    result = returnValue(result, true);
                    break;
                case ExitReject:
                    doesReturn = true;
                    p.debug("ExitReject");
                    result = returnValue(result, false);
                    break;
                case ReturnFalse:
                    doesReturn = true;
                    p.debug("ReturnFalse");
                    result = returnValue(result, false);
                    break;
                case SetDefaultActionAccept:
                    p.debug("SetDefaulActionAccept");
                    p = p.setDefaultAccept(true);
                    break;
                case SetDefaultActionReject:
                    p.debug("SetDefaultActionReject");
                    p = p.setDefaultAccept(false);
                    break;
                case SetLocalDefaultActionAccept:
                    p.debug("SetLocalDefaultActionAccept");
                    p = p.setDefaultAcceptLocal(true);
                    break;
                case SetLocalDefaultActionReject:
                    p.debug("SetLocalDefaultActionReject");
                    p = p.setDefaultAcceptLocal(false);
                    break;
                case ReturnLocalDefaultAction:
                    p.debug("ReturnLocalDefaultAction");
                    // TODO: need to set local default action in an environment
                    if (p.getDefaultAcceptLocal()) {
                        result = returnValue(result, true);
                    } else {
                        result = returnValue(result, false);
                    }
                    break;
                case FallThrough:
                    p.debug("Fallthrough");
                    result = fallthrough(result);
                    break;
                case Return:
                    // TODO: assumming this happens at the end of the function, so it is ignored for now.
                    p.debug("Return");
                    break;
                case RemovePrivateAs:
                    p.debug("RemovePrivateAs");
                    // System.out.println("Warning: use of unimplemented feature RemovePrivateAs");
                    break;
                default:
                    throw new BatfishException("TODO: computeTransferFunction: " + ss.getType());
            }
        } else if (stmt instanceof If) {
            p.debug("If");
            If i = (If) stmt;
            TransferResult<TransferReturn, BDD> r = compute(i.getGuard(), p.indent());
            BDD guard = r.getReturnValue().getSecond();
            p.debug("guard: ");
            BDDRoute current = result.getReturnValue().getFirst();
            TransferParam<BDDRoute> pTrue = p.indent().setData(current.deepCopy());
            TransferParam<BDDRoute> pFalse = p.indent().setData(current.deepCopy());
            p.debug("True Branch");
            TransferResult<TransferReturn, BDD> trueBranch = compute(i.getTrueStatements(), pTrue);
            p.debug("True Branch: " + trueBranch.getReturnValue().getFirst().hashCode());
            p.debug("False Branch");
            TransferResult<TransferReturn, BDD> falseBranch = compute(i.getFalseStatements(), pFalse);
            p.debug("False Branch: " + trueBranch.getReturnValue().getFirst().hashCode());
            BDDRoute r1 = trueBranch.getReturnValue().getFirst();
            BDDRoute r2 = falseBranch.getReturnValue().getFirst();
            BDDRoute recordVal = ite(guard, r1, r2);
            // update return values
            BDD returnVal = ite(guard, trueBranch.getReturnValue().getSecond(), falseBranch.getReturnValue().getSecond());
            // p.debug("New Return Value (neg): " + returnVal.not());
            BDD returnAss = ite(guard, trueBranch.getReturnAssignedValue(), falseBranch.getReturnAssignedValue());
            // p.debug("New Return Assigned: " + returnAss);
            BDD fallThrough = ite(guard, trueBranch.getFallthroughValue(), falseBranch.getFallthroughValue());
            // p.debug("New fallthrough: " + fallThrough);
            result = result.setReturnValue(new TransferReturn(recordVal, returnVal)).setReturnAssignedValue(returnAss).setFallthroughValue(fallThrough);
            p.debug("If return: " + result.getReturnValue().getFirst().hashCode());
        } else if (stmt instanceof SetDefaultPolicy) {
            p.debug("SetDefaultPolicy");
            p = p.setDefaultPolicy((SetDefaultPolicy) stmt);
        } else if (stmt instanceof SetMetric) {
            p.debug("SetMetric");
            SetMetric sm = (SetMetric) stmt;
            LongExpr ie = sm.getMetric();
            BDD isBGP = p.getData().getProtocolHistory().value(Protocol.BGP);
            BDD updateMed = isBGP.and(result.getReturnAssignedValue());
            BDD updateMet = isBGP.not().and(result.getReturnAssignedValue());
            BDDInteger newValue = applyLongExprModification(p.indent(), p.getData().getMetric(), ie);
            BDDInteger med = ite(updateMed, p.getData().getMed(), newValue);
            BDDInteger met = ite(updateMet, p.getData().getMetric(), newValue);
            p.getData().setMetric(met);
            p.getData().setMetric(med);
        } else if (stmt instanceof SetOspfMetricType) {
            p.debug("SetOspfMetricType");
            SetOspfMetricType somt = (SetOspfMetricType) stmt;
            OspfMetricType mt = somt.getMetricType();
            BDDDomain<OspfType> current = result.getReturnValue().getFirst().getOspfMetric();
            BDDDomain<OspfType> newValue = new BDDDomain<>(current);
            if (mt == OspfMetricType.E1) {
                p.indent().debug("Value: E1");
                newValue.setValue(OspfType.E1);
            } else {
                p.indent().debug("Value: E2");
                newValue.setValue(OspfType.E1);
            }
            newValue = ite(result.getReturnAssignedValue(), p.getData().getOspfMetric(), newValue);
            p.getData().setOspfMetric(newValue);
        } else if (stmt instanceof SetLocalPreference) {
            p.debug("SetLocalPreference");
            SetLocalPreference slp = (SetLocalPreference) stmt;
            IntExpr ie = slp.getLocalPreference();
            BDDInteger newValue = applyIntExprModification(p.indent(), p.getData().getLocalPref(), ie);
            newValue = ite(result.getReturnAssignedValue(), p.getData().getLocalPref(), newValue);
            p.getData().setLocalPref(newValue);
        } else if (stmt instanceof AddCommunity) {
            p.debug("AddCommunity");
            AddCommunity ac = (AddCommunity) stmt;
            Set<CommunityVar> comms = _graph.findAllCommunities(_conf, ac.getExpr());
            for (CommunityVar cvar : comms) {
                if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
                    p.indent().debug("Value: " + cvar);
                    BDD comm = p.getData().getCommunities().get(cvar);
                    BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.one());
                    p.indent().debug("New Value: " + newValue);
                    p.getData().getCommunities().put(cvar, newValue);
                }
            }
        } else if (stmt instanceof SetCommunity) {
            p.debug("SetCommunity");
            SetCommunity sc = (SetCommunity) stmt;
            Set<CommunityVar> comms = _graph.findAllCommunities(_conf, sc.getExpr());
            for (CommunityVar cvar : comms) {
                if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
                    p.indent().debug("Value: " + cvar);
                    BDD comm = p.getData().getCommunities().get(cvar);
                    BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.one());
                    p.indent().debug("New Value: " + newValue);
                    p.getData().getCommunities().put(cvar, newValue);
                }
            }
        } else if (stmt instanceof DeleteCommunity) {
            p.debug("DeleteCommunity");
            DeleteCommunity ac = (DeleteCommunity) stmt;
            Set<CommunityVar> comms = _graph.findAllCommunities(_conf, ac.getExpr());
            Set<CommunityVar> toDelete = new HashSet<>();
            // Find comms to delete
            for (CommunityVar cvar : comms) {
                if (cvar.getType() == Type.REGEX) {
                    toDelete.addAll(_commDeps.get(cvar));
                } else {
                    toDelete.add(cvar);
                }
            }
            // Delete the comms
            for (CommunityVar cvar : toDelete) {
                if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
                    p.indent().debug("Value: " + cvar.getValue() + ", " + cvar.getType());
                    BDD comm = p.getData().getCommunities().get(cvar);
                    BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.zero());
                    p.indent().debug("New Value: " + newValue);
                    p.getData().getCommunities().put(cvar, newValue);
                }
            }
        } else if (stmt instanceof RetainCommunity) {
            p.debug("RetainCommunity");
        // no op
        } else if (stmt instanceof PrependAsPath) {
            p.debug("PrependAsPath");
            PrependAsPath pap = (PrependAsPath) stmt;
            Integer prependCost = prependLength(pap.getExpr());
            p.indent().debug("Cost: " + prependCost);
            BDDInteger met = p.getData().getMetric();
            BDDInteger newValue = met.add(BDDInteger.makeFromValue(met.getFactory(), 32, prependCost));
            newValue = ite(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
            p.getData().setMetric(newValue);
        } else if (stmt instanceof SetOrigin) {
            p.debug("SetOrigin");
        // System.out.println("Warning: use of unimplemented feature SetOrigin");
        // TODO: implement me
        } else if (stmt instanceof SetNextHop) {
            p.debug("SetNextHop");
        // System.out.println("Warning: use of unimplemented feature SetNextHop");
        // TODO: implement me
        } else {
            throw new BatfishException("TODO: statement transfer function: " + stmt);
        }
    }
    // If this is the outermost call, then we relate the variables
    if (p.getInitialCall()) {
        p.debug("InitialCall finalizing");
        // Apply the default action
        if (!doesReturn) {
            p.debug("Applying default action: " + p.getDefaultAccept());
            if (p.getDefaultAccept()) {
                result = returnValue(result, true);
            } else {
                result = returnValue(result, false);
            }
        }
        // Set all the values to 0 if the return is not true;
        TransferReturn ret = result.getReturnValue();
        BDDRoute retVal = ite(ret.getSecond(), ret.getFirst(), zeroedRecord());
        result = result.setReturnValue(new TransferReturn(retVal, ret.getSecond()));
    }
    return result;
}
Also used : BDD(net.sf.javabdd.BDD) MatchCommunitySet(org.batfish.datamodel.routing_policy.expr.MatchCommunitySet) MatchPrefix6Set(org.batfish.datamodel.routing_policy.expr.MatchPrefix6Set) InlineCommunitySet(org.batfish.datamodel.routing_policy.expr.InlineCommunitySet) Set(java.util.Set) NamedPrefixSet(org.batfish.datamodel.routing_policy.expr.NamedPrefixSet) HashSet(java.util.HashSet) ExplicitPrefixSet(org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) NamedCommunitySet(org.batfish.datamodel.routing_policy.expr.NamedCommunitySet) TransferResult(org.batfish.symbolic.TransferResult) RetainCommunity(org.batfish.datamodel.routing_policy.statement.RetainCommunity) SetMetric(org.batfish.datamodel.routing_policy.statement.SetMetric) SetCommunity(org.batfish.datamodel.routing_policy.statement.SetCommunity) OspfType(org.batfish.symbolic.OspfType) SetNextHop(org.batfish.datamodel.routing_policy.statement.SetNextHop) LongExpr(org.batfish.datamodel.routing_policy.expr.LongExpr) HashSet(java.util.HashSet) BatfishException(org.batfish.common.BatfishException) StaticStatement(org.batfish.datamodel.routing_policy.statement.Statements.StaticStatement) Statement(org.batfish.datamodel.routing_policy.statement.Statement) StaticStatement(org.batfish.datamodel.routing_policy.statement.Statements.StaticStatement) SetOrigin(org.batfish.datamodel.routing_policy.statement.SetOrigin) DeleteCommunity(org.batfish.datamodel.routing_policy.statement.DeleteCommunity) SetDefaultPolicy(org.batfish.datamodel.routing_policy.statement.SetDefaultPolicy) AddCommunity(org.batfish.datamodel.routing_policy.statement.AddCommunity) CommunityVar(org.batfish.symbolic.CommunityVar) OspfMetricType(org.batfish.datamodel.OspfMetricType) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) SetLocalPreference(org.batfish.datamodel.routing_policy.statement.SetLocalPreference) TransferParam(org.batfish.symbolic.TransferParam) PrependAsPath(org.batfish.datamodel.routing_policy.statement.PrependAsPath) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) IntExpr(org.batfish.datamodel.routing_policy.expr.IntExpr) If(org.batfish.datamodel.routing_policy.statement.If)

Example 3 with SetMetric

use of org.batfish.datamodel.routing_policy.statement.SetMetric 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;
}
Also used : Prefix(org.batfish.datamodel.Prefix) SetMetric(org.batfish.datamodel.routing_policy.statement.SetMetric) Conjunction(org.batfish.datamodel.routing_policy.expr.Conjunction) CallExpr(org.batfish.datamodel.routing_policy.expr.CallExpr) SubRange(org.batfish.datamodel.SubRange) PrefixRange(org.batfish.datamodel.PrefixRange) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) CallStatement(org.batfish.datamodel.routing_policy.statement.CallStatement) Statement(org.batfish.datamodel.routing_policy.statement.Statement) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) PrefixSpace(org.batfish.datamodel.PrefixSpace) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) LiteralLong(org.batfish.datamodel.routing_policy.expr.LiteralLong) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) Not(org.batfish.datamodel.routing_policy.expr.Not) DestinationNetwork(org.batfish.datamodel.routing_policy.expr.DestinationNetwork) ExplicitPrefixSet(org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet) LiteralLong(org.batfish.datamodel.routing_policy.expr.LiteralLong) GeneratedRoute(org.batfish.datamodel.GeneratedRoute) If(org.batfish.datamodel.routing_policy.statement.If)

Example 4 with SetMetric

use of org.batfish.datamodel.routing_policy.statement.SetMetric in project batfish by batfish.

the class TransferSSA method compute.

/*
   * Convert a list of statements into a Z3 boolean expression for the transfer function.
   */
private TransferResult<BoolExpr, BoolExpr> compute(List<Statement> statements, TransferParam<SymbolicRoute> p, TransferResult<BoolExpr, BoolExpr> result) {
    boolean doesReturn = false;
    for (Statement stmt : statements) {
        if (stmt instanceof StaticStatement) {
            StaticStatement ss = (StaticStatement) stmt;
            switch(ss.getType()) {
                case ExitAccept:
                    doesReturn = true;
                    p.debug("ExitAccept");
                    result = returnValue(p, result, true);
                    break;
                case ReturnTrue:
                    doesReturn = true;
                    p.debug("ReturnTrue");
                    result = returnValue(p, result, true);
                    break;
                case ExitReject:
                    doesReturn = true;
                    p.debug("ExitReject");
                    result = returnValue(p, result, false);
                    break;
                case ReturnFalse:
                    doesReturn = true;
                    p.debug("ReturnFalse");
                    result = returnValue(p, result, false);
                    break;
                case SetDefaultActionAccept:
                    p.debug("SetDefaulActionAccept");
                    p = p.setDefaultAccept(true);
                    break;
                case SetDefaultActionReject:
                    p.debug("SetDefaultActionReject");
                    p = p.setDefaultAccept(false);
                    break;
                case SetLocalDefaultActionAccept:
                    p.debug("SetLocalDefaultActionAccept");
                    p = p.setDefaultAcceptLocal(true);
                    break;
                case SetLocalDefaultActionReject:
                    p.debug("SetLocalDefaultActionReject");
                    p = p.setDefaultAcceptLocal(false);
                    break;
                case ReturnLocalDefaultAction:
                    p.debug("ReturnLocalDefaultAction");
                    // TODO: need to set local default action in an environment
                    if (p.getDefaultAcceptLocal()) {
                        result = returnValue(p, result, true);
                    } else {
                        result = returnValue(p, result, false);
                    }
                    break;
                case FallThrough:
                    p.debug("Fallthrough");
                    result = fallthrough(p, result);
                    break;
                case Return:
                    // TODO: assumming this happens at the end of the function, so it is ignored for now.
                    p.debug("Return");
                    break;
                case RemovePrivateAs:
                    p.debug("RemovePrivateAs");
                    System.out.println("Warning: use of unimplemented feature RemovePrivateAs");
                    break;
                default:
                    throw new BatfishException("TODO: computeTransferFunction: " + ss.getType());
            }
        } else if (stmt instanceof If) {
            p.debug("If");
            If i = (If) stmt;
            TransferResult<BoolExpr, BoolExpr> r = compute(i.getGuard(), p);
            result = result.addChangedVariables(r);
            BoolExpr guard = (BoolExpr) r.getReturnValue().simplify();
            String str = guard.toString();
            // If there are updates in the guard, add them to the parameter p before entering branches
            for (Pair<String, Expr> changed : r.getChangedVariables()) {
                p.debug("CHANGED: " + changed.getFirst());
                updateSingleValue(p, changed.getFirst(), changed.getSecond());
            }
            p.debug("guard: " + str);
            // If we know the branch ahead of time, then specialize
            switch(str) {
                case "true":
                    p.debug("True Branch");
                    result = compute(i.getTrueStatements(), p.indent(), result);
                    break;
                case "false":
                    p.debug("False Branch");
                    compute(i.getFalseStatements(), p.indent(), result);
                    break;
                default:
                    p.debug("True Branch");
                    // clear changed variables before proceeding
                    TransferParam<SymbolicRoute> p1 = p.indent().setData(p.getData().copy());
                    TransferParam<SymbolicRoute> p2 = p.indent().setData(p.getData().copy());
                    TransferResult<BoolExpr, BoolExpr> trueBranch = compute(i.getTrueStatements(), p1, initialResult());
                    p.debug("False Branch");
                    TransferResult<BoolExpr, BoolExpr> falseBranch = compute(i.getFalseStatements(), p2, initialResult());
                    p.debug("JOIN");
                    PList<Pair<String, Pair<Expr, Expr>>> pairs = trueBranch.mergeChangedVariables(falseBranch);
                    // Extract and deal with the return value first so that other
                    // variables have this reflected in their value
                    int idx = pairs.find(pair -> pair.getFirst().equals("RETURN"));
                    if (idx >= 0) {
                        Pair<String, Pair<Expr, Expr>> ret = pairs.get(idx);
                        pairs = pairs.minus(idx);
                        pairs = pairs.plus(pairs.size(), ret);
                    }
                    for (Pair<String, Pair<Expr, Expr>> pair : pairs) {
                        String s = pair.getFirst();
                        p.debug("CHANGED: " + s);
                        Pair<Expr, Expr> x = joinPoint(p, result, guard, pair);
                        result = result.addChangedVariable(s, x.getFirst());
                        if (s.equals("RETURN")) {
                            result = result.setReturnValue((BoolExpr) x.getFirst()).setReturnAssignedValue((BoolExpr) x.getSecond());
                        }
                        if (s.equals("FALLTHROUGH")) {
                            result = result.setFallthroughValue((BoolExpr) x.getFirst()).setReturnAssignedValue((BoolExpr) x.getSecond());
                        }
                    }
                    break;
            }
        } else if (stmt instanceof SetDefaultPolicy) {
            p.debug("SetDefaultPolicy");
            p = p.setDefaultPolicy((SetDefaultPolicy) stmt);
        } else if (stmt instanceof SetMetric) {
            p.debug("SetMetric");
            // TODO: what is the semantics for BGP? Is this MED?
            if (!_current.getProto().isBgp()) {
                SetMetric sm = (SetMetric) stmt;
                LongExpr ie = sm.getMetric();
                ArithExpr newValue = applyLongExprModification(p.getData().getMetric(), ie);
                newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
                ArithExpr x = createArithVariableWith(p, "METRIC", newValue);
                p.getData().setMetric(x);
                result = result.addChangedVariable("METRIC", x);
            }
        } else if (stmt instanceof SetOspfMetricType) {
            p.debug("SetOspfMetricType");
            SetOspfMetricType somt = (SetOspfMetricType) stmt;
            OspfMetricType mt = somt.getMetricType();
            SymbolicOspfType t;
            if (mt == OspfMetricType.E1) {
                t = new SymbolicOspfType(_enc, OspfType.E1);
            } else {
                t = new SymbolicOspfType(_enc, OspfType.E2);
            }
            BitVecExpr newValue = t.getBitVec();
            newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getOspfType().getBitVec(), newValue);
            BitVecExpr x = createBitVecVariableWith(p, "OSPF-TYPE", 2, newValue);
            p.getData().getOspfType().setBitVec(x);
            result = result.addChangedVariable("OSPF-TYPE", x);
        } else if (stmt instanceof SetLocalPreference) {
            p.debug("SetLocalPreference");
            SetLocalPreference slp = (SetLocalPreference) stmt;
            IntExpr ie = slp.getLocalPreference();
            ArithExpr newValue = applyIntExprModification(p.getData().getLocalPref(), ie);
            newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getLocalPref(), newValue);
            ArithExpr x = createArithVariableWith(p, "LOCAL-PREF", newValue);
            p.getData().setLocalPref(x);
            result = result.addChangedVariable("LOCAL-PREF", x);
        } else if (stmt instanceof AddCommunity) {
            p.debug("AddCommunity");
            AddCommunity ac = (AddCommunity) stmt;
            Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, ac.getExpr());
            for (CommunityVar cvar : comms) {
                BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkTrue());
                BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
                p.getData().getCommunities().put(cvar, x);
                result = result.addChangedVariable(cvar.getValue(), x);
            }
        } else if (stmt instanceof SetCommunity) {
            p.debug("SetCommunity");
            SetCommunity sc = (SetCommunity) stmt;
            Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, sc.getExpr());
            for (CommunityVar cvar : comms) {
                BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkTrue());
                BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
                p.getData().getCommunities().put(cvar, x);
                result = result.addChangedVariable(cvar.getValue(), x);
            }
        } else if (stmt instanceof DeleteCommunity) {
            p.debug("DeleteCommunity");
            DeleteCommunity ac = (DeleteCommunity) stmt;
            Set<CommunityVar> comms = _enc.getGraph().findAllCommunities(_conf, ac.getExpr());
            Set<CommunityVar> toDelete = new HashSet<>();
            // Find comms to delete
            for (CommunityVar cvar : comms) {
                if (cvar.getType() == Type.REGEX) {
                    toDelete.addAll(_enc.getCommunityDependencies().get(cvar));
                } else {
                    toDelete.add(cvar);
                }
            }
            // Delete each community
            for (CommunityVar cvar : toDelete) {
                BoolExpr newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getCommunities().get(cvar), _enc.mkFalse());
                BoolExpr x = createBoolVariableWith(p, cvar.getValue(), newValue);
                p.getData().getCommunities().put(cvar, x);
                result = result.addChangedVariable(cvar.getValue(), x);
            }
        } else if (stmt instanceof RetainCommunity) {
            p.debug("RetainCommunity");
        // no op
        } else if (stmt instanceof PrependAsPath) {
            p.debug("PrependAsPath");
            PrependAsPath pap = (PrependAsPath) stmt;
            Integer prependCost = prependLength(pap.getExpr());
            ArithExpr newValue = _enc.mkSum(p.getData().getMetric(), _enc.mkInt(prependCost));
            newValue = _enc.mkIf(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
            ArithExpr x = createArithVariableWith(p, "METRIC", newValue);
            p.getData().setMetric(x);
            result = result.addChangedVariable("METRIC", x);
        } else if (stmt instanceof SetOrigin) {
            p.debug("SetOrigin");
            System.out.println("Warning: use of unimplemented feature SetOrigin");
        } else if (stmt instanceof SetNextHop) {
            p.debug("SetNextHop");
            System.out.println("Warning: use of unimplemented feature SetNextHop");
        } else {
            String s = (_isExport ? "export" : "import");
            String msg = String.format("Unimplemented feature %s for %s transfer function on interface %s", stmt.toString(), s, _graphEdge.toString());
            throw new BatfishException(msg);
        }
    }
    // If this is the outermost call, then we relate the variables
    if (p.getInitialCall()) {
        p.debug("InitialCall finalizing");
        // Apply the default action
        if (!doesReturn) {
            p.debug("Applying default action: " + p.getDefaultAccept());
            if (p.getDefaultAccept()) {
                result = returnValue(p, result, true);
            } else {
                result = returnValue(p, result, false);
            }
        }
        BoolExpr related = relateVariables(p, result);
        BoolExpr retValue = _enc.mkIf(result.getReturnValue(), related, _enc.mkNot(_current.getPermitted()));
        result = result.setReturnValue(retValue);
    }
    return result;
}
Also used : IncrementMetric(org.batfish.datamodel.routing_policy.expr.IncrementMetric) MatchAsPath(org.batfish.datamodel.routing_policy.expr.MatchAsPath) RetainCommunity(org.batfish.datamodel.routing_policy.statement.RetainCommunity) Not(org.batfish.datamodel.routing_policy.expr.Not) Disjunction(org.batfish.datamodel.routing_policy.expr.Disjunction) CommunityListLine(org.batfish.datamodel.CommunityListLine) RouteFilterList(org.batfish.datamodel.RouteFilterList) Interface(org.batfish.datamodel.Interface) Map(java.util.Map) AddCommunity(org.batfish.datamodel.routing_policy.statement.AddCommunity) MatchCommunitySet(org.batfish.datamodel.routing_policy.expr.MatchCommunitySet) DecrementLocalPreference(org.batfish.datamodel.routing_policy.expr.DecrementLocalPreference) Pair(org.batfish.common.Pair) MatchPrefix6Set(org.batfish.datamodel.routing_policy.expr.MatchPrefix6Set) Statement(org.batfish.datamodel.routing_policy.statement.Statement) Conjunction(org.batfish.datamodel.routing_policy.expr.Conjunction) InlineCommunitySet(org.batfish.datamodel.routing_policy.expr.InlineCommunitySet) DisjunctionChain(org.batfish.datamodel.routing_policy.expr.DisjunctionChain) Set(java.util.Set) IntExpr(org.batfish.datamodel.routing_policy.expr.IntExpr) CommunitySetExpr(org.batfish.datamodel.routing_policy.expr.CommunitySetExpr) StaticStatement(org.batfish.datamodel.routing_policy.statement.Statements.StaticStatement) Graph(org.batfish.symbolic.Graph) DeleteCommunity(org.batfish.datamodel.routing_policy.statement.DeleteCommunity) List(java.util.List) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) CallExpr(org.batfish.datamodel.routing_policy.expr.CallExpr) IncrementLocalPreference(org.batfish.datamodel.routing_policy.expr.IncrementLocalPreference) BooleanExprs(org.batfish.datamodel.routing_policy.expr.BooleanExprs) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) NamedPrefixSet(org.batfish.datamodel.routing_policy.expr.NamedPrefixSet) SetDefaultPolicy(org.batfish.datamodel.routing_policy.statement.SetDefaultPolicy) OspfMetricType(org.batfish.datamodel.OspfMetricType) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr) AsPathListExpr(org.batfish.datamodel.routing_policy.expr.AsPathListExpr) If(org.batfish.datamodel.routing_policy.statement.If) CommunityVar(org.batfish.symbolic.CommunityVar) HashMap(java.util.HashMap) DecrementMetric(org.batfish.datamodel.routing_policy.expr.DecrementMetric) BatfishException(org.batfish.common.BatfishException) LiteralInt(org.batfish.datamodel.routing_policy.expr.LiteralInt) SetNextHop(org.batfish.datamodel.routing_policy.statement.SetNextHop) ArrayList(java.util.ArrayList) SetOrigin(org.batfish.datamodel.routing_policy.statement.SetOrigin) HashSet(java.util.HashSet) LiteralLong(org.batfish.datamodel.routing_policy.expr.LiteralLong) CommunityList(org.batfish.datamodel.CommunityList) TransferResult(org.batfish.symbolic.TransferResult) RouteFilterLine(org.batfish.datamodel.RouteFilterLine) SubRange(org.batfish.datamodel.SubRange) Type(org.batfish.symbolic.CommunityVar.Type) BoolExpr(com.microsoft.z3.BoolExpr) Configuration(org.batfish.datamodel.Configuration) MatchIpv4(org.batfish.datamodel.routing_policy.expr.MatchIpv4) LineAction(org.batfish.datamodel.LineAction) ArithExpr(com.microsoft.z3.ArithExpr) MatchIpv6(org.batfish.datamodel.routing_policy.expr.MatchIpv6) WithEnvironmentExpr(org.batfish.datamodel.routing_policy.expr.WithEnvironmentExpr) ExplicitPrefixSet(org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet) PrefixRange(org.batfish.datamodel.PrefixRange) PrefixSetExpr(org.batfish.datamodel.routing_policy.expr.PrefixSetExpr) BitVecExpr(com.microsoft.z3.BitVecExpr) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) GraphEdge(org.batfish.symbolic.GraphEdge) SetCommunity(org.batfish.datamodel.routing_policy.statement.SetCommunity) NamedCommunitySet(org.batfish.datamodel.routing_policy.expr.NamedCommunitySet) PrependAsPath(org.batfish.datamodel.routing_policy.statement.PrependAsPath) TransferParam(org.batfish.symbolic.TransferParam) Expr(com.microsoft.z3.Expr) GeneratedRoute(org.batfish.datamodel.GeneratedRoute) MultipliedAs(org.batfish.datamodel.routing_policy.expr.MultipliedAs) OspfType(org.batfish.symbolic.OspfType) LongExpr(org.batfish.datamodel.routing_policy.expr.LongExpr) Protocol(org.batfish.symbolic.Protocol) SetLocalPreference(org.batfish.datamodel.routing_policy.statement.SetLocalPreference) Collections(java.util.Collections) ConjunctionChain(org.batfish.datamodel.routing_policy.expr.ConjunctionChain) LiteralAsList(org.batfish.datamodel.routing_policy.expr.LiteralAsList) SetMetric(org.batfish.datamodel.routing_policy.statement.SetMetric) Prefix(org.batfish.datamodel.Prefix) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) PList(org.batfish.symbolic.collections.PList) BoolExpr(com.microsoft.z3.BoolExpr) MatchCommunitySet(org.batfish.datamodel.routing_policy.expr.MatchCommunitySet) MatchPrefix6Set(org.batfish.datamodel.routing_policy.expr.MatchPrefix6Set) InlineCommunitySet(org.batfish.datamodel.routing_policy.expr.InlineCommunitySet) Set(java.util.Set) NamedPrefixSet(org.batfish.datamodel.routing_policy.expr.NamedPrefixSet) HashSet(java.util.HashSet) ExplicitPrefixSet(org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) NamedCommunitySet(org.batfish.datamodel.routing_policy.expr.NamedCommunitySet) PList(org.batfish.symbolic.collections.PList) TransferResult(org.batfish.symbolic.TransferResult) RetainCommunity(org.batfish.datamodel.routing_policy.statement.RetainCommunity) SetMetric(org.batfish.datamodel.routing_policy.statement.SetMetric) SetCommunity(org.batfish.datamodel.routing_policy.statement.SetCommunity) SetNextHop(org.batfish.datamodel.routing_policy.statement.SetNextHop) Pair(org.batfish.common.Pair) LongExpr(org.batfish.datamodel.routing_policy.expr.LongExpr) HashSet(java.util.HashSet) ArithExpr(com.microsoft.z3.ArithExpr) BatfishException(org.batfish.common.BatfishException) StaticStatement(org.batfish.datamodel.routing_policy.statement.Statements.StaticStatement) Statement(org.batfish.datamodel.routing_policy.statement.Statement) StaticStatement(org.batfish.datamodel.routing_policy.statement.Statements.StaticStatement) SetOrigin(org.batfish.datamodel.routing_policy.statement.SetOrigin) DeleteCommunity(org.batfish.datamodel.routing_policy.statement.DeleteCommunity) SetDefaultPolicy(org.batfish.datamodel.routing_policy.statement.SetDefaultPolicy) AddCommunity(org.batfish.datamodel.routing_policy.statement.AddCommunity) CommunityVar(org.batfish.symbolic.CommunityVar) BitVecExpr(com.microsoft.z3.BitVecExpr) IntExpr(org.batfish.datamodel.routing_policy.expr.IntExpr) CommunitySetExpr(org.batfish.datamodel.routing_policy.expr.CommunitySetExpr) CallExpr(org.batfish.datamodel.routing_policy.expr.CallExpr) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr) AsPathListExpr(org.batfish.datamodel.routing_policy.expr.AsPathListExpr) BoolExpr(com.microsoft.z3.BoolExpr) ArithExpr(com.microsoft.z3.ArithExpr) WithEnvironmentExpr(org.batfish.datamodel.routing_policy.expr.WithEnvironmentExpr) PrefixSetExpr(org.batfish.datamodel.routing_policy.expr.PrefixSetExpr) BitVecExpr(com.microsoft.z3.BitVecExpr) Expr(com.microsoft.z3.Expr) LongExpr(org.batfish.datamodel.routing_policy.expr.LongExpr) OspfMetricType(org.batfish.datamodel.OspfMetricType) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) SetLocalPreference(org.batfish.datamodel.routing_policy.statement.SetLocalPreference) TransferParam(org.batfish.symbolic.TransferParam) PrependAsPath(org.batfish.datamodel.routing_policy.statement.PrependAsPath) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) IntExpr(org.batfish.datamodel.routing_policy.expr.IntExpr) If(org.batfish.datamodel.routing_policy.statement.If)

Example 5 with SetMetric

use of org.batfish.datamodel.routing_policy.statement.SetMetric in project batfish by batfish.

the class OspfTest method getExportPolicyStatements.

private static List<Statement> getExportPolicyStatements(InterfaceAddress address) {
    long externalOspfMetric = 20L;
    If exportIfMatchL2Prefix = new If();
    exportIfMatchL2Prefix.setGuard(new MatchPrefixSet(new DestinationNetwork(), new ExplicitPrefixSet(new PrefixSpace(ImmutableSet.of(PrefixRange.fromPrefix(address.getPrefix()))))));
    exportIfMatchL2Prefix.setTrueStatements(ImmutableList.of(new SetOspfMetricType(OspfMetricType.E1), new SetMetric(new LiteralLong(externalOspfMetric)), Statements.ExitAccept.toStaticStatement()));
    exportIfMatchL2Prefix.setFalseStatements(ImmutableList.of(Statements.ExitReject.toStaticStatement()));
    return ImmutableList.of(exportIfMatchL2Prefix);
}
Also used : DestinationNetwork(org.batfish.datamodel.routing_policy.expr.DestinationNetwork) ExplicitPrefixSet(org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet) SetMetric(org.batfish.datamodel.routing_policy.statement.SetMetric) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) PrefixSpace(org.batfish.datamodel.PrefixSpace) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) LiteralLong(org.batfish.datamodel.routing_policy.expr.LiteralLong) If(org.batfish.datamodel.routing_policy.statement.If)

Aggregations

ExplicitPrefixSet (org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet)5 MatchPrefixSet (org.batfish.datamodel.routing_policy.expr.MatchPrefixSet)5 If (org.batfish.datamodel.routing_policy.statement.If)5 SetMetric (org.batfish.datamodel.routing_policy.statement.SetMetric)5 LiteralLong (org.batfish.datamodel.routing_policy.expr.LiteralLong)4 SetOspfMetricType (org.batfish.datamodel.routing_policy.statement.SetOspfMetricType)4 Statement (org.batfish.datamodel.routing_policy.statement.Statement)4 GeneratedRoute (org.batfish.datamodel.GeneratedRoute)3 OspfMetricType (org.batfish.datamodel.OspfMetricType)3 Prefix (org.batfish.datamodel.Prefix)3 PrefixRange (org.batfish.datamodel.PrefixRange)3 PrefixSpace (org.batfish.datamodel.PrefixSpace)3 SubRange (org.batfish.datamodel.SubRange)3 RoutingPolicy (org.batfish.datamodel.routing_policy.RoutingPolicy)3 CallExpr (org.batfish.datamodel.routing_policy.expr.CallExpr)3 Conjunction (org.batfish.datamodel.routing_policy.expr.Conjunction)3 DestinationNetwork (org.batfish.datamodel.routing_policy.expr.DestinationNetwork)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2