Search in sources :

Example 6 with FlowTraceHop

use of org.batfish.datamodel.FlowTraceHop 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 7 with FlowTraceHop

use of org.batfish.datamodel.FlowTraceHop 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 8 with FlowTraceHop

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

the class CounterExample method buildFlowTraceHop.

/*
   * Build an individual flow hop along a path
   */
private FlowTraceHop buildFlowTraceHop(GraphEdge ge, String route) {
    String node1 = ge.getRouter();
    String int1 = ge.getStart().getName();
    String node2 = ge.getPeer() == null ? "(none)" : ge.getPeer();
    String int2 = ge.getEnd() == null ? "null_interface" : ge.getEnd().getName();
    Edge edge = new Edge(node1, int1, node2, int2);
    SortedSet<String> routes = new TreeSet<>();
    routes.add(route);
    return new FlowTraceHop(edge, routes, null);
}
Also used : FlowTraceHop(org.batfish.datamodel.FlowTraceHop) TreeSet(java.util.TreeSet) Edge(org.batfish.datamodel.Edge) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 9 with FlowTraceHop

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

the class NodJobTest method testNotNatted.

/**
 * Test that traffic originating from 3.0.0.1 is not NATed
 */
@Test
public void testNotNatted() {
    HeaderSpace headerSpace = new HeaderSpace();
    headerSpace.setSrcIps(ImmutableList.of(new IpWildcard("3.0.0.1")));
    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);
    assertThat(fieldConstraints, hasEntry(OriginateVrfInstrumentation.ORIGINATE_VRF_FIELD_NAME, new Long(0)));
    assertThat(smtInput._variablesAsConsts, hasKey("SRC_IP"));
    assertThat(fieldConstraints, hasKey(BasicHeaderField.SRC_IP.getName()));
    assertThat(fieldConstraints, hasEntry(BasicHeaderField.ORIG_SRC_IP.getName(), new Ip("3.0.0.1").asLong()));
    assertThat(fieldConstraints, hasEntry(BasicHeaderField.SRC_IP.getName(), new Ip("3.0.0.1").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(), nullValue());
    });
}
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)

Aggregations

FlowTraceHop (org.batfish.datamodel.FlowTraceHop)9 FlowTrace (org.batfish.datamodel.FlowTrace)8 Edge (org.batfish.datamodel.Edge)6 Ip (org.batfish.datamodel.Ip)6 ArrayList (java.util.ArrayList)5 TreeSet (java.util.TreeSet)4 Flow (org.batfish.datamodel.Flow)4 ImmutableMap (com.google.common.collect.ImmutableMap)3 LinkedHashSet (java.util.LinkedHashSet)3 Map (java.util.Map)3 SortedMap (java.util.SortedMap)3 Interface (org.batfish.datamodel.Interface)3 IpAccessList (org.batfish.datamodel.IpAccessList)3 NodeInterfacePair (org.batfish.datamodel.collections.NodeInterfacePair)3 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)2 ImmutableSortedSet (com.google.common.collect.ImmutableSortedSet)2 Context (com.microsoft.z3.Context)2 Set (java.util.Set)2 SortedSet (java.util.SortedSet)2 TreeMap (java.util.TreeMap)2