Search in sources :

Example 6 with FlowTrace

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

the class CounterExample method buildFlowHistoryDiff.

/*
   * Create a trace-based counterexample demonstrating
   * the difference between two networks on a single packet.
   */
FlowHistory buildFlowHistoryDiff(String testRigName, Collection<String> sourceRouters, Encoder enc, Encoder enc2, Map<String, BoolExpr> reach, Map<String, BoolExpr> reach2) {
    FlowHistory fh = new FlowHistory();
    assert (reach2 != null);
    for (String source : sourceRouters) {
        BoolExpr sourceVar1 = reach.get(source);
        BoolExpr sourceVar2 = reach2.get(source);
        String val1 = evaluate(sourceVar1);
        String val2 = evaluate(sourceVar2);
        if (!Objects.equals(val1, val2)) {
            Tuple<Flow, FlowTrace> diff = buildFlowTrace(enc, source);
            Tuple<Flow, FlowTrace> base = buildFlowTrace(enc2, source);
            SortedSet<Edge> failedLinksDiff = buildFailedLinks(enc);
            SortedSet<Edge> failedLinksBase = buildFailedLinks(enc2);
            SortedSet<BgpAdvertisement> envRoutesDiff = buildEnvRoutingTable(enc);
            SortedSet<BgpAdvertisement> envRoutesBase = buildEnvRoutingTable(enc2);
            Environment baseEnv = new Environment("BASE", testRigName, failedLinksBase, null, null, null, null, envRoutesBase);
            Environment failedEnv = new Environment("DELTA", testRigName, failedLinksDiff, null, null, null, null, envRoutesDiff);
            fh.addFlowTrace(base.getFirst(), "BASE", baseEnv, base.getSecond());
            fh.addFlowTrace(diff.getFirst(), "DELTA", failedEnv, diff.getSecond());
        }
    }
    return fh;
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) FlowHistory(org.batfish.datamodel.FlowHistory) FlowTrace(org.batfish.datamodel.FlowTrace) Environment(org.batfish.datamodel.pojo.Environment) Edge(org.batfish.datamodel.Edge) GraphEdge(org.batfish.symbolic.GraphEdge) Flow(org.batfish.datamodel.Flow)

Example 7 with FlowTrace

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

the class NodJobTest method testNatted.

/**
 * Test that traffic originating from 3.0.0.0 is NATed
 */
@Test
public void testNatted() {
    HeaderSpace headerSpace = new HeaderSpace();
    headerSpace.setSrcIps(ImmutableList.of(new IpWildcard("3.0.0.0")));
    NodJob nodJob = getNodJob(headerSpace);
    Context z3Context = new Context();
    SmtInput smtInput = nodJob.computeSmtInput(System.currentTimeMillis(), z3Context);
    Map<OriginateVrf, Map<String, Long>> fieldConstraintsByOriginateVrf = nodJob.getOriginateVrfConstraints(z3Context, smtInput);
    assertThat(fieldConstraintsByOriginateVrf.entrySet(), hasSize(1));
    assertThat(fieldConstraintsByOriginateVrf, hasKey(_originateVrf));
    Map<String, Long> fieldConstraints = fieldConstraintsByOriginateVrf.get(_originateVrf);
    // Only one OriginateVrf choice, so this must be 0
    assertThat(fieldConstraints, hasEntry(OriginateVrfInstrumentation.ORIGINATE_VRF_FIELD_NAME, new Long(0)));
    assertThat(fieldConstraints, hasEntry(BasicHeaderField.ORIG_SRC_IP.getName(), new Ip("3.0.0.0").asLong()));
    assertThat(fieldConstraints, hasEntry(equalTo(BasicHeaderField.SRC_IP.getName()), not(equalTo(new Ip("3.0.0.0").asLong()))));
    assertThat(fieldConstraints, hasEntry(BasicHeaderField.SRC_IP.getName(), new Ip("1.0.0.10").asLong()));
    Set<Flow> flows = nodJob.getFlows(fieldConstraintsByOriginateVrf);
    _bdpDataPlanePlugin.processFlows(flows, _dataPlane);
    List<FlowTrace> flowTraces = _bdpDataPlanePlugin.getHistoryFlowTraces(_dataPlane);
    flowTraces.forEach(trace -> {
        assertThat(trace.getNotes(), is("ACCEPTED"));
        List<FlowTraceHop> hops = trace.getHops();
        assertThat(hops, hasSize(1));
        FlowTraceHop hop = hops.get(0);
        assertThat(hop.getTransformedFlow(), notNullValue());
        assertThat(hop.getTransformedFlow().getSrcIp(), equalTo(new Ip("1.0.0.10")));
    });
}
Also used : Context(com.microsoft.z3.Context) Ip(org.batfish.datamodel.Ip) HeaderSpace(org.batfish.datamodel.HeaderSpace) OriginateVrf(org.batfish.z3.state.OriginateVrf) Flow(org.batfish.datamodel.Flow) IpWildcard(org.batfish.datamodel.IpWildcard) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) FlowTrace(org.batfish.datamodel.FlowTrace) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) SortedMap(java.util.SortedMap) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Test(org.junit.Test)

Example 8 with FlowTrace

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

the class BdpEngine method processCurrentNextHopInterfaceEdges.

private boolean processCurrentNextHopInterfaceEdges(BdpDataPlane dp, String currentNodeName, Set<Edge> visitedEdges, List<FlowTraceHop> hopsSoFar, Set<FlowTrace> flowTraces, Flow originalFlow, Flow transformedFlow, Ip dstIp, Set<String> dstIpOwners, @Nullable String nextHopInterfaceName, SortedSet<String> routesForThisNextHopInterface, @Nullable Ip finalNextHopIp, @Nullable NodeInterfacePair nextHopInterface, SortedSet<Edge> edges, boolean arp) {
    boolean continueToNextNextHopInterface = false;
    int unreachableNeighbors = 0;
    int potentialNeighbors = 0;
    for (Edge edge : edges) {
        if (!edge.getNode1().equals(currentNodeName)) {
            continue;
        }
        potentialNeighbors++;
        List<FlowTraceHop> newHops = new ArrayList<>(hopsSoFar);
        Set<Edge> newVisitedEdges = new LinkedHashSet<>(visitedEdges);
        FlowTraceHop newHop = new FlowTraceHop(edge, routesForThisNextHopInterface, hopFlow(originalFlow, transformedFlow));
        newVisitedEdges.add(edge);
        newHops.add(newHop);
        /*
       * Check to see whether neighbor would refrain from sending ARP reply
       * (NEIGHBOR_UNREACHABLE)
       *
       * This occurs if:
       *
       * - Using interface-only route
       *
       * AND
       *
       * - Neighbor does not own arpIp
       *
       * AND EITHER
       *
       * -- Neighbor not using proxy-arp
       *
       * - OR
       *
       * -- Subnet of neighbor's receiving-interface contains arpIp
       */
        if (arp) {
            Ip arpIp;
            Set<String> arpIpOwners;
            if (finalNextHopIp == null) {
                arpIp = dstIp;
                arpIpOwners = dstIpOwners;
            } else {
                arpIp = finalNextHopIp;
                arpIpOwners = dp._ipOwners.get(arpIp);
            }
            // using interface-only route
            String node2 = edge.getNode2();
            if (arpIpOwners == null || !arpIpOwners.contains(node2)) {
                // neighbor does not own arpIp
                String int2Name = edge.getInt2();
                Interface int2 = dp._nodes.get(node2)._c.getInterfaces().get(int2Name);
                boolean neighborUnreachable = false;
                Boolean proxyArp = int2.getProxyArp();
                if (proxyArp == null || !proxyArp) {
                    // TODO: proxyArp probably shouldn't be null
                    neighborUnreachable = true;
                } else {
                    for (InterfaceAddress address : int2.getAllAddresses()) {
                        if (address.getPrefix().containsIp(arpIp)) {
                            neighborUnreachable = true;
                            break;
                        }
                    }
                }
                if (neighborUnreachable) {
                    unreachableNeighbors++;
                    continue;
                }
            }
        }
        if (visitedEdges.contains(edge)) {
            FlowTrace trace = new FlowTrace(FlowDisposition.LOOP, newHops, FlowDisposition.LOOP.toString());
            flowTraces.add(trace);
            potentialNeighbors--;
            continue;
        }
        String nextNodeName = edge.getNode2();
        // now check output filter and input filter
        if (nextHopInterfaceName != null) {
            IpAccessList outFilter = dp._nodes.get(currentNodeName)._c.getInterfaces().get(nextHopInterfaceName).getOutgoingFilter();
            if (outFilter != null) {
                FlowDisposition disposition = FlowDisposition.DENIED_OUT;
                boolean denied = flowTraceDeniedHelper(flowTraces, originalFlow, transformedFlow, newHops, outFilter, disposition);
                if (denied) {
                    potentialNeighbors--;
                    continue;
                }
            }
        }
        IpAccessList inFilter = dp._nodes.get(nextNodeName)._c.getInterfaces().get(edge.getInt2()).getIncomingFilter();
        if (inFilter != null) {
            FlowDisposition disposition = FlowDisposition.DENIED_IN;
            boolean denied = flowTraceDeniedHelper(flowTraces, originalFlow, transformedFlow, newHops, inFilter, disposition);
            if (denied) {
                potentialNeighbors--;
                continue;
            }
        }
        // recurse
        collectFlowTraces(dp, nextNodeName, newVisitedEdges, newHops, flowTraces, originalFlow, transformedFlow);
    }
    if (arp && unreachableNeighbors > 0 && unreachableNeighbors == potentialNeighbors) {
        FlowTrace trace = neighborUnreachableTrace(hopsSoFar, nextHopInterface, routesForThisNextHopInterface, originalFlow, transformedFlow);
        flowTraces.add(trace);
        continueToNextNextHopInterface = true;
    }
    return continueToNextNextHopInterface;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Ip(org.batfish.datamodel.Ip) ArrayList(java.util.ArrayList) FlowDisposition(org.batfish.datamodel.FlowDisposition) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) FlowTrace(org.batfish.datamodel.FlowTrace) IpAccessList(org.batfish.datamodel.IpAccessList) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Edge(org.batfish.datamodel.Edge) Interface(org.batfish.datamodel.Interface)

Example 9 with FlowTrace

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

the class BdpEngine method neighborUnreachableTrace.

private FlowTrace neighborUnreachableTrace(List<FlowTraceHop> completedHops, NodeInterfacePair srcInterface, SortedSet<String> routes, Flow originalFlow, Flow transformedFlow) {
    Edge neighborUnreachbleEdge = new Edge(srcInterface, new NodeInterfacePair(Configuration.NODE_NONE_NAME, Interface.NULL_INTERFACE_NAME));
    FlowTraceHop neighborUnreachableHop = new FlowTraceHop(neighborUnreachbleEdge, routes, hopFlow(originalFlow, transformedFlow));
    List<FlowTraceHop> newHops = new ArrayList<>(completedHops);
    newHops.add(neighborUnreachableHop);
    FlowTrace trace = new FlowTrace(FlowDisposition.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK, newHops, FlowDisposition.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK.toString());
    return trace;
}
Also used : FlowTraceHop(org.batfish.datamodel.FlowTraceHop) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) ArrayList(java.util.ArrayList) FlowTrace(org.batfish.datamodel.FlowTrace) Edge(org.batfish.datamodel.Edge)

Example 10 with FlowTrace

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

the class Batfish method populateFlowHistory.

private void populateFlowHistory(FlowHistory flowHistory, String envTag, Environment environment, String flowTag) {
    DataPlanePlugin dataPlanePlugin = getDataPlanePlugin();
    List<Flow> flows = dataPlanePlugin.getHistoryFlows(loadDataPlane());
    List<FlowTrace> flowTraces = dataPlanePlugin.getHistoryFlowTraces(loadDataPlane());
    int numEntries = flows.size();
    for (int i = 0; i < numEntries; i++) {
        Flow flow = flows.get(i);
        if (flow.getTag().equals(flowTag)) {
            FlowTrace flowTrace = flowTraces.get(i);
            flowHistory.addFlowTrace(flow, envTag, environment, flowTrace);
        }
    }
}
Also used : DataPlanePlugin(org.batfish.common.plugin.DataPlanePlugin) FlowTrace(org.batfish.datamodel.FlowTrace) Flow(org.batfish.datamodel.Flow)

Aggregations

FlowTrace (org.batfish.datamodel.FlowTrace)12 Edge (org.batfish.datamodel.Edge)8 Flow (org.batfish.datamodel.Flow)8 FlowTraceHop (org.batfish.datamodel.FlowTraceHop)8 Ip (org.batfish.datamodel.Ip)7 ArrayList (java.util.ArrayList)5 ImmutableMap (com.google.common.collect.ImmutableMap)4 Map (java.util.Map)4 SortedMap (java.util.SortedMap)4 TreeSet (java.util.TreeSet)4 Interface (org.batfish.datamodel.Interface)4 NodeInterfacePair (org.batfish.datamodel.collections.NodeInterfacePair)4 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)3 LinkedHashSet (java.util.LinkedHashSet)3 Set (java.util.Set)3 SortedSet (java.util.SortedSet)3 TreeMap (java.util.TreeMap)3 BatfishException (org.batfish.common.BatfishException)3 FlowDisposition (org.batfish.datamodel.FlowDisposition)3 IpAccessList (org.batfish.datamodel.IpAccessList)3