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;
}
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;
}
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);
}
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());
});
}
Aggregations