Search in sources :

Example 1 with Edge

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

the class Client method initEnvironment.

private boolean initEnvironment(String paramsLine, FileWriter outWriter) {
    InitEnvironmentParams params = parseInitEnvironmentParams(paramsLine);
    String newEnvName;
    String paramsLocation = params.getSourcePath();
    String paramsName = params.getNewEnvironmentName();
    String paramsPrefix = params.getNewEnvironmentPrefix();
    String testrigName = params.getDoDelta() ? _currDeltaTestrig : _currTestrig;
    if (paramsName != null) {
        newEnvName = paramsName;
    } else if (paramsPrefix != null) {
        newEnvName = paramsPrefix + UUID.randomUUID();
    } else {
        newEnvName = DEFAULT_DELTA_ENV_PREFIX + UUID.randomUUID();
    }
    String paramsBaseEnv = params.getSourceEnvironmentName();
    String baseEnvName = paramsBaseEnv != null ? paramsBaseEnv : BfConsts.RELPATH_DEFAULT_ENVIRONMENT_NAME;
    String fileToSend;
    SortedSet<String> paramsNodeBlacklist = params.getNodeBlacklist();
    SortedSet<NodeInterfacePair> paramsInterfaceBlacklist = params.getInterfaceBlacklist();
    SortedSet<Edge> paramsEdgeBlacklist = params.getEdgeBlacklist();
    if (paramsLocation == null || Files.isDirectory(Paths.get(paramsLocation)) || !paramsNodeBlacklist.isEmpty() || !paramsInterfaceBlacklist.isEmpty() || !paramsEdgeBlacklist.isEmpty()) {
        Path tempFile = CommonUtil.createTempFile("batfish_client_tmp_env_", ".zip");
        fileToSend = tempFile.toString();
        if (paramsLocation != null && Files.isDirectory(Paths.get(paramsLocation)) && paramsNodeBlacklist.isEmpty() && paramsInterfaceBlacklist.isEmpty() && paramsEdgeBlacklist.isEmpty()) {
            ZipUtility.zipFiles(Paths.get(paramsLocation), tempFile);
        } else {
            Path tempDir = CommonUtil.createTempDirectory("batfish_client_tmp_env_");
            if (paramsLocation != null) {
                if (Files.isDirectory(Paths.get(paramsLocation))) {
                    CommonUtil.copyDirectory(Paths.get(paramsLocation), tempDir);
                } else if (Files.isRegularFile(Paths.get(paramsLocation))) {
                    UnzipUtility.unzip(Paths.get(paramsLocation), tempDir);
                } else {
                    throw new BatfishException("Invalid environment directory or zip: '" + paramsLocation + "'");
                }
            }
            if (!paramsNodeBlacklist.isEmpty()) {
                String nodeBlacklistText;
                try {
                    nodeBlacklistText = BatfishObjectMapper.writePrettyString(paramsNodeBlacklist);
                } catch (JsonProcessingException e) {
                    throw new BatfishException("Failed to write node blacklist to string", e);
                }
                Path nodeBlacklistFilePath = tempDir.resolve(BfConsts.RELPATH_NODE_BLACKLIST_FILE);
                CommonUtil.writeFile(nodeBlacklistFilePath, nodeBlacklistText);
            }
            if (!paramsInterfaceBlacklist.isEmpty()) {
                String interfaceBlacklistText;
                try {
                    interfaceBlacklistText = BatfishObjectMapper.writePrettyString(paramsInterfaceBlacklist);
                } catch (JsonProcessingException e) {
                    throw new BatfishException("Failed to write interface blacklist to string", e);
                }
                Path interfaceBlacklistFilePath = tempDir.resolve(BfConsts.RELPATH_INTERFACE_BLACKLIST_FILE);
                CommonUtil.writeFile(interfaceBlacklistFilePath, interfaceBlacklistText);
            }
            if (!paramsEdgeBlacklist.isEmpty()) {
                String edgeBlacklistText;
                try {
                    edgeBlacklistText = BatfishObjectMapper.writePrettyString(paramsEdgeBlacklist);
                } catch (JsonProcessingException e) {
                    throw new BatfishException("Failed to write edge blacklist to string", e);
                }
                Path edgeBlacklistFilePath = tempDir.resolve(BfConsts.RELPATH_EDGE_BLACKLIST_FILE);
                CommonUtil.writeFile(edgeBlacklistFilePath, edgeBlacklistText);
            }
            ZipUtility.zipFiles(tempDir, tempFile);
        }
    } else if (Files.isRegularFile(Paths.get(paramsLocation))) {
        fileToSend = paramsLocation;
    } else {
        throw new BatfishException("Invalid environment directory or zip: '" + paramsLocation + "'");
    }
    if (!uploadEnv(fileToSend, testrigName, newEnvName, baseEnvName)) {
        return false;
    }
    _currDeltaEnv = newEnvName;
    _currDeltaTestrig = _currTestrig;
    _logger.output("Active delta testrig->environment is set");
    _logger.infof("to %s->%s\n", _currDeltaTestrig, _currDeltaEnv);
    _logger.output("\n");
    WorkItem wItemProcessEnv = WorkItemBuilder.getWorkItemProcessEnvironment(_currContainerName, _currDeltaTestrig, _currDeltaEnv);
    if (!execute(wItemProcessEnv, outWriter)) {
        return false;
    }
    return true;
}
Also used : Path(java.nio.file.Path) BatfishException(org.batfish.common.BatfishException) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) InitEnvironmentParams(org.batfish.client.params.InitEnvironmentParams) Edge(org.batfish.datamodel.Edge) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) WorkItem(org.batfish.common.WorkItem)

Example 2 with Edge

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

the class CommonUtil method synthesizeTopology.

public static Topology synthesizeTopology(Map<String, Configuration> configurations) {
    SortedSet<Edge> edges = new TreeSet<>();
    Map<Prefix, Set<NodeInterfacePair>> prefixInterfaces = new HashMap<>();
    configurations.forEach((nodeName, node) -> {
        for (Entry<String, Interface> e : node.getInterfaces().entrySet()) {
            String ifaceName = e.getKey();
            Interface iface = e.getValue();
            if (!iface.isLoopback(node.getConfigurationFormat()) && iface.getActive()) {
                for (InterfaceAddress address : iface.getAllAddresses()) {
                    if (address.getNetworkBits() < Prefix.MAX_PREFIX_LENGTH) {
                        Prefix prefix = address.getPrefix();
                        NodeInterfacePair pair = new NodeInterfacePair(nodeName, ifaceName);
                        Set<NodeInterfacePair> interfaceBucket = prefixInterfaces.computeIfAbsent(prefix, k -> new HashSet<>());
                        interfaceBucket.add(pair);
                    }
                }
            }
        }
    });
    for (Set<NodeInterfacePair> bucket : prefixInterfaces.values()) {
        for (NodeInterfacePair p1 : bucket) {
            for (NodeInterfacePair p2 : bucket) {
                if (!p1.equals(p2)) {
                    Edge edge = new Edge(p1, p2);
                    edges.add(edge);
                }
            }
        }
    }
    return new Topology(edges);
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) SortedSet(java.util.SortedSet) ImmutableSet(com.google.common.collect.ImmutableSet) HashSet(java.util.HashSet) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) Prefix(org.batfish.datamodel.Prefix) Topology(org.batfish.datamodel.Topology) TreeSet(java.util.TreeSet) Edge(org.batfish.datamodel.Edge) Interface(org.batfish.datamodel.Interface)

Example 3 with Edge

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

the class BdpEngine method processFlows.

@Override
public SortedMap<Flow, Set<FlowTrace>> processFlows(DataPlane dataPlane, Set<Flow> flows) {
    Map<Flow, Set<FlowTrace>> flowTraces = new ConcurrentHashMap<>();
    BdpDataPlane dp = (BdpDataPlane) dataPlane;
    flows.parallelStream().forEach(flow -> {
        Set<FlowTrace> currentFlowTraces = new TreeSet<>();
        flowTraces.put(flow, currentFlowTraces);
        String ingressNodeName = flow.getIngressNode();
        if (ingressNodeName == null) {
            throw new BatfishException("Cannot construct flow trace since ingressNode is not specified");
        }
        Ip dstIp = flow.getDstIp();
        if (dstIp == null) {
            throw new BatfishException("Cannot construct flow trace since dstIp is not specified");
        }
        Set<Edge> visitedEdges = Collections.emptySet();
        List<FlowTraceHop> hops = new ArrayList<>();
        Set<String> dstIpOwners = dp._ipOwners.get(dstIp);
        SortedSet<Edge> edges = new TreeSet<>();
        String ingressInterfaceName = flow.getIngressInterface();
        if (ingressInterfaceName != null) {
            edges.add(new Edge(TRACEROUTE_INGRESS_NODE_NAME, TRACEROUTE_INGRESS_NODE_INTERFACE_NAME, ingressNodeName, ingressInterfaceName));
            processCurrentNextHopInterfaceEdges(dp, TRACEROUTE_INGRESS_NODE_NAME, visitedEdges, hops, currentFlowTraces, flow, flow, dstIp, dstIpOwners, null, new TreeSet<>(), null, null, edges, false);
        } else {
            collectFlowTraces(dp, ingressNodeName, visitedEdges, hops, currentFlowTraces, flow, flow);
        }
    });
    return new TreeMap<>(flowTraces);
}
Also used : BatfishException(org.batfish.common.BatfishException) SortedSet(java.util.SortedSet) Set(java.util.Set) TreeSet(java.util.TreeSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) Ip(org.batfish.datamodel.Ip) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) Flow(org.batfish.datamodel.Flow) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) TreeSet(java.util.TreeSet) FlowTrace(org.batfish.datamodel.FlowTrace) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Edge(org.batfish.datamodel.Edge)

Example 4 with Edge

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

the class BdpEngine method collectFlowTraces.

private void collectFlowTraces(BdpDataPlane dp, String currentNodeName, Set<Edge> visitedEdges, List<FlowTraceHop> hopsSoFar, Set<FlowTrace> flowTraces, Flow originalFlow, Flow transformedFlow) {
    Ip dstIp = transformedFlow.getDstIp();
    Set<String> dstIpOwners = dp._ipOwners.get(dstIp);
    if (dstIpOwners != null && dstIpOwners.contains(currentNodeName)) {
        FlowTrace trace = new FlowTrace(FlowDisposition.ACCEPTED, hopsSoFar, FlowDisposition.ACCEPTED.toString());
        flowTraces.add(trace);
    } else {
        Node currentNode = dp._nodes.get(currentNodeName);
        String vrfName;
        if (hopsSoFar.isEmpty()) {
            vrfName = transformedFlow.getIngressVrf();
        } else {
            FlowTraceHop lastHop = hopsSoFar.get(hopsSoFar.size() - 1);
            String receivingInterface = lastHop.getEdge().getInt2();
            vrfName = currentNode._c.getInterfaces().get(receivingInterface).getVrf().getName();
        }
        VirtualRouter currentVirtualRouter = currentNode._virtualRouters.get(vrfName);
        Map<AbstractRoute, Map<String, Map<Ip, Set<AbstractRoute>>>> nextHopInterfacesByRoute = currentVirtualRouter._fib.getNextHopInterfacesByRoute(dstIp);
        Map<String, Map<Ip, Set<AbstractRoute>>> nextHopInterfacesWithRoutes = currentVirtualRouter._fib.getNextHopInterfaces(dstIp);
        if (!nextHopInterfacesWithRoutes.isEmpty()) {
            for (String nextHopInterfaceName : nextHopInterfacesWithRoutes.keySet()) {
                // SortedSet<String> routesForThisNextHopInterface = new
                // TreeSet<>(
                // nextHopInterfacesWithRoutes.get(nextHopInterfaceName)
                // .stream().map(ar -> ar.toString())
                // .collect(Collectors.toSet()));
                SortedSet<String> routesForThisNextHopInterface = new TreeSet<>();
                Ip finalNextHopIp = null;
                for (Entry<AbstractRoute, Map<String, Map<Ip, Set<AbstractRoute>>>> e : nextHopInterfacesByRoute.entrySet()) {
                    AbstractRoute routeCandidate = e.getKey();
                    Map<String, Map<Ip, Set<AbstractRoute>>> routeCandidateNextHopInterfaces = e.getValue();
                    if (routeCandidateNextHopInterfaces.containsKey(nextHopInterfaceName)) {
                        Ip nextHopIp = routeCandidate.getNextHopIp();
                        if (!nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) {
                            Set<Ip> finalNextHopIps = routeCandidateNextHopInterfaces.get(nextHopInterfaceName).keySet();
                            if (finalNextHopIps.size() > 1) {
                                throw new BatfishException("Can not currently handle multiple final next hop ips across multiple " + "routes leading to one next hop interface");
                            }
                            Ip newFinalNextHopIp = finalNextHopIps.iterator().next();
                            if (finalNextHopIp != null && !newFinalNextHopIp.equals(finalNextHopIp)) {
                                throw new BatfishException("Can not currently handle multiple final next hop ips for same next hop " + "interface");
                            }
                            finalNextHopIp = newFinalNextHopIp;
                        }
                        routesForThisNextHopInterface.add(routeCandidate + "_fnhip:" + finalNextHopIp);
                    }
                }
                NodeInterfacePair nextHopInterface = new NodeInterfacePair(currentNodeName, nextHopInterfaceName);
                if (nextHopInterfaceName.equals(Interface.NULL_INTERFACE_NAME)) {
                    List<FlowTraceHop> newHops = new ArrayList<>(hopsSoFar);
                    Edge newEdge = new Edge(nextHopInterface, new NodeInterfacePair(Configuration.NODE_NONE_NAME, Interface.NULL_INTERFACE_NAME));
                    FlowTraceHop newHop = new FlowTraceHop(newEdge, routesForThisNextHopInterface, hopFlow(originalFlow, transformedFlow));
                    newHops.add(newHop);
                    FlowTrace nullRouteTrace = new FlowTrace(FlowDisposition.NULL_ROUTED, newHops, FlowDisposition.NULL_ROUTED.toString());
                    flowTraces.add(nullRouteTrace);
                } else {
                    Interface outgoingInterface = dp._nodes.get(nextHopInterface.getHostname())._c.getInterfaces().get(nextHopInterface.getInterface());
                    // Apply any relevant source NAT rules.
                    transformedFlow = applySourceNat(transformedFlow, outgoingInterface.getSourceNats());
                    SortedSet<Edge> edges = dp._topology.getInterfaceEdges().get(nextHopInterface);
                    if (edges != null) {
                        boolean continueToNextNextHopInterface = false;
                        continueToNextNextHopInterface = processCurrentNextHopInterfaceEdges(dp, currentNodeName, visitedEdges, hopsSoFar, flowTraces, originalFlow, transformedFlow, dstIp, dstIpOwners, nextHopInterfaceName, routesForThisNextHopInterface, finalNextHopIp, nextHopInterface, edges, true);
                        if (continueToNextNextHopInterface) {
                            continue;
                        }
                    } else {
                        /*
               * Should only get here for delta environment where
               * non-flow-sink interface from base has no edges in delta
               */
                        Edge neighborUnreachbleEdge = new Edge(nextHopInterface, new NodeInterfacePair(Configuration.NODE_NONE_NAME, Interface.NULL_INTERFACE_NAME));
                        FlowTraceHop neighborUnreachableHop = new FlowTraceHop(neighborUnreachbleEdge, routesForThisNextHopInterface, hopFlow(originalFlow, transformedFlow));
                        List<FlowTraceHop> newHops = new ArrayList<>(hopsSoFar);
                        newHops.add(neighborUnreachableHop);
                        /**
                         * Check if denied out. If not, make standard neighbor-unreachable trace.
                         */
                        IpAccessList outFilter = outgoingInterface.getOutgoingFilter();
                        boolean denied = false;
                        if (outFilter != null) {
                            FlowDisposition disposition = FlowDisposition.DENIED_OUT;
                            denied = flowTraceDeniedHelper(flowTraces, originalFlow, transformedFlow, newHops, outFilter, disposition);
                        }
                        if (!denied) {
                            FlowTrace trace = new FlowTrace(FlowDisposition.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK, newHops, FlowDisposition.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK.toString());
                            flowTraces.add(trace);
                        }
                    }
                }
            }
        } else {
            FlowTrace trace = new FlowTrace(FlowDisposition.NO_ROUTE, hopsSoFar, FlowDisposition.NO_ROUTE.toString());
            flowTraces.add(trace);
        }
    }
}
Also used : SortedSet(java.util.SortedSet) Set(java.util.Set) TreeSet(java.util.TreeSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) Ip(org.batfish.datamodel.Ip) ArrayList(java.util.ArrayList) TreeSet(java.util.TreeSet) AbstractRoute(org.batfish.datamodel.AbstractRoute) BatfishException(org.batfish.common.BatfishException) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) FlowDisposition(org.batfish.datamodel.FlowDisposition) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) FlowTrace(org.batfish.datamodel.FlowTrace) IpAccessList(org.batfish.datamodel.IpAccessList) LRUMap(org.apache.commons.collections4.map.LRUMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) Edge(org.batfish.datamodel.Edge) Interface(org.batfish.datamodel.Interface)

Example 5 with Edge

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

the class BdpEngine method flowTraceDeniedHelper.

private boolean flowTraceDeniedHelper(Set<FlowTrace> flowTraces, Flow originalFlow, Flow transformedFlow, List<FlowTraceHop> newHops, IpAccessList filter, FlowDisposition disposition) {
    boolean out = disposition == FlowDisposition.DENIED_OUT;
    FilterResult outResult = filter.filter(transformedFlow);
    boolean denied = outResult.getAction() == LineAction.REJECT;
    if (denied) {
        String outFilterName = filter.getName();
        Integer matchLine = outResult.getMatchLine();
        String lineDesc;
        if (matchLine != null) {
            lineDesc = filter.getLines().get(matchLine).getName();
            if (lineDesc == null) {
                lineDesc = "line:" + matchLine;
            }
        } else {
            lineDesc = "no-match";
        }
        String notes = disposition + "{" + outFilterName + "}{" + lineDesc + "}";
        if (out) {
            FlowTraceHop lastHop = newHops.get(newHops.size() - 1);
            newHops.remove(newHops.size() - 1);
            Edge lastEdge = lastHop.getEdge();
            Edge deniedOutEdge = new Edge(lastEdge.getFirst(), new NodeInterfacePair(Configuration.NODE_NONE_NAME, Interface.NULL_INTERFACE_NAME));
            FlowTraceHop deniedOutHop = new FlowTraceHop(deniedOutEdge, lastHop.getRoutes(), hopFlow(originalFlow, transformedFlow));
            newHops.add(deniedOutHop);
        }
        FlowTrace trace = new FlowTrace(disposition, newHops, notes);
        flowTraces.add(trace);
    }
    return denied;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) FlowTrace(org.batfish.datamodel.FlowTrace) FilterResult(org.batfish.datamodel.FilterResult) Edge(org.batfish.datamodel.Edge)

Aggregations

Edge (org.batfish.datamodel.Edge)46 Configuration (org.batfish.datamodel.Configuration)23 Interface (org.batfish.datamodel.Interface)19 Topology (org.batfish.datamodel.Topology)17 Test (org.junit.Test)17 Ip (org.batfish.datamodel.Ip)12 NodeInterfacePair (org.batfish.datamodel.collections.NodeInterfacePair)12 Vrf (org.batfish.datamodel.Vrf)10 BatfishException (org.batfish.common.BatfishException)9 FlowTrace (org.batfish.datamodel.FlowTrace)8 ArrayList (java.util.ArrayList)7 Set (java.util.Set)7 TreeSet (java.util.TreeSet)7 IpAccessList (org.batfish.datamodel.IpAccessList)7 HostConfiguration (org.batfish.representation.host.HostConfiguration)7 VendorConfiguration (org.batfish.vendor.VendorConfiguration)7 SynthesizerInputMatchers.hasArpTrueEdge (org.batfish.z3.matchers.SynthesizerInputMatchers.hasArpTrueEdge)7 HashMap (java.util.HashMap)6 FlowTraceHop (org.batfish.datamodel.FlowTraceHop)6 AclPermit (org.batfish.z3.state.AclPermit)6