Search in sources :

Example 1 with FilterResult

use of org.batfish.datamodel.FilterResult in project batfish by batfish.

the class BdpEngine method flowTraceDeniedHelper.

private boolean flowTraceDeniedHelper(Set<FlowTrace> flowTraces, Flow originalFlow, Flow transformedFlow, List<FlowTraceHop> newHops, IpAccessList filter, FlowDisposition disposition) {
    boolean out = disposition == FlowDisposition.DENIED_OUT;
    FilterResult outResult = filter.filter(transformedFlow);
    boolean denied = outResult.getAction() == LineAction.REJECT;
    if (denied) {
        String outFilterName = filter.getName();
        Integer matchLine = outResult.getMatchLine();
        String lineDesc;
        if (matchLine != null) {
            lineDesc = filter.getLines().get(matchLine).getName();
            if (lineDesc == null) {
                lineDesc = "line:" + matchLine;
            }
        } else {
            lineDesc = "no-match";
        }
        String notes = disposition + "{" + outFilterName + "}{" + lineDesc + "}";
        if (out) {
            FlowTraceHop lastHop = newHops.get(newHops.size() - 1);
            newHops.remove(newHops.size() - 1);
            Edge lastEdge = lastHop.getEdge();
            Edge deniedOutEdge = new Edge(lastEdge.getFirst(), new NodeInterfacePair(Configuration.NODE_NONE_NAME, Interface.NULL_INTERFACE_NAME));
            FlowTraceHop deniedOutHop = new FlowTraceHop(deniedOutEdge, lastHop.getRoutes(), hopFlow(originalFlow, transformedFlow));
            newHops.add(deniedOutHop);
        }
        FlowTrace trace = new FlowTrace(disposition, newHops, notes);
        flowTraces.add(trace);
    }
    return denied;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) FlowTrace(org.batfish.datamodel.FlowTrace) FilterResult(org.batfish.datamodel.FilterResult) Edge(org.batfish.datamodel.Edge)

Example 2 with FilterResult

use of org.batfish.datamodel.FilterResult in project batfish by batfish.

the class CounterExample method buildFlowTrace.

/*
   * Build flow information for a given hop along a path
   */
Tuple<Flow, FlowTrace> buildFlowTrace(Encoder enc, String router) {
    EncoderSlice slice = enc.getMainSlice();
    SymbolicPacket pkt = slice.getSymbolicPacket();
    SymbolicDecisions decisions = slice.getSymbolicDecisions();
    Flow f = buildFlow(pkt, router);
    SortedSet<String> visited = new TreeSet<>();
    List<FlowTraceHop> hops = new ArrayList<>();
    String current = router;
    while (true) {
        visited.add(current);
        // Get the forwarding variables
        Map<GraphEdge, BoolExpr> dfwd = decisions.getDataForwarding().get(current);
        Map<GraphEdge, BoolExpr> cfwd = decisions.getControlForwarding().get(current);
        Map<GraphEdge, BoolExpr> across = enc.getMainSlice().getForwardsAcross().get(current);
        // Find the route used
        SymbolicRoute r = decisions.getBestNeighbor().get(current);
        Protocol proto = buildProcotol(r, slice, current);
        Prefix pfx = buildPrefix(r, f);
        // pick the next router
        boolean found = false;
        for (Entry<GraphEdge, BoolExpr> entry : dfwd.entrySet()) {
            GraphEdge ge = entry.getKey();
            BoolExpr dexpr = entry.getValue();
            BoolExpr cexpr = cfwd.get(ge);
            BoolExpr aexpr = across.get(ge);
            String route = buildRoute(pfx, proto, ge);
            if (isTrue(dexpr)) {
                hops.add(buildFlowTraceHop(ge, route));
                if (ge.getPeer() != null && visited.contains(ge.getPeer())) {
                    FlowTrace ft = new FlowTrace(FlowDisposition.LOOP, hops, "LOOP");
                    return new Tuple<>(f, ft);
                }
                if (isFalse(aexpr)) {
                    Interface i = ge.getEnd();
                    IpAccessList acl = i.getIncomingFilter();
                    FilterResult fr = acl.filter(f);
                    String line = "default deny";
                    if (fr.getMatchLine() != null) {
                        line = acl.getLines().get(fr.getMatchLine()).getName();
                    }
                    String note = String.format("DENIED_IN{%s}{%s}", acl.getName(), line);
                    FlowTrace ft = new FlowTrace(FlowDisposition.DENIED_IN, hops, note);
                    return new Tuple<>(f, ft);
                }
                boolean isLoopback = slice.getGraph().isLoopback(ge);
                if (isLoopback) {
                    FlowTrace ft = new FlowTrace(FlowDisposition.ACCEPTED, hops, "ACCEPTED");
                    return new Tuple<>(f, ft);
                }
                if (ge.getPeer() == null) {
                    boolean isBgpPeering = slice.getGraph().getEbgpNeighbors().get(ge) != null;
                    if (isBgpPeering) {
                        FlowTrace ft = new FlowTrace(FlowDisposition.ACCEPTED, hops, "ACCEPTED");
                        return new Tuple<>(f, ft);
                    } else {
                        FlowTrace ft = new FlowTrace(FlowDisposition.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK, hops, "NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK");
                        return new Tuple<>(f, ft);
                    }
                }
                if (slice.getGraph().isHost(ge.getPeer())) {
                    FlowTrace ft = new FlowTrace(FlowDisposition.ACCEPTED, hops, "ACCEPTED");
                    return new Tuple<>(f, ft);
                }
                current = ge.getPeer();
                found = true;
                break;
            } else if (isTrue(cexpr)) {
                hops.add(buildFlowTraceHop(ge, route));
                Interface i = ge.getStart();
                IpAccessList acl = i.getOutgoingFilter();
                FilterResult fr = acl.filter(f);
                IpAccessListLine line = acl.getLines().get(fr.getMatchLine());
                String note = String.format("DENIED_OUT{%s}{%s}", acl.getName(), line.getName());
                FlowTrace ft = new FlowTrace(FlowDisposition.DENIED_OUT, hops, note);
                return new Tuple<>(f, ft);
            }
        }
        if (!found) {
            BoolExpr permitted = r.getPermitted();
            if (boolVal(permitted)) {
                // Check if there is an accepting interface
                for (GraphEdge ge : slice.getGraph().getEdgeMap().get(current)) {
                    Interface i = ge.getStart();
                    Ip ip = i.getAddress().getIp();
                    if (ip.equals(f.getDstIp())) {
                        FlowTrace ft = new FlowTrace(FlowDisposition.ACCEPTED, hops, "ACCEPTED");
                        return new Tuple<>(f, ft);
                    }
                }
                FlowTrace ft = new FlowTrace(FlowDisposition.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK, hops, "NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK");
                return new Tuple<>(f, ft);
            }
            FlowTrace ft = new FlowTrace(FlowDisposition.NO_ROUTE, hops, "NO_ROUTE");
            return new Tuple<>(f, ft);
        }
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Ip(org.batfish.datamodel.Ip) ArrayList(java.util.ArrayList) Prefix(org.batfish.datamodel.Prefix) TreeSet(java.util.TreeSet) IpAccessListLine(org.batfish.datamodel.IpAccessListLine) IpProtocol(org.batfish.datamodel.IpProtocol) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) Protocol(org.batfish.symbolic.Protocol) Flow(org.batfish.datamodel.Flow) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) FlowTrace(org.batfish.datamodel.FlowTrace) IpAccessList(org.batfish.datamodel.IpAccessList) FilterResult(org.batfish.datamodel.FilterResult) GraphEdge(org.batfish.symbolic.GraphEdge) Tuple(org.batfish.symbolic.utils.Tuple) Interface(org.batfish.datamodel.Interface)

Aggregations

FilterResult (org.batfish.datamodel.FilterResult)2 FlowTrace (org.batfish.datamodel.FlowTrace)2 FlowTraceHop (org.batfish.datamodel.FlowTraceHop)2 BoolExpr (com.microsoft.z3.BoolExpr)1 ArrayList (java.util.ArrayList)1 TreeSet (java.util.TreeSet)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Edge (org.batfish.datamodel.Edge)1 Flow (org.batfish.datamodel.Flow)1 Interface (org.batfish.datamodel.Interface)1 Ip (org.batfish.datamodel.Ip)1 IpAccessList (org.batfish.datamodel.IpAccessList)1 IpAccessListLine (org.batfish.datamodel.IpAccessListLine)1 IpProtocol (org.batfish.datamodel.IpProtocol)1 Prefix (org.batfish.datamodel.Prefix)1 RoutingProtocol (org.batfish.datamodel.RoutingProtocol)1 NodeInterfacePair (org.batfish.datamodel.collections.NodeInterfacePair)1 GraphEdge (org.batfish.symbolic.GraphEdge)1 Protocol (org.batfish.symbolic.Protocol)1 Tuple (org.batfish.symbolic.utils.Tuple)1