Search in sources :

Example 1 with Configuration

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

the class CommonUtil method initRemoteIpsecVpns.

public static void initRemoteIpsecVpns(Map<String, Configuration> configurations) {
    Map<IpsecVpn, Ip> vpnRemoteIps = new IdentityHashMap<>();
    Map<Ip, Set<IpsecVpn>> externalIpVpnMap = new HashMap<>();
    SetMultimap<Ip, IpWildcardSetIpSpace> privateIpsByPublicIp = initPrivateIpsByPublicIp(configurations);
    for (Configuration c : configurations.values()) {
        for (IpsecVpn ipsecVpn : c.getIpsecVpns().values()) {
            Ip remoteIp = ipsecVpn.getIkeGateway().getAddress();
            vpnRemoteIps.put(ipsecVpn, remoteIp);
            Set<InterfaceAddress> externalAddresses = ipsecVpn.getIkeGateway().getExternalInterface().getAllAddresses();
            for (InterfaceAddress address : externalAddresses) {
                Ip ip = address.getIp();
                Set<IpsecVpn> vpnsUsingExternalAddress = externalIpVpnMap.computeIfAbsent(ip, k -> Sets.newIdentityHashSet());
                vpnsUsingExternalAddress.add(ipsecVpn);
            }
        }
    }
    for (Entry<IpsecVpn, Ip> e : vpnRemoteIps.entrySet()) {
        IpsecVpn ipsecVpn = e.getKey();
        Ip remoteIp = e.getValue();
        Ip localIp = ipsecVpn.getIkeGateway().getLocalIp();
        ipsecVpn.initCandidateRemoteVpns();
        Set<IpsecVpn> remoteIpsecVpnCandidates = externalIpVpnMap.get(remoteIp);
        if (remoteIpsecVpnCandidates != null) {
            for (IpsecVpn remoteIpsecVpnCandidate : remoteIpsecVpnCandidates) {
                Ip remoteIpsecVpnLocalAddress = remoteIpsecVpnCandidate.getIkeGateway().getLocalIp();
                if (remoteIpsecVpnLocalAddress != null && !remoteIpsecVpnLocalAddress.equals(remoteIp)) {
                    continue;
                }
                Ip reciprocalRemoteAddress = vpnRemoteIps.get(remoteIpsecVpnCandidate);
                Set<IpsecVpn> reciprocalVpns = externalIpVpnMap.get(reciprocalRemoteAddress);
                if (reciprocalVpns == null) {
                    Set<IpWildcardSetIpSpace> privateIpsBehindReciprocalRemoteAddress = privateIpsByPublicIp.get(reciprocalRemoteAddress);
                    if (privateIpsBehindReciprocalRemoteAddress != null && privateIpsBehindReciprocalRemoteAddress.stream().anyMatch(ipSpace -> ipSpace.containsIp(localIp))) {
                        reciprocalVpns = externalIpVpnMap.get(localIp);
                        ipsecVpn.setRemoteIpsecVpn(remoteIpsecVpnCandidate);
                        ipsecVpn.getCandidateRemoteIpsecVpns().add(remoteIpsecVpnCandidate);
                        remoteIpsecVpnCandidate.initCandidateRemoteVpns();
                        remoteIpsecVpnCandidate.setRemoteIpsecVpn(ipsecVpn);
                        remoteIpsecVpnCandidate.getCandidateRemoteIpsecVpns().add(ipsecVpn);
                    }
                } else if (reciprocalVpns.contains(ipsecVpn)) {
                    ipsecVpn.setRemoteIpsecVpn(remoteIpsecVpnCandidate);
                    ipsecVpn.getCandidateRemoteIpsecVpns().add(remoteIpsecVpnCandidate);
                }
            }
        }
    }
}
Also used : IpsecVpn(org.batfish.datamodel.IpsecVpn) SSLEngineConfigurator(org.glassfish.grizzly.ssl.SSLEngineConfigurator) SSLContext(javax.net.ssl.SSLContext) FileTime(java.nio.file.attribute.FileTime) StringUtils(org.apache.commons.lang3.StringUtils) Configurations(org.apache.commons.configuration2.builder.fluent.Configurations) Interface(org.batfish.datamodel.Interface) DirectoryStream(java.nio.file.DirectoryStream) BfConsts(org.batfish.common.BfConsts) Flow(org.batfish.datamodel.Flow) Topology(org.batfish.datamodel.Topology) Map(java.util.Map) ResourceConfig(org.glassfish.jersey.server.ResourceConfig) Pair(org.batfish.common.Pair) Path(java.nio.file.Path) DataPlane(org.batfish.datamodel.DataPlane) VrrpGroup(org.batfish.datamodel.VrrpGroup) ClientTracingFeature(io.opentracing.contrib.jaxrs2.client.ClientTracingFeature) Set(java.util.Set) FileAttribute(java.nio.file.attribute.FileAttribute) StandardCharsets(java.nio.charset.StandardCharsets) DirectoryIteratorException(java.nio.file.DirectoryIteratorException) IOUtils(org.apache.commons.io.IOUtils) Stream(java.util.stream.Stream) Supplier(java.util.function.Supplier) TreeSet(java.util.TreeSet) JSONAssert(org.skyscreamer.jsonassert.JSONAssert) MustBeClosed(com.google.errorprone.annotations.MustBeClosed) SSLSession(javax.net.ssl.SSLSession) FlowProcessor(org.batfish.common.plugin.FlowProcessor) BiConsumer(java.util.function.BiConsumer) SSLContextConfigurator(org.glassfish.grizzly.ssl.SSLContextConfigurator) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Nullable(javax.annotation.Nullable) Files(java.nio.file.Files) Route(org.batfish.datamodel.Route) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) FileUtils(org.apache.commons.io.FileUtils) KeyManager(javax.net.ssl.KeyManager) TreeMap(java.util.TreeMap) Paths(java.nio.file.Paths) X509TrustManager(javax.net.ssl.X509TrustManager) BufferedReader(java.io.BufferedReader) X509Certificate(java.security.cert.X509Certificate) IpsecVpn(org.batfish.datamodel.IpsecVpn) NoSuchFileException(java.nio.file.NoSuchFileException) IpProtocol(org.batfish.datamodel.IpProtocol) SortedSet(java.util.SortedSet) URL(java.net.URL) TrustManager(javax.net.ssl.TrustManager) FlowTrace(org.batfish.datamodel.FlowTrace) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) OspfNeighbor(org.batfish.datamodel.OspfNeighbor) Edge(org.batfish.datamodel.Edge) IpWildcardSetIpSpace(org.batfish.datamodel.IpWildcardSetIpSpace) OspfProcess(org.batfish.datamodel.OspfProcess) URI(java.net.URI) HostnameVerifier(javax.net.ssl.HostnameVerifier) NamedPort(org.batfish.datamodel.NamedPort) Vrf(org.batfish.datamodel.Vrf) OspfArea(org.batfish.datamodel.OspfArea) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) ImmutableSet(com.google.common.collect.ImmutableSet) IdentityHashMap(java.util.IdentityHashMap) PatternSyntaxException(java.util.regex.PatternSyntaxException) TrustManagerFactory(javax.net.ssl.TrustManagerFactory) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) FlowDisposition(org.batfish.datamodel.FlowDisposition) KeyStore(java.security.KeyStore) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) FileNotFoundException(java.io.FileNotFoundException) List(java.util.List) Entry(java.util.Map.Entry) Pattern(java.util.regex.Pattern) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) SortedMap(java.util.SortedMap) IpWildcard(org.batfish.datamodel.IpWildcard) Ip(org.batfish.datamodel.Ip) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) Hashing(com.google.common.hash.Hashing) HashMap(java.util.HashMap) BatfishException(org.batfish.common.BatfishException) BgpProcess(org.batfish.datamodel.BgpProcess) Function(java.util.function.Function) HashSet(java.util.HashSet) ClientBuilder(javax.ws.rs.client.ClientBuilder) Configuration(org.batfish.datamodel.Configuration) OutputStreamWriter(java.io.OutputStreamWriter) OutputStream(java.io.OutputStream) IpLink(org.batfish.datamodel.IpLink) Iterator(java.util.Iterator) MalformedURLException(java.net.MalformedURLException) KeyManagerFactory(javax.net.ssl.KeyManagerFactory) GlobalTracer(io.opentracing.util.GlobalTracer) FileInputStream(java.io.FileInputStream) SetMultimap(com.google.common.collect.SetMultimap) Consumer(java.util.function.Consumer) GrizzlyHttpServerFactory(org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) InputStream(java.io.InputStream) Prefix(org.batfish.datamodel.Prefix) Set(java.util.Set) TreeSet(java.util.TreeSet) SortedSet(java.util.SortedSet) ImmutableSet(com.google.common.collect.ImmutableSet) HashSet(java.util.HashSet) Configuration(org.batfish.datamodel.Configuration) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Ip(org.batfish.datamodel.Ip) IdentityHashMap(java.util.IdentityHashMap) IpWildcardSetIpSpace(org.batfish.datamodel.IpWildcardSetIpSpace)

Example 2 with Configuration

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

the class CommonUtil method initRemoteBgpNeighbors.

/**
 * Initialize BGP neighbors for all nodes.
 *
 * @param configurations map of all configurations, keyed by hostname
 * @param ipOwners mapping of Ips to a set of nodes (hostnames) that owns those IPs
 * @param checkReachability whether bgp neighbor reachability should be checked
 * @param flowProcessor dataplane plugin to use to check reachability. Must not be {@code null} if
 *     {@code checkReachability = true}
 * @param dp dataplane to use to check reachability. Must not be {@code null} if {@code
 *     checkReachability = true}
 */
public static void initRemoteBgpNeighbors(Map<String, Configuration> configurations, Map<Ip, Set<String>> ipOwners, boolean checkReachability, @Nullable FlowProcessor flowProcessor, @Nullable DataPlane dp) {
    // TODO: handle duplicate ips on different vrfs
    Map<BgpNeighbor, Ip> remoteAddresses = new IdentityHashMap<>();
    Map<Ip, Set<BgpNeighbor>> localAddresses = new HashMap<>();
    /*
     * Construct maps indicating which neighbor owns which Ip Address
     */
    for (Configuration node : configurations.values()) {
        String hostname = node.getHostname();
        for (Vrf vrf : node.getVrfs().values()) {
            BgpProcess proc = vrf.getBgpProcess();
            if (proc == null) {
                // nothing to do if no bgp process on this VRF
                continue;
            }
            for (BgpNeighbor bgpNeighbor : proc.getNeighbors().values()) {
                /*
           * Begin by initializing candidate neighbors to an empty set
           */
                bgpNeighbor.initCandidateRemoteBgpNeighbors();
                // Skip things we don't handle
                if (bgpNeighbor.getPrefix().getPrefixLength() < Prefix.MAX_PREFIX_LENGTH) {
                    throw new BatfishException(hostname + ": Do not support dynamic bgp sessions at this time: " + bgpNeighbor.getPrefix());
                }
                Ip remoteAddress = bgpNeighbor.getAddress();
                if (remoteAddress == null) {
                    throw new BatfishException(hostname + ": Could not determine remote address of bgp neighbor: " + bgpNeighbor);
                }
                Ip localAddress = bgpNeighbor.getLocalIp();
                if (localAddress == null || !ipOwners.containsKey(localAddress) || !ipOwners.get(localAddress).contains(hostname)) {
                    // Local address is not owned by anybody
                    continue;
                }
                remoteAddresses.put(bgpNeighbor, remoteAddress);
                // Add this neighbor as owner of its local address
                localAddresses.computeIfAbsent(localAddress, k -> Collections.newSetFromMap(new IdentityHashMap<>())).add(bgpNeighbor);
            }
        }
    }
    /*
     * For each neighbor, construct the set of candidate neighbors, then filter out impossible
     * sessions.
     */
    for (Entry<BgpNeighbor, Ip> e : remoteAddresses.entrySet()) {
        BgpNeighbor bgpNeighbor = e.getKey();
        Ip remoteAddress = e.getValue();
        Ip localAddress = bgpNeighbor.getLocalIp();
        int localLocalAs = bgpNeighbor.getLocalAs();
        int localRemoteAs = bgpNeighbor.getRemoteAs();
        /*
       * Let the set of candidate neighbors be set of neighbors that own the remoteAddress
       */
        Set<BgpNeighbor> remoteBgpNeighborCandidates = localAddresses.get(remoteAddress);
        if (remoteBgpNeighborCandidates == null) {
            // No possible remote neighbors
            continue;
        }
        /*
       * Filter the set of candidate neighbors based on these checks:
       * - Remote neighbor's remote address is the same as our local address
       * - Remote neighbor's remote AS is the same as our local AS (and vice-versa)
       */
        for (BgpNeighbor remoteBgpNeighborCandidate : remoteBgpNeighborCandidates) {
            int remoteLocalAs = remoteBgpNeighborCandidate.getLocalAs();
            int remoteRemoteAs = remoteBgpNeighborCandidate.getRemoteAs();
            Ip reciprocalRemoteIp = remoteBgpNeighborCandidate.getAddress();
            if (localAddress.equals(reciprocalRemoteIp) && localLocalAs == remoteRemoteAs && localRemoteAs == remoteLocalAs) {
                /*
           * Fairly confident establishing the session is possible here, but still check
           * reachability if needed.
           * We should check reachability only for eBgp multihop or iBgp
           */
                if (checkReachability && (bgpNeighbor.getEbgpMultihop() || localLocalAs == remoteLocalAs)) {
                    /*
             * Ensure that the session can be established by running traceroute in both directions
             */
                    if (flowProcessor == null || dp == null) {
                        throw new BatfishException("Cannot compute neighbor reachability without a dataplane");
                    }
                    Flow.Builder fb = new Flow.Builder();
                    fb.setIpProtocol(IpProtocol.TCP);
                    fb.setTag("neighbor-resolution");
                    fb.setIngressNode(bgpNeighbor.getOwner().getHostname());
                    fb.setSrcIp(localAddress);
                    fb.setDstIp(remoteAddress);
                    fb.setSrcPort(NamedPort.EPHEMERAL_LOWEST.number());
                    fb.setDstPort(NamedPort.BGP.number());
                    Flow forwardFlow = fb.build();
                    fb.setIngressNode(remoteBgpNeighborCandidate.getOwner().getHostname());
                    fb.setSrcIp(forwardFlow.getDstIp());
                    fb.setDstIp(forwardFlow.getSrcIp());
                    fb.setSrcPort(forwardFlow.getDstPort());
                    fb.setDstPort(forwardFlow.getSrcPort());
                    Flow backwardFlow = fb.build();
                    SortedMap<Flow, Set<FlowTrace>> traces = flowProcessor.processFlows(dp, ImmutableSet.of(forwardFlow, backwardFlow));
                    if (traces.values().stream().map(fts -> fts.stream().allMatch(ft -> ft.getDisposition() != FlowDisposition.ACCEPTED)).anyMatch(Predicate.isEqual(true))) {
                        /*
               * If either flow has all traceroutes fail, do not consider the neighbor valid
               */
                        continue;
                    }
                    bgpNeighbor.getCandidateRemoteBgpNeighbors().add(remoteBgpNeighborCandidate);
                } else {
                    bgpNeighbor.getCandidateRemoteBgpNeighbors().add(remoteBgpNeighborCandidate);
                }
            }
        }
        Set<BgpNeighbor> finalCandidates = bgpNeighbor.getCandidateRemoteBgpNeighbors();
        if (finalCandidates.size() > 1) {
            /* If we still have not narrowed it down to a single neighbor,
         * pick based on sorted hostnames
         */
            SortedMap<String, BgpNeighbor> hostnameToNeighbor = finalCandidates.stream().collect(ImmutableSortedMap.toImmutableSortedMap(String::compareTo, k -> k.getOwner().getHostname(), Function.identity()));
            bgpNeighbor.setRemoteBgpNeighbor(hostnameToNeighbor.get(hostnameToNeighbor.firstKey()));
        } else if (finalCandidates.size() == 1) {
            bgpNeighbor.setRemoteBgpNeighbor(finalCandidates.iterator().next());
        } else {
            bgpNeighbor.setRemoteBgpNeighbor(null);
        }
    }
}
Also used : SSLEngineConfigurator(org.glassfish.grizzly.ssl.SSLEngineConfigurator) SSLContext(javax.net.ssl.SSLContext) FileTime(java.nio.file.attribute.FileTime) StringUtils(org.apache.commons.lang3.StringUtils) Configurations(org.apache.commons.configuration2.builder.fluent.Configurations) Interface(org.batfish.datamodel.Interface) DirectoryStream(java.nio.file.DirectoryStream) BfConsts(org.batfish.common.BfConsts) Flow(org.batfish.datamodel.Flow) Topology(org.batfish.datamodel.Topology) Map(java.util.Map) ResourceConfig(org.glassfish.jersey.server.ResourceConfig) Pair(org.batfish.common.Pair) Path(java.nio.file.Path) DataPlane(org.batfish.datamodel.DataPlane) VrrpGroup(org.batfish.datamodel.VrrpGroup) ClientTracingFeature(io.opentracing.contrib.jaxrs2.client.ClientTracingFeature) Set(java.util.Set) FileAttribute(java.nio.file.attribute.FileAttribute) StandardCharsets(java.nio.charset.StandardCharsets) DirectoryIteratorException(java.nio.file.DirectoryIteratorException) IOUtils(org.apache.commons.io.IOUtils) Stream(java.util.stream.Stream) Supplier(java.util.function.Supplier) TreeSet(java.util.TreeSet) JSONAssert(org.skyscreamer.jsonassert.JSONAssert) MustBeClosed(com.google.errorprone.annotations.MustBeClosed) SSLSession(javax.net.ssl.SSLSession) FlowProcessor(org.batfish.common.plugin.FlowProcessor) BiConsumer(java.util.function.BiConsumer) SSLContextConfigurator(org.glassfish.grizzly.ssl.SSLContextConfigurator) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Nullable(javax.annotation.Nullable) Files(java.nio.file.Files) Route(org.batfish.datamodel.Route) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) FileUtils(org.apache.commons.io.FileUtils) KeyManager(javax.net.ssl.KeyManager) TreeMap(java.util.TreeMap) Paths(java.nio.file.Paths) X509TrustManager(javax.net.ssl.X509TrustManager) BufferedReader(java.io.BufferedReader) X509Certificate(java.security.cert.X509Certificate) IpsecVpn(org.batfish.datamodel.IpsecVpn) NoSuchFileException(java.nio.file.NoSuchFileException) IpProtocol(org.batfish.datamodel.IpProtocol) SortedSet(java.util.SortedSet) URL(java.net.URL) TrustManager(javax.net.ssl.TrustManager) FlowTrace(org.batfish.datamodel.FlowTrace) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) OspfNeighbor(org.batfish.datamodel.OspfNeighbor) Edge(org.batfish.datamodel.Edge) IpWildcardSetIpSpace(org.batfish.datamodel.IpWildcardSetIpSpace) OspfProcess(org.batfish.datamodel.OspfProcess) URI(java.net.URI) HostnameVerifier(javax.net.ssl.HostnameVerifier) NamedPort(org.batfish.datamodel.NamedPort) Vrf(org.batfish.datamodel.Vrf) OspfArea(org.batfish.datamodel.OspfArea) ImmutableSetMultimap(com.google.common.collect.ImmutableSetMultimap) ImmutableSet(com.google.common.collect.ImmutableSet) IdentityHashMap(java.util.IdentityHashMap) PatternSyntaxException(java.util.regex.PatternSyntaxException) TrustManagerFactory(javax.net.ssl.TrustManagerFactory) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) FlowDisposition(org.batfish.datamodel.FlowDisposition) KeyStore(java.security.KeyStore) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) FileNotFoundException(java.io.FileNotFoundException) List(java.util.List) Entry(java.util.Map.Entry) Pattern(java.util.regex.Pattern) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) SortedMap(java.util.SortedMap) IpWildcard(org.batfish.datamodel.IpWildcard) Ip(org.batfish.datamodel.Ip) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) Hashing(com.google.common.hash.Hashing) HashMap(java.util.HashMap) BatfishException(org.batfish.common.BatfishException) BgpProcess(org.batfish.datamodel.BgpProcess) Function(java.util.function.Function) HashSet(java.util.HashSet) ClientBuilder(javax.ws.rs.client.ClientBuilder) Configuration(org.batfish.datamodel.Configuration) OutputStreamWriter(java.io.OutputStreamWriter) OutputStream(java.io.OutputStream) IpLink(org.batfish.datamodel.IpLink) Iterator(java.util.Iterator) MalformedURLException(java.net.MalformedURLException) KeyManagerFactory(javax.net.ssl.KeyManagerFactory) GlobalTracer(io.opentracing.util.GlobalTracer) FileInputStream(java.io.FileInputStream) SetMultimap(com.google.common.collect.SetMultimap) Consumer(java.util.function.Consumer) GrizzlyHttpServerFactory(org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) InputStream(java.io.InputStream) Prefix(org.batfish.datamodel.Prefix) BatfishException(org.batfish.common.BatfishException) Set(java.util.Set) TreeSet(java.util.TreeSet) SortedSet(java.util.SortedSet) ImmutableSet(com.google.common.collect.ImmutableSet) HashSet(java.util.HashSet) Configuration(org.batfish.datamodel.Configuration) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) BgpProcess(org.batfish.datamodel.BgpProcess) Ip(org.batfish.datamodel.Ip) IdentityHashMap(java.util.IdentityHashMap) ClientBuilder(javax.ws.rs.client.ClientBuilder) Vrf(org.batfish.datamodel.Vrf) Flow(org.batfish.datamodel.Flow) BgpNeighbor(org.batfish.datamodel.BgpNeighbor)

Example 3 with Configuration

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

the class BdpEngine method computeFixedPoint.

/**
 * Attempt to compute the fixed point of the data plane.
 *
 * @param nodes A dictionary of configuration-wrapping Bdp nodes keyed by name
 * @param topology The topology representing physical adjacencies between interface of the nodes
 * @param dp The output data plane
 * @param externalAdverts Optional external BGP advertisements fed into the data plane computation
 * @param ae The output answer element in which to store a report of the computation. Also
 *     contains the current recovery iteration.
 * @param recoveryIterationHashCodes Dependent-route computation iteration hash-code dictionaries,
 *     themselves keyed by outer recovery iteration.
 * @return true iff the computation is oscillating
 */
private boolean computeFixedPoint(SortedMap<String, Node> nodes, Topology topology, BdpDataPlane dp, Set<BgpAdvertisement> externalAdverts, BdpAnswerElement ae, SortedMap<Integer, SortedMap<Integer, Integer>> recoveryIterationHashCodes, SortedMap<Integer, SortedSet<Prefix>> iterationOscillatingPrefixes) {
    try (ActiveSpan computeFixedPointSpan = GlobalTracer.get().buildSpan("Computing fixed point").startActive()) {
        // avoid unused warning
        assert computeFixedPointSpan != null;
        SortedSet<Prefix> oscillatingPrefixes = ae.getOscillatingPrefixes();
        // BEGIN DONE ONCE (except main rib)
        // For each virtual router, setup the initial easy-to-do routes and init protocol-based RIBs:
        AtomicInteger initialCompleted = _newBatch.apply("Compute initial connected and static routes, ospf setup, bgp setup", nodes.size());
        try (ActiveSpan initRibsBdpSpan = GlobalTracer.get().buildSpan("Initializing easy routes for BDP").startActive()) {
            // avoid unused warning
            assert initRibsBdpSpan != null;
            nodes.values().parallelStream().forEach(n -> {
                for (VirtualRouter vr : n._virtualRouters.values()) {
                    vr.initRibsForBdp(dp.getIpOwners(), externalAdverts);
                }
                initialCompleted.incrementAndGet();
            });
        }
        // OSPF internal routes
        int numOspfInternalIterations;
        try (ActiveSpan ospfInternalRoutesSpan = GlobalTracer.get().buildSpan("Initializing OSPF internal routes").startActive()) {
            assert ospfInternalRoutesSpan != null;
            numOspfInternalIterations = initOspfInternalRoutes(nodes, topology);
        }
        // RIP internal routes
        try (ActiveSpan ripInternalRoutesSpan = GlobalTracer.get().buildSpan("Initializing RIP internal routes").startActive()) {
            assert ripInternalRoutesSpan != null;
            initRipInternalRoutes(nodes, topology);
        }
        // Prep for traceroutes
        nodes.values().parallelStream().forEach(n -> n._virtualRouters.values().forEach(vr -> {
            vr.importRib(vr._mainRib, vr._independentRib);
            // Needed for activateStaticRoutes
            vr._prevMainRib = vr._mainRib;
            vr.activateStaticRoutes();
        }));
        // Update bgp neighbors with reachability
        dp.setNodes(nodes);
        computeFibs(nodes);
        dp.setTopology(topology);
        initRemoteBgpNeighbors(nodes.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, e -> e.getValue().getConfiguration())), dp.getIpOwners(), true, this, dp);
        // END DONE ONCE
        /*
       * Setup maps to track iterations. We need this for oscillation detection.
       * Specifically, if we detect that an iteration hashcode (a hash of all the nodes' RIBs)
       * has been previously encountered, we go into recovery mode.
       * Recovery mode means enabling "lockstep route propagation" for oscillating prefixes.
       *
       * Lockstep route propagation only allows one of the neighbors to propagate routes for
       * oscillating prefixes in a given iteration.
       * E.g., lexicographically lower neighbor propagates routes during
       * odd iterations, and lex-higher neighbor during even iterations.
       */
        Map<Integer, SortedSet<Integer>> iterationsByHashCode = new HashMap<>();
        SortedMap<Integer, Integer> iterationHashCodes = new TreeMap<>();
        Map<Integer, SortedSet<Route>> iterationRoutes = null;
        Map<Integer, SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>>> iterationAbstractRoutes = null;
        if (_settings.getBdpRecordAllIterations()) {
            if (_settings.getBdpDetail()) {
                iterationAbstractRoutes = new TreeMap<>();
            } else {
                iterationRoutes = new TreeMap<>();
            }
        } else if (_maxRecordedIterations > 0) {
            if (_settings.getBdpDetail()) {
                iterationAbstractRoutes = new LRUMap<>(_maxRecordedIterations);
            } else {
                iterationRoutes = new LRUMap<>(_maxRecordedIterations);
            }
        }
        AtomicBoolean dependentRoutesChanged = new AtomicBoolean(false);
        AtomicBoolean evenDependentRoutesChanged = new AtomicBoolean(false);
        AtomicBoolean oddDependentRoutesChanged = new AtomicBoolean(false);
        int numDependentRoutesIterations = 0;
        // Go into iteration mode, until the routes converge (or oscillation is detected)
        do {
            numDependentRoutesIterations++;
            AtomicBoolean currentChangedMonitor;
            if (oscillatingPrefixes.isEmpty()) {
                currentChangedMonitor = dependentRoutesChanged;
            } else if (numDependentRoutesIterations % 2 == 0) {
                currentChangedMonitor = evenDependentRoutesChanged;
            } else {
                currentChangedMonitor = oddDependentRoutesChanged;
            }
            currentChangedMonitor.set(false);
            computeDependentRoutesIteration(nodes, topology, dp, numDependentRoutesIterations, oscillatingPrefixes);
            /* Collect sizes of certain RIBs this iteration */
            computeIterationStatistics(nodes, ae, numDependentRoutesIterations);
            recordIterationDebugInfo(nodes, dp, iterationRoutes, iterationAbstractRoutes, numDependentRoutesIterations);
            // Check to see if hash has changed
            AtomicInteger checkFixedPointCompleted = _newBatch.apply("Iteration " + numDependentRoutesIterations + ": Check if fixed-point reached", nodes.size());
            // This hashcode uniquely identifies the iteration (i.e., network state)
            int iterationHashCode = computeIterationHashCode(nodes);
            SortedSet<Integer> iterationsWithThisHashCode = iterationsByHashCode.computeIfAbsent(iterationHashCode, h -> new TreeSet<>());
            iterationHashCodes.put(numDependentRoutesIterations, iterationHashCode);
            int minNumberOfUnchangedIterationsForConvergence = oscillatingPrefixes.isEmpty() ? 1 : 2;
            if (iterationsWithThisHashCode.isEmpty() || (!oscillatingPrefixes.isEmpty() && iterationsWithThisHashCode.equals(Collections.singleton(numDependentRoutesIterations - 1)))) {
                iterationsWithThisHashCode.add(numDependentRoutesIterations);
            } else if (!iterationsWithThisHashCode.contains(numDependentRoutesIterations - minNumberOfUnchangedIterationsForConvergence)) {
                int lowestIterationWithThisHashCode = iterationsWithThisHashCode.first();
                int completedOscillationRecoveryAttempts = ae.getCompletedOscillationRecoveryAttempts();
                if (!oscillatingPrefixes.isEmpty()) {
                    completedOscillationRecoveryAttempts++;
                    ae.setCompletedOscillationRecoveryAttempts(completedOscillationRecoveryAttempts);
                }
                recoveryIterationHashCodes.put(completedOscillationRecoveryAttempts, iterationHashCodes);
                handleOscillation(recoveryIterationHashCodes, iterationRoutes, iterationAbstractRoutes, lowestIterationWithThisHashCode, numDependentRoutesIterations, iterationOscillatingPrefixes, ae);
                return true;
            }
            compareToPreviousIteration(nodes, currentChangedMonitor, checkFixedPointCompleted);
            computeFibs(nodes);
            initRemoteBgpNeighbors(nodes.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, e -> e.getValue().getConfiguration())), dp.getIpOwners(), true, this, dp);
        } while (checkDependentRoutesChanged(dependentRoutesChanged, evenDependentRoutesChanged, oddDependentRoutesChanged, oscillatingPrefixes, numDependentRoutesIterations));
        AtomicInteger computeBgpAdvertisementsToOutsideCompleted = _newBatch.apply("Compute BGP advertisements sent to outside", nodes.size());
        nodes.values().parallelStream().forEach(n -> {
            for (VirtualRouter vr : n._virtualRouters.values()) {
                vr.computeBgpAdvertisementsToOutside(dp.getIpOwners());
            }
            computeBgpAdvertisementsToOutsideCompleted.incrementAndGet();
        });
        // Set iteration stats in the answer
        ae.setOspfInternalIterations(numOspfInternalIterations);
        ae.setDependentRoutesIterations(numDependentRoutesIterations);
        return false;
    }
}
Also used : SortedSet(java.util.SortedSet) BiFunction(java.util.function.BiFunction) LRUMap(org.apache.commons.collections4.map.LRUMap) FlowTrace(org.batfish.datamodel.FlowTrace) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Edge(org.batfish.datamodel.Edge) Interface(org.batfish.datamodel.Interface) Flow(org.batfish.datamodel.Flow) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Topology(org.batfish.datamodel.Topology) CommonUtil.initRemoteBgpNeighbors(org.batfish.common.util.CommonUtil.initRemoteBgpNeighbors) Map(java.util.Map) DataPlane(org.batfish.datamodel.DataPlane) ImmutableMap(com.google.common.collect.ImmutableMap) FlowDisposition(org.batfish.datamodel.FlowDisposition) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) List(java.util.List) SourceNat(org.batfish.datamodel.SourceNat) Entry(java.util.Map.Entry) Optional(java.util.Optional) SortedMap(java.util.SortedMap) BatfishLogger(org.batfish.common.BatfishLogger) Ip(org.batfish.datamodel.Ip) RouteBuilder(org.batfish.datamodel.RouteBuilder) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) FilterResult(org.batfish.datamodel.FilterResult) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) BdpAnswerElement(org.batfish.datamodel.answers.BdpAnswerElement) CommonUtil(org.batfish.common.util.CommonUtil) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) BatfishException(org.batfish.common.BatfishException) BgpProcess(org.batfish.datamodel.BgpProcess) IpAccessList(org.batfish.datamodel.IpAccessList) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) AbstractRoute(org.batfish.datamodel.AbstractRoute) Version(org.batfish.common.Version) FlowProcessor(org.batfish.common.plugin.FlowProcessor) Configuration(org.batfish.datamodel.Configuration) LineAction(org.batfish.datamodel.LineAction) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) Route(org.batfish.datamodel.Route) GlobalTracer(io.opentracing.util.GlobalTracer) BdpOscillationException(org.batfish.common.BdpOscillationException) TreeMap(java.util.TreeMap) ActiveSpan(io.opentracing.ActiveSpan) Collections(java.util.Collections) Prefix(org.batfish.datamodel.Prefix) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Prefix(org.batfish.datamodel.Prefix) TreeMap(java.util.TreeMap) SortedSet(java.util.SortedSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Entry(java.util.Map.Entry) ActiveSpan(io.opentracing.ActiveSpan) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LRUMap(org.apache.commons.collections4.map.LRUMap) SortedMap(java.util.SortedMap)

Example 4 with Configuration

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

the class Batfish method processNodeBlacklist.

private void processNodeBlacklist(Map<String, Configuration> configurations, ValidateEnvironmentAnswerElement veae) {
    SortedSet<String> blacklistNodes = getNodeBlacklist();
    for (String hostname : blacklistNodes) {
        Configuration node = configurations.get(hostname);
        if (node != null) {
            for (Interface iface : node.getInterfaces().values()) {
                iface.setActive(false);
                iface.setBlacklisted(true);
            }
        } else {
            veae.setValid(false);
            veae.getUndefinedNodeBlacklistNodes().add(hostname);
        }
    }
}
Also used : HostConfiguration(org.batfish.representation.host.HostConfiguration) Configuration(org.batfish.datamodel.Configuration) ImmutableConfiguration(org.apache.commons.configuration2.ImmutableConfiguration) AwsConfiguration(org.batfish.representation.aws.AwsConfiguration) IptablesVendorConfiguration(org.batfish.representation.iptables.IptablesVendorConfiguration) VendorConfiguration(org.batfish.vendor.VendorConfiguration) Interface(org.batfish.datamodel.Interface)

Example 5 with Configuration

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

the class Batfish method disableUnusableVlanInterfaces.

private void disableUnusableVlanInterfaces(Map<String, Configuration> configurations) {
    for (Configuration c : configurations.values()) {
        Map<Integer, Interface> vlanInterfaces = new HashMap<>();
        Map<Integer, Integer> vlanMemberCounts = new HashMap<>();
        Set<Interface> nonVlanInterfaces = new HashSet<>();
        Integer vlanNumber = null;
        // vlanMemberCounts:
        for (Interface iface : c.getInterfaces().values()) {
            if ((iface.getInterfaceType() == InterfaceType.VLAN) && ((vlanNumber = CommonUtil.getInterfaceVlanNumber(iface.getName())) != null)) {
                vlanInterfaces.put(vlanNumber, iface);
                vlanMemberCounts.put(vlanNumber, 0);
            } else {
                nonVlanInterfaces.add(iface);
            }
        }
        // Update vlanMemberCounts:
        for (Interface iface : nonVlanInterfaces) {
            List<SubRange> vlans = new ArrayList<>();
            vlanNumber = iface.getAccessVlan();
            if (vlanNumber == 0) {
                // vlan trunked interface
                vlans.addAll(iface.getAllowedVlans());
                vlanNumber = iface.getNativeVlan();
            }
            vlans.add(new SubRange(vlanNumber, vlanNumber));
            for (SubRange sr : vlans) {
                for (int vlanId = sr.getStart(); vlanId <= sr.getEnd(); ++vlanId) {
                    vlanMemberCounts.compute(vlanId, (k, v) -> (v == null) ? 1 : (v + 1));
                }
            }
        }
        // Disable all "normal" vlan interfaces with zero member counts:
        String hostname = c.getHostname();
        SubRange normalVlanRange = c.getNormalVlanRange();
        for (Map.Entry<Integer, Integer> entry : vlanMemberCounts.entrySet()) {
            if (entry.getValue() == 0) {
                vlanNumber = entry.getKey();
                if ((vlanNumber >= normalVlanRange.getStart()) && (vlanNumber <= normalVlanRange.getEnd())) {
                    Interface iface = vlanInterfaces.get(vlanNumber);
                    if ((iface != null) && iface.getAutoState()) {
                        _logger.warnf("WARNING: Disabling unusable vlan interface because no switch port is assigned " + "to it: \"%s:%d\"\n", hostname, vlanNumber);
                        iface.setActive(false);
                        iface.setBlacklisted(true);
                    }
                }
            }
        }
    }
}
Also used : HostConfiguration(org.batfish.representation.host.HostConfiguration) Configuration(org.batfish.datamodel.Configuration) ImmutableConfiguration(org.apache.commons.configuration2.ImmutableConfiguration) AwsConfiguration(org.batfish.representation.aws.AwsConfiguration) IptablesVendorConfiguration(org.batfish.representation.iptables.IptablesVendorConfiguration) VendorConfiguration(org.batfish.vendor.VendorConfiguration) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SubRange(org.batfish.datamodel.SubRange) Map(java.util.Map) TreeMap(java.util.TreeMap) Collectors.toMap(java.util.stream.Collectors.toMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) NavigableMap(java.util.NavigableMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) ImmutableMap(com.google.common.collect.ImmutableMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) Interface(org.batfish.datamodel.Interface) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Aggregations

Configuration (org.batfish.datamodel.Configuration)170 Test (org.junit.Test)69 Interface (org.batfish.datamodel.Interface)55 Ip (org.batfish.datamodel.Ip)49 Vrf (org.batfish.datamodel.Vrf)45 HashMap (java.util.HashMap)44 Topology (org.batfish.datamodel.Topology)38 VendorConfiguration (org.batfish.vendor.VendorConfiguration)35 Prefix (org.batfish.datamodel.Prefix)33 Edge (org.batfish.datamodel.Edge)32 InterfaceAddress (org.batfish.datamodel.InterfaceAddress)30 Map (java.util.Map)29 Set (java.util.Set)29 TreeMap (java.util.TreeMap)29 BatfishException (org.batfish.common.BatfishException)28 IpAccessList (org.batfish.datamodel.IpAccessList)26 ArrayList (java.util.ArrayList)25 HashSet (java.util.HashSet)25 List (java.util.List)25 SortedSet (java.util.SortedSet)24