Search in sources :

Example 1 with BgpAdvertisement

use of org.batfish.datamodel.BgpAdvertisement 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 2 with BgpAdvertisement

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

the class VirtualRouter method initBaseBgpRibs.

public void initBaseBgpRibs(Set<BgpAdvertisement> externalAdverts, Map<Ip, Set<String>> ipOwners) {
    if (_vrf.getBgpProcess() != null) {
        int ebgpAdmin = RoutingProtocol.BGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
        int ibgpAdmin = RoutingProtocol.IBGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
        for (BgpAdvertisement advert : externalAdverts) {
            if (advert.getDstNode().equals(_c.getHostname())) {
                Ip dstIp = advert.getDstIp();
                Set<String> dstIpOwners = ipOwners.get(dstIp);
                String hostname = _c.getHostname();
                if (dstIpOwners == null || !dstIpOwners.contains(hostname)) {
                    continue;
                }
                Ip srcIp = advert.getSrcIp();
                // TODO: support passive bgp connections
                Prefix srcPrefix = new Prefix(srcIp, Prefix.MAX_PREFIX_LENGTH);
                BgpNeighbor neighbor = _vrf.getBgpProcess().getNeighbors().get(srcPrefix);
                if (neighbor != null) {
                    BgpAdvertisementType type = advert.getType();
                    BgpRoute.Builder outgoingRouteBuilder = new BgpRoute.Builder();
                    boolean ebgp;
                    boolean received;
                    switch(type) {
                        case EBGP_RECEIVED:
                            ebgp = true;
                            received = true;
                            break;
                        case EBGP_SENT:
                            ebgp = true;
                            received = false;
                            break;
                        case IBGP_RECEIVED:
                            ebgp = false;
                            received = true;
                            break;
                        case IBGP_SENT:
                            ebgp = false;
                            received = false;
                            break;
                        case EBGP_ORIGINATED:
                        case IBGP_ORIGINATED:
                        default:
                            throw new BatfishException("Missing or invalid bgp advertisement type");
                    }
                    BgpMultipathRib targetRib = ebgp ? _baseEbgpRib : _baseIbgpRib;
                    RoutingProtocol targetProtocol = ebgp ? RoutingProtocol.BGP : RoutingProtocol.IBGP;
                    if (received) {
                        int admin = ebgp ? ebgpAdmin : ibgpAdmin;
                        AsPath asPath = advert.getAsPath();
                        SortedSet<Long> clusterList = advert.getClusterList();
                        SortedSet<Long> communities = new TreeSet<>(advert.getCommunities());
                        int localPreference = advert.getLocalPreference();
                        long metric = advert.getMed();
                        Prefix network = advert.getNetwork();
                        Ip nextHopIp = advert.getNextHopIp();
                        Ip originatorIp = advert.getOriginatorIp();
                        OriginType originType = advert.getOriginType();
                        RoutingProtocol srcProtocol = advert.getSrcProtocol();
                        int weight = advert.getWeight();
                        BgpRoute.Builder builder = new BgpRoute.Builder();
                        builder.setAdmin(admin);
                        builder.setAsPath(asPath.getAsSets());
                        builder.setClusterList(clusterList);
                        builder.setCommunities(communities);
                        builder.setLocalPreference(localPreference);
                        builder.setMetric(metric);
                        builder.setNetwork(network);
                        builder.setNextHopIp(nextHopIp);
                        builder.setOriginatorIp(originatorIp);
                        builder.setOriginType(originType);
                        builder.setProtocol(targetProtocol);
                        // TODO: support external route reflector clients
                        builder.setReceivedFromIp(advert.getSrcIp());
                        builder.setReceivedFromRouteReflectorClient(false);
                        builder.setSrcProtocol(srcProtocol);
                        // TODO: possibly suppport setting tag
                        builder.setWeight(weight);
                        BgpRoute route = builder.build();
                        targetRib.mergeRoute(route);
                    } else {
                        int localPreference;
                        if (ebgp) {
                            localPreference = BgpRoute.DEFAULT_LOCAL_PREFERENCE;
                        } else {
                            localPreference = advert.getLocalPreference();
                        }
                        outgoingRouteBuilder.setAsPath(advert.getAsPath().getAsSets());
                        outgoingRouteBuilder.setCommunities(new TreeSet<>(advert.getCommunities()));
                        outgoingRouteBuilder.setLocalPreference(localPreference);
                        outgoingRouteBuilder.setMetric(advert.getMed());
                        outgoingRouteBuilder.setNetwork(advert.getNetwork());
                        outgoingRouteBuilder.setNextHopIp(advert.getNextHopIp());
                        outgoingRouteBuilder.setOriginatorIp(advert.getOriginatorIp());
                        outgoingRouteBuilder.setOriginType(advert.getOriginType());
                        outgoingRouteBuilder.setProtocol(targetProtocol);
                        outgoingRouteBuilder.setReceivedFromIp(advert.getSrcIp());
                        // TODO:
                        // outgoingRouteBuilder.setReceivedFromRouteReflectorClient(...);
                        outgoingRouteBuilder.setSrcProtocol(advert.getSrcProtocol());
                        BgpRoute transformedOutgoingRoute = outgoingRouteBuilder.build();
                        BgpRoute.Builder transformedIncomingRouteBuilder = new BgpRoute.Builder();
                        // Incoming originatorIp
                        transformedIncomingRouteBuilder.setOriginatorIp(transformedOutgoingRoute.getOriginatorIp());
                        // Incoming receivedFromIp
                        transformedIncomingRouteBuilder.setReceivedFromIp(transformedOutgoingRoute.getReceivedFromIp());
                        // Incoming clusterList
                        transformedIncomingRouteBuilder.getClusterList().addAll(transformedOutgoingRoute.getClusterList());
                        // Incoming receivedFromRouteReflectorClient
                        transformedIncomingRouteBuilder.setReceivedFromRouteReflectorClient(transformedOutgoingRoute.getReceivedFromRouteReflectorClient());
                        // Incoming asPath
                        transformedIncomingRouteBuilder.setAsPath(transformedOutgoingRoute.getAsPath().getAsSets());
                        // Incoming communities
                        transformedIncomingRouteBuilder.getCommunities().addAll(transformedOutgoingRoute.getCommunities());
                        // Incoming protocol
                        transformedIncomingRouteBuilder.setProtocol(targetProtocol);
                        // Incoming network
                        transformedIncomingRouteBuilder.setNetwork(transformedOutgoingRoute.getNetwork());
                        // Incoming nextHopIp
                        transformedIncomingRouteBuilder.setNextHopIp(transformedOutgoingRoute.getNextHopIp());
                        // Incoming originType
                        transformedIncomingRouteBuilder.setOriginType(transformedOutgoingRoute.getOriginType());
                        // Incoming localPreference
                        transformedIncomingRouteBuilder.setLocalPreference(transformedOutgoingRoute.getLocalPreference());
                        // Incoming admin
                        int admin = ebgp ? ebgpAdmin : ibgpAdmin;
                        transformedIncomingRouteBuilder.setAdmin(admin);
                        // Incoming metric
                        transformedIncomingRouteBuilder.setMetric(transformedOutgoingRoute.getMetric());
                        // Incoming srcProtocol
                        transformedIncomingRouteBuilder.setSrcProtocol(targetProtocol);
                        String importPolicyName = neighbor.getImportPolicy();
                        if (ebgp && transformedOutgoingRoute.getAsPath().containsAs(neighbor.getLocalAs()) && !neighbor.getAllowLocalAsIn()) {
                            // disable-peer-as-check (getAllowRemoteAsOut) is set
                            continue;
                        }
                        /*
               * CREATE INCOMING ROUTE
               */
                        boolean acceptIncoming = true;
                        if (importPolicyName != null) {
                            RoutingPolicy importPolicy = _c.getRoutingPolicies().get(importPolicyName);
                            if (importPolicy != null) {
                                acceptIncoming = importPolicy.process(transformedOutgoingRoute, transformedIncomingRouteBuilder, advert.getSrcIp(), _key, Direction.IN);
                            }
                        }
                        if (acceptIncoming) {
                            BgpRoute transformedIncomingRoute = transformedIncomingRouteBuilder.build();
                            targetRib.mergeRoute(transformedIncomingRoute);
                        }
                    }
                }
            }
        }
    }
    importRib(_ebgpMultipathRib, _baseEbgpRib);
    importRib(_ebgpBestPathRib, _baseEbgpRib);
    importRib(_bgpBestPathRib, _baseEbgpRib);
    importRib(_ibgpMultipathRib, _baseIbgpRib);
    importRib(_ibgpBestPathRib, _baseIbgpRib);
    importRib(_bgpBestPathRib, _baseIbgpRib);
}
Also used : BatfishException(org.batfish.common.BatfishException) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) OriginType(org.batfish.datamodel.OriginType) BgpAdvertisementType(org.batfish.datamodel.BgpAdvertisement.BgpAdvertisementType) Ip(org.batfish.datamodel.Ip) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) Prefix(org.batfish.datamodel.Prefix) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) AsPath(org.batfish.datamodel.AsPath) TreeSet(java.util.TreeSet) BgpRoute(org.batfish.datamodel.BgpRoute)

Example 3 with BgpAdvertisement

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

the class VirtualRouter method computeBgpAdvertisementsToOutside.

int computeBgpAdvertisementsToOutside(Map<Ip, Set<String>> ipOwners) {
    int numAdvertisements = 0;
    // If we have no BGP process, nothing to do
    if (_vrf.getBgpProcess() == null) {
        return numAdvertisements;
    }
    for (BgpNeighbor neighbor : _vrf.getBgpProcess().getNeighbors().values()) {
        Ip localIp = neighbor.getLocalIp();
        Set<String> localIpOwners = ipOwners.get(localIp);
        String hostname = _c.getHostname();
        if (localIpOwners == null || !localIpOwners.contains(hostname)) {
            continue;
        }
        Prefix remotePrefix = neighbor.getPrefix();
        if (remotePrefix.getPrefixLength() != Prefix.MAX_PREFIX_LENGTH) {
            // Do not support dynamic outside neighbors
            continue;
        }
        Ip remoteIp = remotePrefix.getStartIp();
        if (ipOwners.get(remoteIp) != null) {
            // Skip if neighbor is not outside the network
            continue;
        }
        int localAs = neighbor.getLocalAs();
        int remoteAs = neighbor.getRemoteAs();
        String remoteHostname = remoteIp.toString();
        String remoteVrfName = Configuration.DEFAULT_VRF_NAME;
        RoutingPolicy exportPolicy = _c.getRoutingPolicies().get(neighbor.getExportPolicy());
        boolean ebgpSession = localAs != remoteAs;
        RoutingProtocol targetProtocol = ebgpSession ? RoutingProtocol.BGP : RoutingProtocol.IBGP;
        Set<AbstractRoute> candidateRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
        // Add IGP routes
        Set<AbstractRoute> activeRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
        activeRoutes.addAll(_mainRib.getRoutes());
        for (AbstractRoute candidateRoute : activeRoutes) {
            if (candidateRoute.getProtocol() != RoutingProtocol.BGP && candidateRoute.getProtocol() != RoutingProtocol.IBGP) {
                candidateRoutes.add(candidateRoute);
            }
        }
        /*
       * bgp advertise-external
       *
       * When this is set, add best eBGP path independently of whether
       * it is preempted by an iBGP or IGP route. Only applicable to
       * iBGP sessions.
       */
        boolean advertiseExternal = !ebgpSession && neighbor.getAdvertiseExternal();
        if (advertiseExternal) {
            candidateRoutes.addAll(_ebgpBestPathRib.getRoutes());
        }
        /*
       * bgp advertise-inactive
       *
       * When this is set, add best BGP path independently of whether
       * it is preempted by an IGP route. Only applicable to eBGP
       * sessions.
       */
        boolean advertiseInactive = ebgpSession && neighbor.getAdvertiseInactive();
        /* Add best bgp paths if they are active, or if advertise-inactive */
        for (AbstractRoute candidateRoute : _bgpBestPathRib.getRoutes()) {
            if (advertiseInactive || activeRoutes.contains(candidateRoute)) {
                candidateRoutes.add(candidateRoute);
            }
        }
        /* Add all bgp paths if additional-paths active for this session */
        boolean additionalPaths = !ebgpSession && neighbor.getAdditionalPathsSend() && neighbor.getAdditionalPathsSelectAll();
        if (additionalPaths) {
            candidateRoutes.addAll(_bgpMultipathRib.getRoutes());
        }
        for (AbstractRoute route : candidateRoutes) {
            BgpRoute.Builder transformedOutgoingRouteBuilder = new BgpRoute.Builder();
            RoutingProtocol routeProtocol = route.getProtocol();
            boolean routeIsBgp = routeProtocol == RoutingProtocol.IBGP || routeProtocol == RoutingProtocol.BGP;
            // originatorIP
            Ip originatorIp;
            if (!ebgpSession && routeProtocol.equals(RoutingProtocol.IBGP)) {
                BgpRoute bgpRoute = (BgpRoute) route;
                originatorIp = bgpRoute.getOriginatorIp();
            } else {
                originatorIp = _vrf.getBgpProcess().getRouterId();
            }
            transformedOutgoingRouteBuilder.setOriginatorIp(originatorIp);
            transformedOutgoingRouteBuilder.setReceivedFromIp(neighbor.getLocalIp());
            // for bgp remote route)
            if (routeIsBgp) {
                BgpRoute bgpRoute = (BgpRoute) route;
                transformedOutgoingRouteBuilder.setOriginType(bgpRoute.getOriginType());
                if (ebgpSession && bgpRoute.getAsPath().containsAs(neighbor.getRemoteAs()) && !neighbor.getAllowRemoteAsOut()) {
                    // disable-peer-as-check (getAllowRemoteAsOut) is set
                    continue;
                }
                /*
           * route reflection: reflect everything received from
           * clients to clients and non-clients. reflect everything
           * received from non-clients to clients. Do not reflect to
           * originator
           */
                Ip routeOriginatorIp = bgpRoute.getOriginatorIp();
                /*
           *  iBGP speaker should not send out routes to iBGP neighbor whose router-id is
           *  same as originator id of advertisement
           */
                if (!ebgpSession && routeOriginatorIp != null && remoteIp.equals(routeOriginatorIp)) {
                    continue;
                }
                if (routeProtocol.equals(RoutingProtocol.IBGP) && !ebgpSession) {
                    boolean routeReceivedFromRouteReflectorClient = bgpRoute.getReceivedFromRouteReflectorClient();
                    boolean sendingToRouteReflectorClient = neighbor.getRouteReflectorClient();
                    transformedOutgoingRouteBuilder.getClusterList().addAll(bgpRoute.getClusterList());
                    if (!routeReceivedFromRouteReflectorClient && !sendingToRouteReflectorClient) {
                        continue;
                    }
                    if (sendingToRouteReflectorClient) {
                        // sender adds its local cluster id to clusterlist of
                        // new route
                        transformedOutgoingRouteBuilder.getClusterList().add(neighbor.getClusterId());
                    }
                }
            }
            // Outgoing communities
            if (routeIsBgp) {
                BgpRoute bgpRoute = (BgpRoute) route;
                transformedOutgoingRouteBuilder.setAsPath(bgpRoute.getAsPath().getAsSets());
                if (neighbor.getSendCommunity()) {
                    transformedOutgoingRouteBuilder.getCommunities().addAll(bgpRoute.getCommunities());
                }
            }
            if (ebgpSession) {
                SortedSet<Integer> newAsPathElement = new TreeSet<>();
                newAsPathElement.add(localAs);
                transformedOutgoingRouteBuilder.getAsPath().add(0, newAsPathElement);
            }
            // Outgoing protocol
            transformedOutgoingRouteBuilder.setProtocol(targetProtocol);
            transformedOutgoingRouteBuilder.setNetwork(route.getNetwork());
            // Outgoing metric
            if (routeIsBgp) {
                transformedOutgoingRouteBuilder.setMetric(route.getMetric());
            }
            // Outgoing nextHopIp
            // Outgoing localPreference
            Ip nextHopIp;
            int localPreference;
            if (ebgpSession || !routeIsBgp) {
                nextHopIp = neighbor.getLocalIp();
                localPreference = BgpRoute.DEFAULT_LOCAL_PREFERENCE;
            } else {
                nextHopIp = route.getNextHopIp();
                BgpRoute ibgpRoute = (BgpRoute) route;
                localPreference = ibgpRoute.getLocalPreference();
            }
            if (nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) {
                // should only happen for ibgp
                String nextHopInterface = route.getNextHopInterface();
                InterfaceAddress nextHopAddress = _c.getInterfaces().get(nextHopInterface).getAddress();
                if (nextHopAddress == null) {
                    throw new BatfishException("route's nextHopInterface has no address");
                }
                nextHopIp = nextHopAddress.getIp();
            }
            transformedOutgoingRouteBuilder.setNextHopIp(nextHopIp);
            transformedOutgoingRouteBuilder.setLocalPreference(localPreference);
            // Outgoing srcProtocol
            transformedOutgoingRouteBuilder.setSrcProtocol(route.getProtocol());
            /*
         * CREATE OUTGOING ROUTE
         */
            boolean acceptOutgoing = exportPolicy.process(route, transformedOutgoingRouteBuilder, remoteIp, remoteVrfName, Direction.OUT);
            if (acceptOutgoing) {
                BgpRoute transformedOutgoingRoute = transformedOutgoingRouteBuilder.build();
                // Record sent advertisement
                BgpAdvertisementType sentType = ebgpSession ? BgpAdvertisementType.EBGP_SENT : BgpAdvertisementType.IBGP_SENT;
                Ip sentOriginatorIp = transformedOutgoingRoute.getOriginatorIp();
                SortedSet<Long> sentClusterList = transformedOutgoingRoute.getClusterList();
                AsPath sentAsPath = transformedOutgoingRoute.getAsPath();
                SortedSet<Long> sentCommunities = transformedOutgoingRoute.getCommunities();
                Prefix sentNetwork = route.getNetwork();
                Ip sentNextHopIp;
                String sentSrcNode = hostname;
                String sentSrcVrf = _vrf.getName();
                Ip sentSrcIp = neighbor.getLocalIp();
                String sentDstNode = remoteHostname;
                String sentDstVrf = remoteVrfName;
                Ip sentDstIp = remoteIp;
                int sentWeight = -1;
                if (ebgpSession) {
                    sentNextHopIp = nextHopIp;
                } else {
                    sentNextHopIp = transformedOutgoingRoute.getNextHopIp();
                }
                int sentLocalPreference = transformedOutgoingRoute.getLocalPreference();
                long sentMed = transformedOutgoingRoute.getMetric();
                OriginType sentOriginType = transformedOutgoingRoute.getOriginType();
                RoutingProtocol sentSrcProtocol = targetProtocol;
                BgpAdvertisement sentAdvert = new BgpAdvertisement(sentType, sentNetwork, sentNextHopIp, sentSrcNode, sentSrcVrf, sentSrcIp, sentDstNode, sentDstVrf, sentDstIp, sentSrcProtocol, sentOriginType, sentLocalPreference, sentMed, sentOriginatorIp, sentAsPath, sentCommunities, sentClusterList, sentWeight);
                _sentBgpAdvertisements.add(sentAdvert);
                numAdvertisements++;
            }
        }
    }
    return numAdvertisements;
}
Also used : RoutingProtocol(org.batfish.datamodel.RoutingProtocol) BgpAdvertisementType(org.batfish.datamodel.BgpAdvertisement.BgpAdvertisementType) Ip(org.batfish.datamodel.Ip) Prefix(org.batfish.datamodel.Prefix) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) TreeSet(java.util.TreeSet) BgpRoute(org.batfish.datamodel.BgpRoute) AbstractRoute(org.batfish.datamodel.AbstractRoute) BatfishException(org.batfish.common.BatfishException) OriginType(org.batfish.datamodel.OriginType) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) AsPath(org.batfish.datamodel.AsPath) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement)

Example 4 with BgpAdvertisement

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

the class JsonExternalBgpAdvertisementPlugin method loadExternalBgpAdvertisements.

@Override
public Set<BgpAdvertisement> loadExternalBgpAdvertisements() {
    Set<BgpAdvertisement> advertSet = new LinkedHashSet<>();
    String externalBgpAnnouncementsFileContents = _batfish.readExternalBgpAnnouncementsFile();
    if (externalBgpAnnouncementsFileContents != null) {
        try {
            JSONObject jsonObj = new JSONObject(externalBgpAnnouncementsFileContents);
            JSONArray announcements = jsonObj.getJSONArray(BfConsts.PROP_BGP_ANNOUNCEMENTS);
            for (int index = 0; index < announcements.length(); index++) {
                JSONObject announcement = new JSONObject();
                JSONObject announcementSrc = announcements.getJSONObject(index);
                for (Iterator<?> i = announcementSrc.keys(); i.hasNext(); ) {
                    String key = (String) i.next();
                    announcement.put(key, announcementSrc.get(key));
                }
                BgpAdvertisement bgpAdvertisement = BatfishObjectMapper.mapper().readValue(announcement.toString(), BgpAdvertisement.class);
                advertSet.add(bgpAdvertisement);
            }
        } catch (JSONException | IOException e) {
            throw new BatfishException("Error processing external BGP advertisements file", e);
        }
    }
    return advertSet;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) BatfishException(org.batfish.common.BatfishException) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) JSONObject(org.codehaus.jettison.json.JSONObject) JSONArray(org.codehaus.jettison.json.JSONArray) JSONException(org.codehaus.jettison.json.JSONException) IOException(java.io.IOException)

Example 5 with BgpAdvertisement

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

the class EnvironmentTest method testConstructorAndGetter.

@Test
public void testConstructorAndGetter() {
    SortedSet<String> nodeBlacklist = Sets.newTreeSet();
    nodeBlacklist.add("node1");
    SortedMap<String, String> bgpTables = Maps.newTreeMap();
    bgpTables.put("bgpTable1", "table1Content");
    SortedMap<String, String> routingTables = Maps.newTreeMap();
    routingTables.put("routingTable1", "table1Content");
    SortedSet<BgpAdvertisement> bgpAdvertisements = Sets.newTreeSet();
    bgpAdvertisements.add(new BgpAdvertisement(BgpAdvertisementType.EBGP_SENT, Prefix.parse("1.1.1.1/24"), new Ip("1.1.1.1"), "srcNode", "srcVrf", new Ip("2.2.2.2"), "dstNode", "dstVrf", new Ip("3.3.3.3"), RoutingProtocol.BGP, OriginType.EGP, 20, 20, new Ip("0.0.0.0"), new AsPath(Lists.newArrayList()), ImmutableSortedSet.of(), ImmutableSortedSet.of(), 10));
    Environment e = new Environment("environment", "testrig", Sets.newTreeSet(), Sets.newTreeSet(), nodeBlacklist, bgpTables, routingTables, bgpAdvertisements);
    assertThat(e.getEnvName(), equalTo("environment"));
    assertThat(e.getTestrigName(), equalTo("testrig"));
    assertThat(e.getEdgeBlacklist(), equalTo(Sets.newHashSet()));
    assertThat(e.getInterfaceBlacklist(), equalTo(Sets.newHashSet()));
    assertThat(e.getNodeBlacklist(), equalTo(nodeBlacklist));
    assertThat(e.getBgpTables(), equalTo(bgpTables));
    assertThat(e.getRoutingTables(), equalTo(routingTables));
    assertThat(e.getExternalBgpAnnouncements(), equalTo(bgpAdvertisements));
}
Also used : BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) AsPath(org.batfish.datamodel.AsPath) Ip(org.batfish.datamodel.Ip) Test(org.junit.Test)

Aggregations

BgpAdvertisement (org.batfish.datamodel.BgpAdvertisement)16 BatfishException (org.batfish.common.BatfishException)7 Ip (org.batfish.datamodel.Ip)7 LinkedHashSet (java.util.LinkedHashSet)6 AsPath (org.batfish.datamodel.AsPath)6 Prefix (org.batfish.datamodel.Prefix)6 TreeSet (java.util.TreeSet)5 AbstractRoute (org.batfish.datamodel.AbstractRoute)5 Configuration (org.batfish.datamodel.Configuration)5 Flow (org.batfish.datamodel.Flow)5 RoutingPolicy (org.batfish.datamodel.routing_policy.RoutingPolicy)5 SortedSet (java.util.SortedSet)4 BgpAdvertisementType (org.batfish.datamodel.BgpAdvertisement.BgpAdvertisementType)4 BgpNeighbor (org.batfish.datamodel.BgpNeighbor)4 FlowTrace (org.batfish.datamodel.FlowTrace)4 InterfaceAddress (org.batfish.datamodel.InterfaceAddress)4 Test (org.junit.Test)4 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3