use of org.batfish.datamodel.flow.Hop in project batfish by batfish.
the class F5BigipStructuredGrammarTest method testSnatBidirectionalTraceroute.
@Test
public void testSnatBidirectionalTraceroute() throws IOException {
String hostname = "f5_bigip_structured_snat";
parseConfig(hostname);
Batfish batfish = getBatfishForConfigurationNames(hostname);
NetworkSnapshot snapshot = batfish.getSnapshot();
batfish.computeDataPlane(snapshot);
// SNAT via snat /Common/snat1
Flow flow = Flow.builder().setDstIp(Ip.parse("192.0.2.1")).setDstPort(80).setIngressInterface("/Common/vlan1").setIngressNode(hostname).setIpProtocol(IpProtocol.TCP).setSrcIp(Ip.parse("8.8.8.8")).setSrcPort(50000).build();
SortedMap<Flow, List<TraceAndReverseFlow>> flowTraces = batfish.getTracerouteEngine(snapshot).computeTracesAndReverseFlows(ImmutableSet.of(flow), false);
List<TraceAndReverseFlow> traces = flowTraces.get(flow);
assertThat(traces, hasSize(1));
Flow reverseFlow = traces.get(0).getReverseFlow();
assertThat(reverseFlow, equalTo(Flow.builder().setSrcIp(Ip.parse("192.0.2.1")).setSrcPort(80).setIngressInterface("/Common/vlan1").setIngressNode(hostname).setIpProtocol(IpProtocol.TCP).setDstIp(Ip.parse("10.200.1.2")).setDstPort(1024).build()));
Set<FirewallSessionTraceInfo> sessions = traces.get(0).getNewFirewallSessions();
SortedMap<Flow, List<TraceAndReverseFlow>> reverseFlowTraces = batfish.getTracerouteEngine(snapshot).computeTracesAndReverseFlows(ImmutableSet.of(reverseFlow), sessions, false);
Optional<TransformationStepDetail> stepDetailOptional = reverseFlowTraces.get(reverseFlow).stream().map(TraceAndReverseFlow::getTrace).map(Trace::getHops).flatMap(Collection::stream).map(Hop::getSteps).flatMap(Collection::stream).map(Step::getDetail).filter(Predicates.instanceOf(TransformationStepDetail.class)).map(TransformationStepDetail.class::cast).filter(d -> d.getTransformationType() == TransformationType.DEST_NAT).findFirst();
assertTrue("There is a DNAT transformation step.", stepDetailOptional.isPresent());
TransformationStepDetail detail = stepDetailOptional.get();
assertThat(detail.getFlowDiffs(), contains(FlowDiff.flowDiff(IpField.DESTINATION, Ip.parse("10.200.1.2"), Ip.parse("8.8.8.8")), FlowDiff.flowDiff(PortField.DESTINATION, 1024, 50000)));
}
use of org.batfish.datamodel.flow.Hop in project batfish by batfish.
the class WorkMgrTest method testColumnComparatorTrace.
@Test
public void testColumnComparatorTrace() {
String col = "col1";
ColumnMetadata columnMetadata = new ColumnMetadata(col, Schema.TRACE, "colDesc");
Comparator<Row> comparator = _manager.columnComparator(columnMetadata);
Row r1 = Row.of(col, new Trace(FlowDisposition.ACCEPTED, ImmutableList.of()));
Row r2 = Row.of(col, new Trace(FlowDisposition.ACCEPTED, ImmutableList.of(new Hop(new Node("a"), ImmutableList.of(LoopStep.INSTANCE)))));
Row r3 = Row.of(col, new Trace(FlowDisposition.DELIVERED_TO_SUBNET, ImmutableList.of()));
assertThat(comparator.compare(r1, r2), lessThan(0));
assertThat(comparator.compare(r1, r3), lessThan(0));
assertThat(comparator.compare(r2, r3), lessThan(0));
}
use of org.batfish.datamodel.flow.Hop in project batfish by batfish.
the class BidirectionalReachabilityAnalysisTest method testRequiredTransitNodes_traceroute.
@Test
public void testRequiredTransitNodes_traceroute() throws IOException {
SortedMap<String, Configuration> configs = makeRequiredTransitNodesNetwork();
Batfish batfish = getBatfish(configs, temp);
batfish.computeDataPlane(batfish.getSnapshot());
BiConsumer<Flow, List<String>> assertTraceHops = (flow, expectedHops) -> {
List<Trace> traces = batfish.getTracerouteEngine(batfish.getSnapshot()).computeTraces(ImmutableSet.of(flow), false).get(flow);
assertEquals(1, traces.size());
Trace trace = traces.get(0);
assertEquals(FlowDisposition.ACCEPTED, trace.getDisposition());
List<String> hops = trace.getHops().stream().map(Hop::getNode).map(Node::getName).collect(ImmutableList.toImmutableList());
assertEquals(expectedHops, hops);
};
Builder fb = Flow.builder().setIngressVrf(Configuration.DEFAULT_VRF_NAME);
// test forward traces
fb.setIngressNode(RTN_SRC).setSrcIp(RTN_TRANSIT_SRC_IP);
assertTraceHops.accept(fb.setDstIp(RTN_TRANSIT_DST_IP).build(), ImmutableList.of(RTN_SRC, RTN_TRANSIT, RTN_DST));
assertTraceHops.accept(fb.setDstIp(RTN_OTHER_DST_IP).build(), ImmutableList.of(RTN_SRC, RTN_OTHER, RTN_DST));
// test reverse traces
fb.setIngressNode(RTN_DST).setSrcIp(RTN_TRANSIT_DST_IP);
assertTraceHops.accept(fb.setDstIp(RTN_TRANSIT_SRC_IP).build(), ImmutableList.of(RTN_DST, RTN_TRANSIT, RTN_SRC));
assertTraceHops.accept(fb.setDstIp(RTN_OTHER_SRC_IP).build(), ImmutableList.of(RTN_DST, RTN_OTHER, RTN_SRC));
}
use of org.batfish.datamodel.flow.Hop in project batfish by batfish.
the class TracerouteEngineImplTest method testTransformationSteps.
@Test
public void testTransformationSteps() throws IOException {
NetworkFactory nf = new NetworkFactory();
Configuration c = nf.configurationBuilder().setConfigurationFormat(ConfigurationFormat.CISCO_IOS).build();
Vrf vrf = nf.vrfBuilder().setOwner(c).build();
Ip ip21 = Ip.parse("2.0.0.1");
Ip ip22 = Ip.parse("2.0.0.2");
Ip ip33 = Ip.parse("3.0.0.3");
Ip ip41 = Ip.parse("4.0.0.2");
Prefix prefix2 = Prefix.parse("2.0.0.0/24");
Interface.Builder ib = nf.interfaceBuilder().setType(InterfaceType.PHYSICAL).setOwner(c).setVrf(vrf);
Interface inInterface = ib.setAddress(ConcreteInterfaceAddress.parse("1.0.0.1/24")).setIncomingTransformation(when(matchDst(ip21)).apply(NOOP_DEST_NAT).setOrElse(when(matchDst(prefix2)).apply(assignDestinationIp(ip33, ip33)).build()).build()).build();
ib.setAddress(ConcreteInterfaceAddress.parse("4.0.0.1/24")).setOutgoingTransformation(when(matchSrc(ip21)).apply(NOOP_SOURCE_NAT).setOrElse(when(matchSrc(prefix2)).apply(assignSourceIp(ip33, ip33)).build()).build()).build();
Batfish batfish = BatfishTestUtils.getBatfish(ImmutableSortedMap.of(c.getHostname(), c), _tempFolder);
NetworkSnapshot snapshot = batfish.getSnapshot();
batfish.computeDataPlane(snapshot);
// Test flows matched by dest nat rules that permit but don't transform
Flow flow = builder().setIngressNode(c.getHostname()).setIngressInterface(inInterface.getName()).setSrcIp(ip22).setDstIp(ip21).build();
List<Trace> traces = computeTraces(batfish, snapshot, flow, false);
assertThat(traces, hasSize(1));
Trace trace = traces.get(0);
assertThat(trace.getDisposition(), equalTo(NO_ROUTE));
assertThat(trace.getHops(), hasSize(1));
Hop hop = trace.getHops().get(0);
assertThat(hop.getSteps(), hasSize(3));
List<Step<?>> steps = hop.getSteps();
assertThat(steps.get(1), equalTo(new TransformationStep(new TransformationStepDetail(DEST_NAT, ImmutableSortedSet.of()), StepAction.PERMITTED)));
// Test flows matched and transformed by dest nat rules
flow = builder().setIngressNode(c.getHostname()).setIngressInterface(inInterface.getName()).setSrcIp(ip21).setDstIp(ip22).build();
traces = computeTraces(batfish, snapshot, flow, false);
assertThat(traces, hasSize(1));
trace = traces.get(0);
assertThat(trace.getDisposition(), equalTo(NO_ROUTE));
assertThat(trace.getHops(), hasSize(1));
hop = trace.getHops().get(0);
assertThat(hop.getSteps(), hasSize(3));
steps = hop.getSteps();
assertThat(steps.get(1), equalTo(new TransformationStep(new TransformationStepDetail(DEST_NAT, flowDiffs(flow, flow.toBuilder().setDstIp(ip33).build())), StepAction.TRANSFORMED)));
// Test flows not matched by dest nat rules
flow = builder().setIngressNode(c.getHostname()).setIngressInterface(inInterface.getName()).setSrcIp(ip21).setDstIp(ip33).build();
traces = computeTraces(batfish, snapshot, flow, false);
assertThat(traces, hasSize(1));
trace = traces.get(0);
assertThat(trace.getDisposition(), equalTo(NO_ROUTE));
assertThat(trace.getHops(), hasSize(1));
hop = trace.getHops().get(0);
assertThat(hop.getSteps(), hasSize(2));
// Test flows matched by source nat rules that permit but don't transform
flow = builder().setIngressNode(c.getHostname()).setIngressInterface(inInterface.getName()).setSrcIp(ip21).setDstIp(ip41).build();
traces = computeTraces(batfish, snapshot, flow, false);
assertThat(traces, hasSize(1));
trace = traces.get(0);
assertThat(trace.getDisposition(), equalTo(DELIVERED_TO_SUBNET));
assertThat(trace.getHops(), hasSize(1));
hop = trace.getHops().get(0);
assertThat(hop.getSteps(), hasSize(5));
steps = hop.getSteps();
// source nat step
assertThat(steps.get(2), equalTo(new TransformationStep(new TransformationStepDetail(SOURCE_NAT, ImmutableSortedSet.of()), StepAction.PERMITTED)));
// Test flows matched and transformed by source nat rules
flow = builder().setIngressNode(c.getHostname()).setIngressInterface(inInterface.getName()).setSrcIp(ip22).setDstIp(ip41).build();
traces = computeTraces(batfish, snapshot, flow, false);
assertThat(traces, hasSize(1));
trace = traces.get(0);
assertThat(trace.getDisposition(), equalTo(DELIVERED_TO_SUBNET));
assertThat(trace.getHops(), hasSize(1));
hop = trace.getHops().get(0);
assertThat(hop.getSteps(), hasSize(5));
steps = hop.getSteps();
// source nat step
assertThat(steps.get(2), equalTo(new TransformationStep(new TransformationStepDetail(SOURCE_NAT, flowDiffs(flow, flow.toBuilder().setSrcIp(ip33).build())), StepAction.TRANSFORMED)));
// Test flows that match no source nat rule
flow = builder().setIngressNode(c.getHostname()).setIngressInterface(inInterface.getName()).setSrcIp(ip33).setDstIp(ip41).build();
traces = computeTraces(batfish, snapshot, flow, false);
assertThat(traces, hasSize(1));
trace = traces.get(0);
assertThat(trace.getDisposition(), equalTo(DELIVERED_TO_SUBNET));
assertThat(trace.getHops(), hasSize(1));
hop = trace.getHops().get(0);
assertThat(hop.getSteps(), hasSize(4));
}
use of org.batfish.datamodel.flow.Hop in project batfish by batfish.
the class TracerouteEngineImplTest method testBidirectionalTracerouteWithDeliveredStep.
@Test
public void testBidirectionalTracerouteWithDeliveredStep() throws IOException {
// Construct network
NetworkFactory nf = new NetworkFactory();
Configuration.Builder cb = nf.configurationBuilder().setConfigurationFormat(ConfigurationFormat.CISCO_IOS);
Configuration c1 = cb.setHostname("c1").build();
Vrf vrf1 = nf.vrfBuilder().setOwner(c1).build();
nf.interfaceBuilder().setType(InterfaceType.PHYSICAL).setName("c1_out").setOwner(c1).setVrf(vrf1).setAddress(ConcreteInterfaceAddress.parse("10.0.0.1/24")).build();
String c1ToFw = "c1_to_fw";
nf.interfaceBuilder().setType(InterfaceType.PHYSICAL).setName(c1ToFw).setOwner(c1).setVrf(vrf1).setAddress(ConcreteInterfaceAddress.parse("1.1.1.1/24")).build();
vrf1.getStaticRoutes().add(StaticRoute.testBuilder().setNetwork(Prefix.parse("20.0.0.2/32")).setNextHopInterface(c1ToFw).setNextHopIp(Ip.parse("1.1.1.2")).setAdministrativeCost(1).build());
Configuration fw = cb.setConfigurationFormat(ConfigurationFormat.CISCO_ASA).setHostname("fw").build();
Vrf fwVrf = nf.vrfBuilder().setOwner(fw).build();
String fwToC1Name = "fw_to_c1";
nf.interfaceBuilder().setType(InterfaceType.PHYSICAL).setName(fwToC1Name).setOwner(fw).setVrf(fwVrf).setAddress(ConcreteInterfaceAddress.parse("1.1.1.2/24")).build();
// set up another interface with session
String fwOutName = "fwOut";
nf.interfaceBuilder().setType(InterfaceType.PHYSICAL).setName(fwOutName).setOwner(fw).setVrf(fwVrf).setAddress(ConcreteInterfaceAddress.parse("20.0.0.1/24")).setFirewallSessionInterfaceInfo(new FirewallSessionInterfaceInfo(Action.POST_NAT_FIB_LOOKUP, ImmutableSet.of(fwOutName), null, null)).build();
// set up a static route for the reverse flow
fwVrf.getStaticRoutes().add(StaticRoute.testBuilder().setNetwork(Prefix.parse("10.0.0.0/24")).setAdministrativeCost(1).setNextHopIp(Ip.parse("1.1.1.1")).build());
// Compute data plane
SortedMap<String, Configuration> configs = ImmutableSortedMap.of(c1.getHostname(), c1, fw.getHostname(), fw);
Batfish batfish = BatfishTestUtils.getBatfish(configs, _tempFolder);
NetworkSnapshot snapshot = batfish.getSnapshot();
batfish.computeDataPlane(snapshot);
TracerouteEngine tracerouteEngine = batfish.getTracerouteEngine(snapshot);
Flow flow = builder().setIngressNode(c1.getHostname()).setIngressVrf(vrf1.getName()).setSrcIp(Ip.parse("10.0.0.2")).setDstIp(Ip.parse("20.0.0.2")).setIpProtocol(IpProtocol.TCP).setSrcPort(12345).setDstPort(12346).build();
List<TraceAndReverseFlow> forwardTracerouteResult = tracerouteEngine.computeTracesAndReverseFlows(ImmutableSet.of(flow), false).get(flow);
assertThat(forwardTracerouteResult, hasSize(1));
Flow reverseFlow = forwardTracerouteResult.get(0).getReverseFlow();
assertNotNull(reverseFlow);
Set<FirewallSessionTraceInfo> newSessions = forwardTracerouteResult.get(0).getNewFirewallSessions();
// reverse direction
List<TraceAndReverseFlow> reverseResult = tracerouteEngine.computeTracesAndReverseFlows(ImmutableSet.of(reverseFlow), newSessions, false).get(reverseFlow);
assertThat(reverseResult, hasSize(1));
List<Hop> reverseHops = reverseResult.get(0).getTrace().getHops();
assertThat(reverseHops, hasSize(2));
assertThat(reverseHops.get(0).getSteps(), hasSize(4));
assertTrue(reverseHops.get(0).getSteps().get(0) instanceof EnterInputIfaceStep);
assertTrue(reverseHops.get(0).getSteps().get(1) instanceof MatchSessionStep);
assertTrue(reverseHops.get(0).getSteps().get(2) instanceof RoutingStep);
assertTrue(reverseHops.get(0).getSteps().get(3) instanceof ExitOutputIfaceStep);
assertThat(reverseHops.get(1).getSteps(), hasSize(4));
assertTrue(reverseHops.get(1).getSteps().get(0) instanceof EnterInputIfaceStep);
assertTrue(reverseHops.get(1).getSteps().get(1) instanceof RoutingStep);
assertTrue(reverseHops.get(1).getSteps().get(2) instanceof ExitOutputIfaceStep);
assertTrue(reverseHops.get(1).getSteps().get(3) instanceof DeliveredStep);
}
Aggregations