Search in sources :

Example 1 with FibForward

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

the class FlowTracerTest method testBuildRoutingStepFibForward.

@Test
public void testBuildRoutingStepFibForward() {
    Prefix prefix = Prefix.parse("12.12.12.12/30");
    FibForward fibForward = FibForward.of(Ip.parse("1.1.1.1"), "iface1");
    Set<FibEntry> fibEntries = ImmutableSet.of(new FibEntry(fibForward, ImmutableList.of(StaticRoute.testBuilder().setNextHopIp(Ip.parse("2.2.2.2")).setNetwork(prefix).setAdministrativeCost(1).build())));
    RoutingStep routingStep = buildRoutingStep("myvrf", fibForward, fibEntries);
    assertThat(routingStep.getAction(), equalTo(StepAction.FORWARDED));
    assertThat(routingStep.getDetail().getVrf(), equalTo("myvrf"));
    assertThat(routingStep.getDetail().getRoutes(), equalTo(ImmutableList.of(new RouteInfo(RoutingProtocol.STATIC, prefix, NextHopIp.of(Ip.parse("2.2.2.2")), 1, 0))));
    assertThat(routingStep.getDetail().getArpIp(), equalTo(Ip.parse("1.1.1.1")));
    assertThat(routingStep.getDetail().getOutputInterface(), equalTo("iface1"));
}
Also used : FibForward(org.batfish.datamodel.FibForward) FibEntry(org.batfish.datamodel.FibEntry) Prefix(org.batfish.datamodel.Prefix) RoutingStep(org.batfish.datamodel.flow.RoutingStep) FlowTracer.buildRoutingStep(org.batfish.dataplane.traceroute.FlowTracer.buildRoutingStep) RouteInfo(org.batfish.datamodel.flow.RouteInfo) Test(org.junit.Test)

Example 2 with FibForward

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

the class FlowTracer method fibLookup.

/**
 * Perform a FIB lookup of {@code dstIp} on {@code fib} of {@code currentNodeName} and take
 * corresponding actions given {@code intraHopBreadcrumbs} already produced at this node. Use
 * {@code forwardOutInterfaceHandler} to handle forwarding action.
 */
@VisibleForTesting
void fibLookup(Ip dstIp, String currentNodeName, String lookupVrf, Fib fib, BiConsumer<FlowTracer, FibForward> forwardOutInterfaceHandler, Stack<Breadcrumb> intraHopBreadcrumbs) {
    // Loop detection
    Breadcrumb breadcrumb = newBreadcrumb(currentNodeName, _vrfName, _ingressInterface, _currentFlow);
    if (_breadcrumbs.contains(breadcrumb)) {
        buildLoopTrace(breadcrumb);
        return;
    }
    if (intraHopBreadcrumbs.isEmpty()) {
        _breadcrumbs.push(breadcrumb);
    }
    try {
        Set<FibEntry> fibEntries = fib.get(dstIp);
        if (fibEntries.isEmpty()) {
            buildNoRouteTrace(lookupVrf);
            return;
        }
        // Group traces by action (we do not want extra branching if there is branching
        // in FIB resolution)
        TreeMap<FibAction, Set<FibEntry>> groupedByFibAction = new TreeMap<>(FibActionComparator.INSTANCE);
        for (FibEntry e : fibEntries) {
            groupedByFibAction.computeIfAbsent(e.getAction(), k -> new HashSet<>()).add(e);
        }
        // For every action corresponding to ECMP LPM FibEntry
        groupedByFibAction.forEach(((fibAction, fibEntriesForFibAction) -> {
            forkTracerSameNode().forward(fibAction, fibEntriesForFibAction, dstIp, currentNodeName, lookupVrf, forwardOutInterfaceHandler, intraHopBreadcrumbs, breadcrumb);
        }));
    } finally {
        if (intraHopBreadcrumbs.isEmpty()) {
            _breadcrumbs.pop();
        }
    }
}
Also used : SessionActionVisitor(org.batfish.datamodel.visitors.SessionActionVisitor) Hop(org.batfish.datamodel.flow.Hop) Accept(org.batfish.datamodel.flow.Accept) FibForward(org.batfish.datamodel.FibForward) TracerouteUtils.buildEnterSrcIfaceStep(org.batfish.dataplane.traceroute.TracerouteUtils.buildEnterSrcIfaceStep) FibNextVrf(org.batfish.datamodel.FibNextVrf) InboundStepDetail(org.batfish.datamodel.flow.InboundStep.InboundStepDetail) Interface(org.batfish.datamodel.Interface) FlowDiff.returnFlowDiffs(org.batfish.datamodel.FlowDiff.returnFlowDiffs) Flow(org.batfish.datamodel.Flow) MatchSessionStep(org.batfish.datamodel.flow.MatchSessionStep) Map(java.util.Map) HopInfo.forwardedHop(org.batfish.dataplane.traceroute.HopInfo.forwardedHop) PreNatFibLookup(org.batfish.datamodel.flow.PreNatFibLookup) INGRESS_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.INGRESS_FILTER) PacketPolicyResult(org.batfish.datamodel.packet_policy.PacketPolicyEvaluator.PacketPolicyResult) DeliveredStep(org.batfish.datamodel.flow.DeliveredStep) RoutingStep(org.batfish.datamodel.flow.RoutingStep) Set(java.util.Set) Evaluator(org.batfish.datamodel.acl.Evaluator) LoopStep(org.batfish.datamodel.flow.LoopStep) TraceAndReverseFlow(org.batfish.datamodel.flow.TraceAndReverseFlow) Step(org.batfish.datamodel.flow.Step) OriginatingSessionScope(org.batfish.datamodel.flow.OriginatingSessionScope) SetupSessionStepDetail(org.batfish.datamodel.flow.SetupSessionStep.SetupSessionStepDetail) Discarded(org.batfish.datamodel.flow.Discarded) Iterables(com.google.common.collect.Iterables) NULL_ROUTED(org.batfish.datamodel.flow.StepAction.NULL_ROUTED) Drop(org.batfish.datamodel.packet_policy.Drop) EGRESS_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.EGRESS_FILTER) TracerouteUtils.returnFlow(org.batfish.dataplane.traceroute.TracerouteUtils.returnFlow) IncomingSessionScope(org.batfish.datamodel.flow.IncomingSessionScope) FORWARDED(org.batfish.datamodel.flow.StepAction.FORWARDED) ArrayList(java.util.ArrayList) PolicyStep(org.batfish.datamodel.flow.PolicyStep) Builder(org.batfish.datamodel.flow.RoutingStep.Builder) MatchSessionStepDetail(org.batfish.datamodel.flow.MatchSessionStep.MatchSessionStepDetail) TracerouteUtils.fibEntriesToRouteInfos(org.batfish.dataplane.traceroute.TracerouteUtils.fibEntriesToRouteInfos) RoutingStepDetail(org.batfish.datamodel.flow.RoutingStep.RoutingStepDetail) HopInfo.failureHop(org.batfish.dataplane.traceroute.HopInfo.failureHop) BiConsumer(java.util.function.BiConsumer) ForwardedOutInterface(org.batfish.datamodel.flow.ForwardedOutInterface) ExitOutputIfaceStep(org.batfish.datamodel.flow.ExitOutputIfaceStep) ExitOutputIfaceStepDetail(org.batfish.datamodel.flow.ExitOutputIfaceStep.ExitOutputIfaceStepDetail) OriginateStepDetail(org.batfish.datamodel.flow.OriginateStep.OriginateStepDetail) Nullable(javax.annotation.Nullable) ForwardOutInterface(org.batfish.datamodel.flow.ForwardOutInterface) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) Comparator.nullsFirst(java.util.Comparator.nullsFirst) FirewallSessionInterfaceInfo(org.batfish.datamodel.FirewallSessionInterfaceInfo) TransformationEvaluator(org.batfish.datamodel.transformation.TransformationEvaluator) Fib(org.batfish.datamodel.Fib) FirewallSessionTraceInfo(org.batfish.datamodel.flow.FirewallSessionTraceInfo) FibLookup(org.batfish.datamodel.packet_policy.FibLookup) TreeMap(java.util.TreeMap) DelegatedToNextVrf(org.batfish.datamodel.flow.DelegatedToNextVrf) SOURCE_ORIGINATING_FROM_DEVICE(org.batfish.datamodel.acl.SourcesReferencedByIpAccessLists.SOURCE_ORIGINATING_FROM_DEVICE) VrfExprNameExtractor(org.batfish.datamodel.packet_policy.VrfExprNameExtractor) HopInfo.loopHop(org.batfish.dataplane.traceroute.HopInfo.loopHop) StepAction(org.batfish.datamodel.flow.StepAction) PERMITTED(org.batfish.datamodel.flow.StepAction.PERMITTED) IpProtocol(org.batfish.datamodel.IpProtocol) FilterType(org.batfish.datamodel.flow.FilterStep.FilterType) SortedSet(java.util.SortedSet) ForwardedIntoVxlanTunnel(org.batfish.datamodel.flow.ForwardedIntoVxlanTunnel) FibAction(org.batfish.datamodel.FibAction) NextHopVtep(org.batfish.datamodel.route.nh.NextHopVtep) Trace(org.batfish.datamodel.flow.Trace) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) FibLookupOverrideLookupIp(org.batfish.datamodel.packet_policy.FibLookupOverrideLookupIp) TracerouteUtils.getFinalActionForDisposition(org.batfish.dataplane.traceroute.TracerouteUtils.getFinalActionForDisposition) FORWARDED_TO_NEXT_VRF(org.batfish.datamodel.flow.StepAction.FORWARDED_TO_NEXT_VRF) PolicyStepDetail(org.batfish.datamodel.flow.PolicyStep.PolicyStepDetail) TransformationResult(org.batfish.datamodel.transformation.TransformationEvaluator.TransformationResult) ImmutableSet(com.google.common.collect.ImmutableSet) ActionVisitor(org.batfish.datamodel.packet_policy.ActionVisitor) SetupSessionStep(org.batfish.datamodel.flow.SetupSessionStep) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) FlowDisposition(org.batfish.datamodel.FlowDisposition) FibActionVisitor(org.batfish.datamodel.visitors.FibActionVisitor) TracerouteUtils.createFilterStep(org.batfish.dataplane.traceroute.TracerouteUtils.createFilterStep) Interner(com.google.common.collect.Interner) IpSpace(org.batfish.datamodel.IpSpace) Collectors(java.util.stream.Collectors) TRANSMITTED(org.batfish.datamodel.flow.StepAction.TRANSMITTED) ArpErrorStep(org.batfish.datamodel.flow.ArpErrorStep) Preconditions.checkState(com.google.common.base.Preconditions.checkState) SessionMatchExpr(org.batfish.datamodel.flow.SessionMatchExpr) List(java.util.List) EGRESS_ORIGINAL_FLOW_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.EGRESS_ORIGINAL_FLOW_FILTER) ConnectedRoute(org.batfish.datamodel.ConnectedRoute) FlowDiff.flowDiffs(org.batfish.datamodel.FlowDiff.flowDiffs) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) Ip(org.batfish.datamodel.Ip) Action(org.batfish.datamodel.FirewallSessionInterfaceInfo.Action) SessionAction(org.batfish.datamodel.flow.SessionAction) POST_TRANSFORMATION_INGRESS_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.POST_TRANSFORMATION_INGRESS_FILTER) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) InboundStep(org.batfish.datamodel.flow.InboundStep) HopInfo.successHop(org.batfish.dataplane.traceroute.HopInfo.successHop) Transformation(org.batfish.datamodel.transformation.Transformation) DeliveredStepDetail(org.batfish.datamodel.flow.DeliveredStep.DeliveredStepDetail) TransformationStep(org.batfish.datamodel.flow.TransformationStep) BatfishException(org.batfish.common.BatfishException) IpAccessList(org.batfish.datamodel.IpAccessList) Stack(java.util.Stack) HashSet(java.util.HashSet) OriginateStep(org.batfish.datamodel.flow.OriginateStep) ImmutableList(com.google.common.collect.ImmutableList) RouteInfo(org.batfish.datamodel.flow.RouteInfo) FirewallSessionVrfInfo(org.batfish.datamodel.FirewallSessionVrfInfo) Configuration(org.batfish.datamodel.Configuration) TracerouteUtils.sessionTransformation(org.batfish.dataplane.traceroute.TracerouteUtils.sessionTransformation) PostNatFibLookup(org.batfish.datamodel.flow.PostNatFibLookup) SessionScope(org.batfish.datamodel.flow.SessionScope) Comparator.comparing(java.util.Comparator.comparing) FibNullRoute(org.batfish.datamodel.FibNullRoute) PRE_TRANSFORMATION_EGRESS_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.PRE_TRANSFORMATION_EGRESS_FILTER) Nonnull(javax.annotation.Nonnull) DENIED(org.batfish.datamodel.flow.StepAction.DENIED) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Interners(com.google.common.collect.Interners) PacketPolicy(org.batfish.datamodel.packet_policy.PacketPolicy) Consumer(java.util.function.Consumer) Ordering(com.google.common.collect.Ordering) Node(org.batfish.datamodel.pojo.Node) ArpErrorStepDetail(org.batfish.datamodel.flow.ArpErrorStep.ArpErrorStepDetail) FilterStep(org.batfish.datamodel.flow.FilterStep) VisibleForTesting(com.google.common.annotations.VisibleForTesting) FibEntry(org.batfish.datamodel.FibEntry) Comparator(java.util.Comparator) PacketPolicyEvaluator(org.batfish.datamodel.packet_policy.PacketPolicyEvaluator) Set(java.util.Set) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) SortedSet(java.util.SortedSet) ImmutableSet(com.google.common.collect.ImmutableSet) HashSet(java.util.HashSet) FibEntry(org.batfish.datamodel.FibEntry) TreeMap(java.util.TreeMap) FibAction(org.batfish.datamodel.FibAction) HashSet(java.util.HashSet) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 3 with FibForward

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

the class FlowTracer method processSessions.

/**
 * Check this {@param flow} matches a session on this device. If so, process the flow. Returns
 * true if the flow is matched/processed.
 */
private boolean processSessions() {
    String inputIfaceName = _ingressInterface;
    String currentNodeName = _currentNode.getName();
    Collection<FirewallSessionTraceInfo> sessions = _ingressInterface != null ? _tracerouteContext.getSessionsForIncomingInterface(currentNodeName, inputIfaceName) : // Flow originated here; check for sessions to match flows originating in current VRF
    _tracerouteContext.getSessionsForOriginatingVrf(currentNodeName, _vrfName);
    if (sessions.isEmpty()) {
        return false;
    }
    // session match expr cannot use MatchSrcInterface or ACL/IpSpace references.
    Evaluator aclEval = new Evaluator(_currentFlow, null, ImmutableMap.of(), ImmutableMap.of());
    List<FirewallSessionTraceInfo> matchingSessions = sessions.stream().filter(session -> aclEval.visit(session.getSessionFlows())).collect(Collectors.toList());
    checkState(matchingSessions.size() < 2, "Flow cannot match more than 1 session");
    if (matchingSessions.isEmpty()) {
        return false;
    }
    FirewallSessionTraceInfo session = matchingSessions.get(0);
    MatchSessionStepDetail.Builder matchDetail = MatchSessionStepDetail.builder().setSessionScope(session.getSessionScope()).setSessionAction(session.getAction()).setMatchCriteria(session.getMatchCriteria());
    Configuration config = _tracerouteContext.getConfigurations().get(currentNodeName);
    Map<String, IpAccessList> ipAccessLists = config.getIpAccessLists();
    Map<String, IpSpace> ipSpaces = config.getIpSpaces();
    // compute transformation. it will be applied after applying incoming ACL
    Transformation transformation = session.getTransformation();
    TransformationResult transformationResult = Optional.ofNullable(transformation).map(t -> TransformationEvaluator.eval(t, _currentFlow, inputIfaceName, ipAccessLists, ipSpaces)).orElse(null);
    if (transformation != null) {
        matchDetail.setTransformation(flowDiffs(_currentFlow, transformationResult.getOutputFlow()));
    }
    _steps.add(new MatchSessionStep(matchDetail.build()));
    // apply incoming ACL if any
    if (inputIfaceName != null) {
        FirewallSessionInterfaceInfo incomingIfaceSessionInfo = config.getAllInterfaces().get(inputIfaceName).getFirewallSessionInterfaceInfo();
        checkState(incomingIfaceSessionInfo != null, "Session matched, but interface %s does not have FirewallSessionInterfaceInfo.", inputIfaceName);
        String incomingAclName = incomingIfaceSessionInfo.getIncomingAclName();
        if (incomingAclName != null && applyFilter(ipAccessLists.get(incomingAclName), FilterType.INGRESS_FILTER) == DENIED) {
            return true;
        }
    }
    session.getAction().accept(new SessionActionVisitor<Void>() {

        @Override
        public Void visitAcceptVrf(Accept acceptVrf) {
            // Apply transformation to flow if present, then accept
            if (transformationResult != null) {
                _currentFlow = transformationResult.getOutputFlow();
                _steps.addAll(transformationResult.getTraceSteps());
            }
            buildAcceptTrace();
            return null;
        }

        @Override
        public Void visitPostNatFibLookup(PostNatFibLookup postNatFibLookup) {
            // Apply transformation first, if any
            if (transformationResult != null) {
                _currentFlow = transformationResult.getOutputFlow();
                _steps.addAll(transformationResult.getTraceSteps());
            }
            // Accept if the flow is destined for this vrf on this host.
            if (isAcceptedAtCurrentVrf(_currentFlow.getDstIp())) {
                buildAcceptTrace();
                return null;
            }
            fibLookup(_currentFlow.getDstIp(), currentNodeName, _vrfName, _tracerouteContext.getFib(currentNodeName, _vrfName).get(), (flowTracer, fibForward) -> {
                String outgoingIfaceName = fibForward.getInterfaceName();
                // TODO: handle ACLs
                // add ExitOutputIfaceStep
                flowTracer._steps.add(buildExitOutputIfaceStep(outgoingIfaceName));
                SortedSet<NodeInterfacePair> neighborIfaces = _tracerouteContext.getInterfaceNeighbors(currentNodeName, outgoingIfaceName);
                if (neighborIfaces.isEmpty()) {
                    FlowDisposition disposition = _tracerouteContext.computeDisposition(currentNodeName, outgoingIfaceName, _currentFlow.getDstIp());
                    flowTracer.buildArpFailureTrace(outgoingIfaceName, _currentFlow.getDstIp(), disposition);
                } else {
                    flowTracer.processOutgoingInterfaceEdges(outgoingIfaceName, fibForward.getArpIp().orElse(_currentFlow.getDstIp()), neighborIfaces);
                }
            });
            return null;
        }

        @Override
        public Void visitPreNatFibLookup(PreNatFibLookup preNatFibLookup) {
            // TODO Confirm it is possible to accept at this point in pipeline.
            if (isAcceptedAtCurrentVrf(_currentFlow.getDstIp())) {
                buildAcceptTrace();
                return null;
            }
            fibLookup(_currentFlow.getDstIp(), currentNodeName, _vrfName, _tracerouteContext.getFib(currentNodeName, _vrfName).get(), (flowTracer, fibForward) -> {
                // Routing happened, so it's finally time to apply transformation
                if (transformationResult != null) {
                    flowTracer._currentFlow = transformationResult.getOutputFlow();
                    flowTracer._steps.addAll(transformationResult.getTraceSteps());
                }
                String outgoingIfaceName = fibForward.getInterfaceName();
                // TODO: handle ACLs
                // add ExitOutputIfaceStep
                flowTracer._steps.add(buildExitOutputIfaceStep(outgoingIfaceName));
                SortedSet<NodeInterfacePair> neighborIfaces = _tracerouteContext.getInterfaceNeighbors(currentNodeName, outgoingIfaceName);
                Ip arpIp = fibForward.getArpIp().orElse(flowTracer._currentFlow.getDstIp());
                if (neighborIfaces.isEmpty()) {
                    FlowDisposition disposition = _tracerouteContext.computeDisposition(currentNodeName, outgoingIfaceName, flowTracer._currentFlow.getDstIp());
                    flowTracer.buildArpFailureTrace(outgoingIfaceName, arpIp, disposition);
                } else {
                    flowTracer.processOutgoingInterfaceEdges(outgoingIfaceName, arpIp, neighborIfaces);
                }
            });
            return null;
        }

        @Override
        public Void visitForwardOutInterface(ForwardOutInterface forwardOutInterface) {
            // Apply transformation first, if any
            Flow originalFlow = _currentFlow;
            if (transformationResult != null) {
                _currentFlow = transformationResult.getOutputFlow();
                _steps.addAll(transformationResult.getTraceSteps());
            }
            // cycle detection
            Breadcrumb breadcrumb = newBreadcrumb(currentNodeName, _vrfName, _ingressInterface, originalFlow);
            if (_breadcrumbs.contains(breadcrumb)) {
                buildLoopTrace(breadcrumb);
                return null;
            }
            _breadcrumbs.push(breadcrumb);
            try {
                NodeInterfacePair nextHop = forwardOutInterface.getNextHop();
                String outgoingInterfaceName = forwardOutInterface.getOutgoingInterface();
                Interface outgoingInterface = config.getAllInterfaces().get(outgoingInterfaceName);
                // apply outgoing ACL from firewall info, if any
                StepAction filterResult = Optional.ofNullable(outgoingInterface.getFirewallSessionInterfaceInfo()).map(FirewallSessionInterfaceInfo::getOutgoingAclName).map(outgoingAclName -> applyFilter(ipAccessLists.get(outgoingAclName), FilterType.EGRESS_FILTER)).orElse(null);
                if (filterResult == DENIED) {
                    return null;
                }
                // add ExitOutIfaceStep
                _steps.add(buildExitOutputIfaceStep(outgoingInterfaceName));
                if (nextHop == null) {
                    /* ARP error. Currently we can't use buildArpFailureTrace for sessions, because forwarding
                     * analysis disposition maps currently include routing conditions, which do not apply to
                     * sessions.
                     *
                     * ARP failure is only possible for sessions that have an outgoing interface but no next
                     * hop. This only happens when the user started the trace entering the outgoing interface.
                     * For now, just always call this EXITS_NETWORK. In the future we may want to apply the
                     * normal ARP error disposition logic, which would require factoring out routing-independent
                     * disposition maps in forwarding analysis.
                     */
                    buildArpFailureTrace(outgoingInterfaceName, originalFlow.getDstIp(), FlowDisposition.EXITS_NETWORK);
                    return null;
                }
                Hop hop = new Hop(new Node(currentNodeName), _steps);
                _hops.add(forwardedHop(hop, _originalFlow, checkNotNull(getVisitedBreadcrumb(), "Must push a breadcrumb before forwarding to next hop"), getHopSessionInfo()));
                if (_traceRecorder.tryRecordPartialTrace(_hops)) {
                    return null;
                }
                // Forward to neighbor.
                forkTracerFollowEdge(NodeInterfacePair.of(currentNodeName, outgoingInterfaceName), nextHop).processHop();
                return null;
            } finally {
                _breadcrumbs.pop();
            }
        }
    });
    return true;
}
Also used : SessionActionVisitor(org.batfish.datamodel.visitors.SessionActionVisitor) Hop(org.batfish.datamodel.flow.Hop) Accept(org.batfish.datamodel.flow.Accept) FibForward(org.batfish.datamodel.FibForward) TracerouteUtils.buildEnterSrcIfaceStep(org.batfish.dataplane.traceroute.TracerouteUtils.buildEnterSrcIfaceStep) FibNextVrf(org.batfish.datamodel.FibNextVrf) InboundStepDetail(org.batfish.datamodel.flow.InboundStep.InboundStepDetail) Interface(org.batfish.datamodel.Interface) FlowDiff.returnFlowDiffs(org.batfish.datamodel.FlowDiff.returnFlowDiffs) Flow(org.batfish.datamodel.Flow) MatchSessionStep(org.batfish.datamodel.flow.MatchSessionStep) Map(java.util.Map) HopInfo.forwardedHop(org.batfish.dataplane.traceroute.HopInfo.forwardedHop) PreNatFibLookup(org.batfish.datamodel.flow.PreNatFibLookup) INGRESS_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.INGRESS_FILTER) PacketPolicyResult(org.batfish.datamodel.packet_policy.PacketPolicyEvaluator.PacketPolicyResult) DeliveredStep(org.batfish.datamodel.flow.DeliveredStep) RoutingStep(org.batfish.datamodel.flow.RoutingStep) Set(java.util.Set) Evaluator(org.batfish.datamodel.acl.Evaluator) LoopStep(org.batfish.datamodel.flow.LoopStep) TraceAndReverseFlow(org.batfish.datamodel.flow.TraceAndReverseFlow) Step(org.batfish.datamodel.flow.Step) OriginatingSessionScope(org.batfish.datamodel.flow.OriginatingSessionScope) SetupSessionStepDetail(org.batfish.datamodel.flow.SetupSessionStep.SetupSessionStepDetail) Discarded(org.batfish.datamodel.flow.Discarded) Iterables(com.google.common.collect.Iterables) NULL_ROUTED(org.batfish.datamodel.flow.StepAction.NULL_ROUTED) Drop(org.batfish.datamodel.packet_policy.Drop) EGRESS_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.EGRESS_FILTER) TracerouteUtils.returnFlow(org.batfish.dataplane.traceroute.TracerouteUtils.returnFlow) IncomingSessionScope(org.batfish.datamodel.flow.IncomingSessionScope) FORWARDED(org.batfish.datamodel.flow.StepAction.FORWARDED) ArrayList(java.util.ArrayList) PolicyStep(org.batfish.datamodel.flow.PolicyStep) Builder(org.batfish.datamodel.flow.RoutingStep.Builder) MatchSessionStepDetail(org.batfish.datamodel.flow.MatchSessionStep.MatchSessionStepDetail) TracerouteUtils.fibEntriesToRouteInfos(org.batfish.dataplane.traceroute.TracerouteUtils.fibEntriesToRouteInfos) RoutingStepDetail(org.batfish.datamodel.flow.RoutingStep.RoutingStepDetail) HopInfo.failureHop(org.batfish.dataplane.traceroute.HopInfo.failureHop) BiConsumer(java.util.function.BiConsumer) ForwardedOutInterface(org.batfish.datamodel.flow.ForwardedOutInterface) ExitOutputIfaceStep(org.batfish.datamodel.flow.ExitOutputIfaceStep) ExitOutputIfaceStepDetail(org.batfish.datamodel.flow.ExitOutputIfaceStep.ExitOutputIfaceStepDetail) OriginateStepDetail(org.batfish.datamodel.flow.OriginateStep.OriginateStepDetail) Nullable(javax.annotation.Nullable) ForwardOutInterface(org.batfish.datamodel.flow.ForwardOutInterface) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) Comparator.nullsFirst(java.util.Comparator.nullsFirst) FirewallSessionInterfaceInfo(org.batfish.datamodel.FirewallSessionInterfaceInfo) TransformationEvaluator(org.batfish.datamodel.transformation.TransformationEvaluator) Fib(org.batfish.datamodel.Fib) FirewallSessionTraceInfo(org.batfish.datamodel.flow.FirewallSessionTraceInfo) FibLookup(org.batfish.datamodel.packet_policy.FibLookup) TreeMap(java.util.TreeMap) DelegatedToNextVrf(org.batfish.datamodel.flow.DelegatedToNextVrf) SOURCE_ORIGINATING_FROM_DEVICE(org.batfish.datamodel.acl.SourcesReferencedByIpAccessLists.SOURCE_ORIGINATING_FROM_DEVICE) VrfExprNameExtractor(org.batfish.datamodel.packet_policy.VrfExprNameExtractor) HopInfo.loopHop(org.batfish.dataplane.traceroute.HopInfo.loopHop) StepAction(org.batfish.datamodel.flow.StepAction) PERMITTED(org.batfish.datamodel.flow.StepAction.PERMITTED) IpProtocol(org.batfish.datamodel.IpProtocol) FilterType(org.batfish.datamodel.flow.FilterStep.FilterType) SortedSet(java.util.SortedSet) ForwardedIntoVxlanTunnel(org.batfish.datamodel.flow.ForwardedIntoVxlanTunnel) FibAction(org.batfish.datamodel.FibAction) NextHopVtep(org.batfish.datamodel.route.nh.NextHopVtep) Trace(org.batfish.datamodel.flow.Trace) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) FibLookupOverrideLookupIp(org.batfish.datamodel.packet_policy.FibLookupOverrideLookupIp) TracerouteUtils.getFinalActionForDisposition(org.batfish.dataplane.traceroute.TracerouteUtils.getFinalActionForDisposition) FORWARDED_TO_NEXT_VRF(org.batfish.datamodel.flow.StepAction.FORWARDED_TO_NEXT_VRF) PolicyStepDetail(org.batfish.datamodel.flow.PolicyStep.PolicyStepDetail) TransformationResult(org.batfish.datamodel.transformation.TransformationEvaluator.TransformationResult) ImmutableSet(com.google.common.collect.ImmutableSet) ActionVisitor(org.batfish.datamodel.packet_policy.ActionVisitor) SetupSessionStep(org.batfish.datamodel.flow.SetupSessionStep) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) FlowDisposition(org.batfish.datamodel.FlowDisposition) FibActionVisitor(org.batfish.datamodel.visitors.FibActionVisitor) TracerouteUtils.createFilterStep(org.batfish.dataplane.traceroute.TracerouteUtils.createFilterStep) Interner(com.google.common.collect.Interner) IpSpace(org.batfish.datamodel.IpSpace) Collectors(java.util.stream.Collectors) TRANSMITTED(org.batfish.datamodel.flow.StepAction.TRANSMITTED) ArpErrorStep(org.batfish.datamodel.flow.ArpErrorStep) Preconditions.checkState(com.google.common.base.Preconditions.checkState) SessionMatchExpr(org.batfish.datamodel.flow.SessionMatchExpr) List(java.util.List) EGRESS_ORIGINAL_FLOW_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.EGRESS_ORIGINAL_FLOW_FILTER) ConnectedRoute(org.batfish.datamodel.ConnectedRoute) FlowDiff.flowDiffs(org.batfish.datamodel.FlowDiff.flowDiffs) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) Ip(org.batfish.datamodel.Ip) Action(org.batfish.datamodel.FirewallSessionInterfaceInfo.Action) SessionAction(org.batfish.datamodel.flow.SessionAction) POST_TRANSFORMATION_INGRESS_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.POST_TRANSFORMATION_INGRESS_FILTER) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) InboundStep(org.batfish.datamodel.flow.InboundStep) HopInfo.successHop(org.batfish.dataplane.traceroute.HopInfo.successHop) Transformation(org.batfish.datamodel.transformation.Transformation) DeliveredStepDetail(org.batfish.datamodel.flow.DeliveredStep.DeliveredStepDetail) TransformationStep(org.batfish.datamodel.flow.TransformationStep) BatfishException(org.batfish.common.BatfishException) IpAccessList(org.batfish.datamodel.IpAccessList) Stack(java.util.Stack) HashSet(java.util.HashSet) OriginateStep(org.batfish.datamodel.flow.OriginateStep) ImmutableList(com.google.common.collect.ImmutableList) RouteInfo(org.batfish.datamodel.flow.RouteInfo) FirewallSessionVrfInfo(org.batfish.datamodel.FirewallSessionVrfInfo) Configuration(org.batfish.datamodel.Configuration) TracerouteUtils.sessionTransformation(org.batfish.dataplane.traceroute.TracerouteUtils.sessionTransformation) PostNatFibLookup(org.batfish.datamodel.flow.PostNatFibLookup) SessionScope(org.batfish.datamodel.flow.SessionScope) Comparator.comparing(java.util.Comparator.comparing) FibNullRoute(org.batfish.datamodel.FibNullRoute) PRE_TRANSFORMATION_EGRESS_FILTER(org.batfish.datamodel.flow.FilterStep.FilterType.PRE_TRANSFORMATION_EGRESS_FILTER) Nonnull(javax.annotation.Nonnull) DENIED(org.batfish.datamodel.flow.StepAction.DENIED) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Interners(com.google.common.collect.Interners) PacketPolicy(org.batfish.datamodel.packet_policy.PacketPolicy) Consumer(java.util.function.Consumer) Ordering(com.google.common.collect.Ordering) Node(org.batfish.datamodel.pojo.Node) ArpErrorStepDetail(org.batfish.datamodel.flow.ArpErrorStep.ArpErrorStepDetail) FilterStep(org.batfish.datamodel.flow.FilterStep) VisibleForTesting(com.google.common.annotations.VisibleForTesting) FibEntry(org.batfish.datamodel.FibEntry) Comparator(java.util.Comparator) PacketPolicyEvaluator(org.batfish.datamodel.packet_policy.PacketPolicyEvaluator) Transformation(org.batfish.datamodel.transformation.Transformation) TracerouteUtils.sessionTransformation(org.batfish.dataplane.traceroute.TracerouteUtils.sessionTransformation) Configuration(org.batfish.datamodel.Configuration) FibLookupOverrideLookupIp(org.batfish.datamodel.packet_policy.FibLookupOverrideLookupIp) Ip(org.batfish.datamodel.Ip) Node(org.batfish.datamodel.pojo.Node) FirewallSessionInterfaceInfo(org.batfish.datamodel.FirewallSessionInterfaceInfo) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) SortedSet(java.util.SortedSet) PreNatFibLookup(org.batfish.datamodel.flow.PreNatFibLookup) Accept(org.batfish.datamodel.flow.Accept) PostNatFibLookup(org.batfish.datamodel.flow.PostNatFibLookup) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) Hop(org.batfish.datamodel.flow.Hop) HopInfo.forwardedHop(org.batfish.dataplane.traceroute.HopInfo.forwardedHop) HopInfo.failureHop(org.batfish.dataplane.traceroute.HopInfo.failureHop) HopInfo.loopHop(org.batfish.dataplane.traceroute.HopInfo.loopHop) HopInfo.successHop(org.batfish.dataplane.traceroute.HopInfo.successHop) FlowDisposition(org.batfish.datamodel.FlowDisposition) Evaluator(org.batfish.datamodel.acl.Evaluator) TransformationEvaluator(org.batfish.datamodel.transformation.TransformationEvaluator) PacketPolicyEvaluator(org.batfish.datamodel.packet_policy.PacketPolicyEvaluator) FirewallSessionTraceInfo(org.batfish.datamodel.flow.FirewallSessionTraceInfo) Flow(org.batfish.datamodel.Flow) TraceAndReverseFlow(org.batfish.datamodel.flow.TraceAndReverseFlow) TracerouteUtils.returnFlow(org.batfish.dataplane.traceroute.TracerouteUtils.returnFlow) IpSpace(org.batfish.datamodel.IpSpace) StepAction(org.batfish.datamodel.flow.StepAction) MatchSessionStep(org.batfish.datamodel.flow.MatchSessionStep) ForwardOutInterface(org.batfish.datamodel.flow.ForwardOutInterface) MatchSessionStepDetail(org.batfish.datamodel.flow.MatchSessionStep.MatchSessionStepDetail) IpAccessList(org.batfish.datamodel.IpAccessList) TransformationResult(org.batfish.datamodel.transformation.TransformationEvaluator.TransformationResult) Interface(org.batfish.datamodel.Interface) ForwardedOutInterface(org.batfish.datamodel.flow.ForwardedOutInterface) ForwardOutInterface(org.batfish.datamodel.flow.ForwardOutInterface)

Example 4 with FibForward

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

the class FlowTracer method buildRoutingStep.

@VisibleForTesting
static RoutingStep buildRoutingStep(String vrf, FibAction fibAction, Set<FibEntry> fibEntries) {
    RoutingStep.Builder routingStepBuilder = RoutingStep.builder();
    List<RouteInfo> routeInfos = fibEntriesToRouteInfos(fibEntries);
    RoutingStepDetail.Builder routingStepDetailBuilder = RoutingStepDetail.builder().setVrf(vrf).setRoutes(routeInfos);
    fibAction.accept(new FibActionVisitor<Void>() {

        @Override
        public Void visitFibForward(FibForward fibForward) {
            assert !routeInfos.isEmpty();
            RouteInfo primaryRouteInfo = routeInfos.get(0);
            if (primaryRouteInfo.getNextHop() instanceof NextHopVtep) {
                NextHopVtep nhVtep = (NextHopVtep) primaryRouteInfo.getNextHop();
                routingStepDetailBuilder.setForwardingDetail(ForwardedIntoVxlanTunnel.of(nhVtep.getVni(), nhVtep.getVtepIp()));
            } else {
                Optional<Ip> maybeResolvedNextHopIp = fibForward.getArpIp();
                if (!maybeResolvedNextHopIp.isPresent()) {
                    routingStepDetailBuilder.setForwardingDetail(ForwardedOutInterface.of(fibForward.getInterfaceName()));
                } else {
                    Ip resolvedNextHopIp = maybeResolvedNextHopIp.get();
                    routingStepDetailBuilder.setForwardingDetail(ForwardedOutInterface.of(fibForward.getInterfaceName(), resolvedNextHopIp)).setArpIp(resolvedNextHopIp);
                }
            }
            routingStepDetailBuilder.setOutputInterface(fibForward.getInterfaceName());
            routingStepBuilder.setAction(FORWARDED);
            return null;
        }

        @Override
        public Void visitFibNextVrf(FibNextVrf fibNextVrf) {
            routingStepDetailBuilder.setForwardingDetail(DelegatedToNextVrf.of(fibNextVrf.getNextVrf()));
            routingStepBuilder.setAction(FORWARDED_TO_NEXT_VRF);
            return null;
        }

        @Override
        public Void visitFibNullRoute(FibNullRoute fibNullRoute) {
            routingStepDetailBuilder.setForwardingDetail(Discarded.instance());
            routingStepBuilder.setAction(NULL_ROUTED);
            return null;
        }
    });
    return routingStepBuilder.setDetail(routingStepDetailBuilder.build()).build();
}
Also used : Optional(java.util.Optional) FibNullRoute(org.batfish.datamodel.FibNullRoute) FibLookupOverrideLookupIp(org.batfish.datamodel.packet_policy.FibLookupOverrideLookupIp) Ip(org.batfish.datamodel.Ip) RoutingStep(org.batfish.datamodel.flow.RoutingStep) FibNextVrf(org.batfish.datamodel.FibNextVrf) FibForward(org.batfish.datamodel.FibForward) RoutingStepDetail(org.batfish.datamodel.flow.RoutingStep.RoutingStepDetail) Builder(org.batfish.datamodel.flow.RoutingStep.Builder) RouteInfo(org.batfish.datamodel.flow.RouteInfo) NextHopVtep(org.batfish.datamodel.route.nh.NextHopVtep) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

FibForward (org.batfish.datamodel.FibForward)4 RouteInfo (org.batfish.datamodel.flow.RouteInfo)4 RoutingStep (org.batfish.datamodel.flow.RoutingStep)4 VisibleForTesting (com.google.common.annotations.VisibleForTesting)3 Optional (java.util.Optional)3 FibEntry (org.batfish.datamodel.FibEntry)3 MoreObjects.firstNonNull (com.google.common.base.MoreObjects.firstNonNull)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)2 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)2 Preconditions.checkState (com.google.common.base.Preconditions.checkState)2 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 ImmutableSet (com.google.common.collect.ImmutableSet)2 ImmutableSortedSet (com.google.common.collect.ImmutableSortedSet)2 Interner (com.google.common.collect.Interner)2 Interners (com.google.common.collect.Interners)2 Iterables (com.google.common.collect.Iterables)2 Ordering (com.google.common.collect.Ordering)2 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2