Search in sources :

Example 1 with BgpAdvertisementType

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

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

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

the class Batfish method initBgpAdvertisements.

@Override
public void initBgpAdvertisements(Map<String, Configuration> configurations) {
    Set<BgpAdvertisement> globalBgpAdvertisements = getDataPlanePlugin().getAdvertisements();
    for (Configuration node : configurations.values()) {
        node.initBgpAdvertisements();
        for (Vrf vrf : node.getVrfs().values()) {
            vrf.initBgpAdvertisements();
        }
    }
    for (BgpAdvertisement bgpAdvertisement : globalBgpAdvertisements) {
        BgpAdvertisementType type = bgpAdvertisement.getType();
        String srcVrf = bgpAdvertisement.getSrcVrf();
        String dstVrf = bgpAdvertisement.getDstVrf();
        switch(type) {
            case EBGP_ORIGINATED:
                {
                    String originationNodeName = bgpAdvertisement.getSrcNode();
                    Configuration originationNode = configurations.get(originationNodeName);
                    if (originationNode != null) {
                        originationNode.getBgpAdvertisements().add(bgpAdvertisement);
                        originationNode.getOriginatedAdvertisements().add(bgpAdvertisement);
                        originationNode.getOriginatedEbgpAdvertisements().add(bgpAdvertisement);
                        Vrf originationVrf = originationNode.getVrfs().get(srcVrf);
                        originationVrf.getBgpAdvertisements().add(bgpAdvertisement);
                        originationVrf.getOriginatedAdvertisements().add(bgpAdvertisement);
                        originationVrf.getOriginatedEbgpAdvertisements().add(bgpAdvertisement);
                    } else {
                        throw new BatfishException("Originated bgp advertisement refers to missing node: \"" + originationNodeName + "\"");
                    }
                    break;
                }
            case IBGP_ORIGINATED:
                {
                    String originationNodeName = bgpAdvertisement.getSrcNode();
                    Configuration originationNode = configurations.get(originationNodeName);
                    if (originationNode != null) {
                        originationNode.getBgpAdvertisements().add(bgpAdvertisement);
                        originationNode.getOriginatedAdvertisements().add(bgpAdvertisement);
                        originationNode.getOriginatedIbgpAdvertisements().add(bgpAdvertisement);
                        Vrf originationVrf = originationNode.getVrfs().get(srcVrf);
                        originationVrf.getBgpAdvertisements().add(bgpAdvertisement);
                        originationVrf.getOriginatedAdvertisements().add(bgpAdvertisement);
                        originationVrf.getOriginatedIbgpAdvertisements().add(bgpAdvertisement);
                    } else {
                        throw new BatfishException("Originated bgp advertisement refers to missing node: \"" + originationNodeName + "\"");
                    }
                    break;
                }
            case EBGP_RECEIVED:
                {
                    String recevingNodeName = bgpAdvertisement.getDstNode();
                    Configuration receivingNode = configurations.get(recevingNodeName);
                    if (receivingNode != null) {
                        receivingNode.getBgpAdvertisements().add(bgpAdvertisement);
                        receivingNode.getReceivedAdvertisements().add(bgpAdvertisement);
                        receivingNode.getReceivedEbgpAdvertisements().add(bgpAdvertisement);
                        Vrf receivingVrf = receivingNode.getVrfs().get(dstVrf);
                        receivingVrf.getBgpAdvertisements().add(bgpAdvertisement);
                        receivingVrf.getReceivedAdvertisements().add(bgpAdvertisement);
                        receivingVrf.getReceivedEbgpAdvertisements().add(bgpAdvertisement);
                    }
                    break;
                }
            case IBGP_RECEIVED:
                {
                    String recevingNodeName = bgpAdvertisement.getDstNode();
                    Configuration receivingNode = configurations.get(recevingNodeName);
                    if (receivingNode != null) {
                        receivingNode.getBgpAdvertisements().add(bgpAdvertisement);
                        receivingNode.getReceivedAdvertisements().add(bgpAdvertisement);
                        receivingNode.getReceivedIbgpAdvertisements().add(bgpAdvertisement);
                        Vrf receivingVrf = receivingNode.getVrfs().get(dstVrf);
                        receivingVrf.getBgpAdvertisements().add(bgpAdvertisement);
                        receivingVrf.getReceivedAdvertisements().add(bgpAdvertisement);
                        receivingVrf.getReceivedIbgpAdvertisements().add(bgpAdvertisement);
                    }
                    break;
                }
            case EBGP_SENT:
                {
                    String sendingNodeName = bgpAdvertisement.getSrcNode();
                    Configuration sendingNode = configurations.get(sendingNodeName);
                    if (sendingNode != null) {
                        sendingNode.getBgpAdvertisements().add(bgpAdvertisement);
                        sendingNode.getSentAdvertisements().add(bgpAdvertisement);
                        sendingNode.getSentEbgpAdvertisements().add(bgpAdvertisement);
                        Vrf sendingVrf = sendingNode.getVrfs().get(srcVrf);
                        sendingVrf.getBgpAdvertisements().add(bgpAdvertisement);
                        sendingVrf.getSentAdvertisements().add(bgpAdvertisement);
                        sendingVrf.getSentEbgpAdvertisements().add(bgpAdvertisement);
                    }
                    break;
                }
            case IBGP_SENT:
                {
                    String sendingNodeName = bgpAdvertisement.getSrcNode();
                    Configuration sendingNode = configurations.get(sendingNodeName);
                    if (sendingNode != null) {
                        sendingNode.getBgpAdvertisements().add(bgpAdvertisement);
                        sendingNode.getSentAdvertisements().add(bgpAdvertisement);
                        sendingNode.getSentIbgpAdvertisements().add(bgpAdvertisement);
                        Vrf sendingVrf = sendingNode.getVrfs().get(srcVrf);
                        sendingVrf.getBgpAdvertisements().add(bgpAdvertisement);
                        sendingVrf.getSentAdvertisements().add(bgpAdvertisement);
                        sendingVrf.getSentIbgpAdvertisements().add(bgpAdvertisement);
                    }
                    break;
                }
            default:
                throw new BatfishException("Invalid bgp advertisement type");
        }
    }
}
Also used : CleanBatfishException(org.batfish.common.CleanBatfishException) BatfishException(org.batfish.common.BatfishException) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) 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) BgpAdvertisementType(org.batfish.datamodel.BgpAdvertisement.BgpAdvertisementType) RoutesByVrf(org.batfish.datamodel.collections.RoutesByVrf) Vrf(org.batfish.datamodel.Vrf) BgpAdvertisementsByVrf(org.batfish.datamodel.collections.BgpAdvertisementsByVrf)

Example 4 with BgpAdvertisementType

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

the class VirtualRouter method propagateBgpRoutes.

int propagateBgpRoutes(Map<Ip, Set<String>> ipOwners, int dependentRoutesIterations, SortedSet<Prefix> oscillatingPrefixes, Map<String, Node> nodes) {
    int numRoutes = 0;
    _receivedBgpAdvertisements = new LinkedHashSet<>();
    _prevSentBgpAdvertisements = _sentBgpAdvertisements != null ? _sentBgpAdvertisements : new LinkedHashSet<>();
    _sentBgpAdvertisements = new LinkedHashSet<>();
    // If we have no BGP process, nothing to do
    if (_vrf.getBgpProcess() == null) {
        return numRoutes;
    }
    int ebgpAdminCost = RoutingProtocol.BGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
    int ibgpAdminCost = RoutingProtocol.IBGP.getDefaultAdministrativeCost(_c.getConfigurationFormat());
    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;
        }
        BgpNeighbor remoteBgpNeighbor = neighbor.getRemoteBgpNeighbor();
        if (remoteBgpNeighbor == null) {
            continue;
        }
        int localAs = neighbor.getLocalAs();
        int remoteAs = neighbor.getRemoteAs();
        Configuration remoteConfig = remoteBgpNeighbor.getOwner();
        String remoteHostname = remoteConfig.getHostname();
        String remoteVrfName = remoteBgpNeighbor.getVrf();
        Vrf remoteVrf = remoteConfig.getVrfs().get(remoteVrfName);
        VirtualRouter remoteVirtualRouter = nodes.get(remoteHostname)._virtualRouters.get(remoteVrfName);
        RoutingPolicy remoteExportPolicy = remoteConfig.getRoutingPolicies().get(remoteBgpNeighbor.getExportPolicy());
        boolean ebgpSession = localAs != remoteAs;
        BgpMultipathRib targetRib = ebgpSession ? _ebgpStagingRib : _ibgpStagingRib;
        RoutingProtocol targetProtocol = ebgpSession ? RoutingProtocol.BGP : RoutingProtocol.IBGP;
        Set<AbstractRoute> remoteCandidateRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
        // Add IGP routes
        Set<AbstractRoute> activeRemoteRoutes = Collections.newSetFromMap(new IdentityHashMap<>());
        activeRemoteRoutes.addAll(remoteVirtualRouter._prevMainRib.getRoutes());
        for (AbstractRoute remoteCandidateRoute : activeRemoteRoutes) {
            if (remoteCandidateRoute.getProtocol() != RoutingProtocol.BGP && remoteCandidateRoute.getProtocol() != RoutingProtocol.IBGP) {
                remoteCandidateRoutes.add(remoteCandidateRoute);
            }
        }
        /*
       * 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 && remoteBgpNeighbor.getAdvertiseExternal();
        if (advertiseExternal) {
            remoteCandidateRoutes.addAll(remoteVirtualRouter._prevEbgpBestPathRib.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 && remoteBgpNeighbor.getAdvertiseInactive();
        /* Add best bgp paths if they are active, or if advertise-inactive */
        for (AbstractRoute remoteCandidateRoute : remoteVirtualRouter._prevBgpBestPathRib.getRoutes()) {
            if (advertiseInactive || activeRemoteRoutes.contains(remoteCandidateRoute)) {
                remoteCandidateRoutes.add(remoteCandidateRoute);
            }
        }
        /* Add all bgp paths if additional-paths active for this session */
        boolean additionalPaths = !ebgpSession && neighbor.getAdditionalPathsReceive() && remoteBgpNeighbor.getAdditionalPathsSend() && remoteBgpNeighbor.getAdditionalPathsSelectAll();
        if (additionalPaths) {
            remoteCandidateRoutes.addAll(remoteVirtualRouter._prevBgpMultipathRib.getRoutes());
        }
        for (AbstractRoute remoteRoute : remoteCandidateRoutes) {
            BgpRoute.Builder transformedOutgoingRouteBuilder = new BgpRoute.Builder();
            transformedOutgoingRouteBuilder.setReceivedFromIp(remoteBgpNeighbor.getLocalIp());
            RoutingProtocol remoteRouteProtocol = remoteRoute.getProtocol();
            boolean remoteRouteIsBgp = remoteRouteProtocol == RoutingProtocol.IBGP || remoteRouteProtocol == RoutingProtocol.BGP;
            // originatorIP
            Ip originatorIp;
            if (!ebgpSession && remoteRouteProtocol.equals(RoutingProtocol.IBGP)) {
                BgpRoute bgpRemoteRoute = (BgpRoute) remoteRoute;
                originatorIp = bgpRemoteRoute.getOriginatorIp();
            } else {
                originatorIp = remoteVrf.getBgpProcess().getRouterId();
            }
            transformedOutgoingRouteBuilder.setOriginatorIp(originatorIp);
            // note whether new route is received from route reflector client
            transformedOutgoingRouteBuilder.setReceivedFromRouteReflectorClient(!ebgpSession && neighbor.getRouteReflectorClient());
            // for bgp remote route)
            if (remoteRouteIsBgp) {
                BgpRoute bgpRemoteRoute = (BgpRoute) remoteRoute;
                transformedOutgoingRouteBuilder.setOriginType(bgpRemoteRoute.getOriginType());
                if (ebgpSession && bgpRemoteRoute.getAsPath().containsAs(remoteBgpNeighbor.getRemoteAs()) && !remoteBgpNeighbor.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 remoteOriginatorIp = bgpRemoteRoute.getOriginatorIp();
                /*
           *  iBGP speaker should not send out routes to iBGP neighbor whose router-id is
           *  same as originator id of advertisement
           */
                if (!ebgpSession && remoteOriginatorIp != null && _vrf.getBgpProcess().getRouterId().equals(remoteOriginatorIp)) {
                    continue;
                }
                if (remoteRouteProtocol.equals(RoutingProtocol.IBGP) && !ebgpSession) {
                    /*
             *  The remote route is iBGP. The session is iBGP. We consider whether to reflect, and
             *  modify the outgoing route as appropriate.
             */
                    boolean remoteRouteReceivedFromRouteReflectorClient = bgpRemoteRoute.getReceivedFromRouteReflectorClient();
                    boolean sendingToRouteReflectorClient = remoteBgpNeighbor.getRouteReflectorClient();
                    Ip remoteReceivedFromIp = bgpRemoteRoute.getReceivedFromIp();
                    boolean remoteRouteOriginatedByRemoteNeighbor = remoteReceivedFromIp.equals(Ip.ZERO);
                    if (!remoteRouteReceivedFromRouteReflectorClient && !sendingToRouteReflectorClient && !remoteRouteOriginatedByRemoteNeighbor) {
                        /*
               * Neither reflecting nor originating this iBGP route, so don't send
               */
                        continue;
                    }
                    transformedOutgoingRouteBuilder.getClusterList().addAll(bgpRemoteRoute.getClusterList());
                    if (!remoteRouteOriginatedByRemoteNeighbor) {
                        // we are reflecting, so we need to get the clusterid associated with the remoteRoute
                        BgpNeighbor remoteReceivedFromSession = remoteVrf.getBgpProcess().getNeighbors().get(new Prefix(remoteReceivedFromIp, Prefix.MAX_PREFIX_LENGTH));
                        long newClusterId = remoteReceivedFromSession.getClusterId();
                        transformedOutgoingRouteBuilder.getClusterList().add(newClusterId);
                    }
                    Set<Long> localClusterIds = _vrf.getBgpProcess().getClusterIds();
                    Set<Long> outgoingClusterList = transformedOutgoingRouteBuilder.getClusterList();
                    if (localClusterIds.stream().anyMatch(outgoingClusterList::contains)) {
                        /*
               *  receiver will reject new route if it contains any of its local cluster ids
               */
                        continue;
                    }
                }
            }
            // Outgoing communities
            if (remoteRouteIsBgp) {
                BgpRoute bgpRemoteRoute = (BgpRoute) remoteRoute;
                transformedOutgoingRouteBuilder.setAsPath(bgpRemoteRoute.getAsPath().getAsSets());
                if (remoteBgpNeighbor.getSendCommunity()) {
                    transformedOutgoingRouteBuilder.getCommunities().addAll(bgpRemoteRoute.getCommunities());
                }
            }
            if (ebgpSession) {
                SortedSet<Integer> newAsPathElement = new TreeSet<>();
                newAsPathElement.add(remoteAs);
                transformedOutgoingRouteBuilder.getAsPath().add(0, newAsPathElement);
            }
            // Outgoing protocol
            transformedOutgoingRouteBuilder.setProtocol(targetProtocol);
            transformedOutgoingRouteBuilder.setNetwork(remoteRoute.getNetwork());
            // Outgoing metric
            if (remoteRouteIsBgp) {
                transformedOutgoingRouteBuilder.setMetric(remoteRoute.getMetric());
            }
            // Outgoing nextHopIp
            // Outgoing localPreference
            Ip nextHopIp;
            int localPreference;
            if (ebgpSession || !remoteRouteIsBgp) {
                nextHopIp = remoteBgpNeighbor.getLocalIp();
                localPreference = BgpRoute.DEFAULT_LOCAL_PREFERENCE;
            } else {
                nextHopIp = remoteRoute.getNextHopIp();
                BgpRoute remoteIbgpRoute = (BgpRoute) remoteRoute;
                localPreference = remoteIbgpRoute.getLocalPreference();
            }
            if (nextHopIp.equals(Route.UNSET_ROUTE_NEXT_HOP_IP)) {
                // should only happen for ibgp
                String nextHopInterface = remoteRoute.getNextHopInterface();
                InterfaceAddress nextHopAddress = remoteVrf.getInterfaces().get(nextHopInterface).getAddress();
                if (nextHopAddress == null) {
                    throw new BatfishException("remote route's nextHopInterface has no address");
                }
                nextHopIp = nextHopAddress.getIp();
            }
            transformedOutgoingRouteBuilder.setNextHopIp(nextHopIp);
            transformedOutgoingRouteBuilder.setLocalPreference(localPreference);
            // Outgoing srcProtocol
            transformedOutgoingRouteBuilder.setSrcProtocol(remoteRoute.getProtocol());
            /*
         * CREATE OUTGOING ROUTE
         */
            boolean acceptOutgoing = remoteExportPolicy.process(remoteRoute, transformedOutgoingRouteBuilder, localIp, remoteVrfName, Direction.OUT);
            if (acceptOutgoing) {
                BgpRoute transformedOutgoingRoute = transformedOutgoingRouteBuilder.build();
                // Record sent advertisement
                BgpAdvertisementType sentType = ebgpSession ? BgpAdvertisementType.EBGP_SENT : BgpAdvertisementType.IBGP_SENT;
                Ip sentReceivedFromIp = transformedOutgoingRoute.getReceivedFromIp();
                Ip sentOriginatorIp = transformedOutgoingRoute.getOriginatorIp();
                SortedSet<Long> sentClusterList = transformedOutgoingRoute.getClusterList();
                boolean sentReceivedFromRouteReflectorClient = transformedOutgoingRoute.getReceivedFromRouteReflectorClient();
                AsPath sentAsPath = transformedOutgoingRoute.getAsPath();
                SortedSet<Long> sentCommunities = transformedOutgoingRoute.getCommunities();
                Prefix sentNetwork = remoteRoute.getNetwork();
                Ip sentNextHopIp;
                String sentSrcNode = remoteHostname;
                String sentSrcVrf = remoteVrfName;
                Ip sentSrcIp = remoteBgpNeighbor.getLocalIp();
                String sentDstNode = hostname;
                String sentDstVrf = _vrf.getName();
                Ip sentDstIp = neighbor.getLocalIp();
                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;
                BgpRoute.Builder transformedIncomingRouteBuilder = new BgpRoute.Builder();
                // Incoming originatorIp
                transformedIncomingRouteBuilder.setOriginatorIp(sentOriginatorIp);
                // Incoming receivedFromIp
                transformedIncomingRouteBuilder.setReceivedFromIp(sentReceivedFromIp);
                // Incoming clusterList
                transformedIncomingRouteBuilder.getClusterList().addAll(sentClusterList);
                // Incoming receivedFromRouteReflectorClient
                transformedIncomingRouteBuilder.setReceivedFromRouteReflectorClient(sentReceivedFromRouteReflectorClient);
                // Incoming asPath
                transformedIncomingRouteBuilder.setAsPath(sentAsPath.getAsSets());
                // Incoming communities
                transformedIncomingRouteBuilder.getCommunities().addAll(sentCommunities);
                // Incoming protocol
                transformedIncomingRouteBuilder.setProtocol(targetProtocol);
                // Incoming network
                transformedIncomingRouteBuilder.setNetwork(sentNetwork);
                // Incoming nextHopIp
                transformedIncomingRouteBuilder.setNextHopIp(sentNextHopIp);
                // Incoming localPreference
                transformedIncomingRouteBuilder.setLocalPreference(sentLocalPreference);
                // Incoming admin
                int admin = ebgpSession ? ebgpAdminCost : ibgpAdminCost;
                transformedIncomingRouteBuilder.setAdmin(admin);
                // Incoming metric
                transformedIncomingRouteBuilder.setMetric(sentMed);
                // Incoming originType
                transformedIncomingRouteBuilder.setOriginType(sentOriginType);
                // Incoming srcProtocol
                transformedIncomingRouteBuilder.setSrcProtocol(sentSrcProtocol);
                String importPolicyName = neighbor.getImportPolicy();
                if (transformedOutgoingRoute.getAsPath().containsAs(neighbor.getLocalAs()) && !neighbor.getAllowLocalAsIn()) {
                    // disable-peer-as-check (getAllowRemoteAsOut) is set
                    continue;
                }
                BgpAdvertisement sentAdvert = new BgpAdvertisement(sentType, sentNetwork, sentNextHopIp, sentSrcNode, sentSrcVrf, sentSrcIp, sentDstNode, sentDstVrf, sentDstIp, sentSrcProtocol, sentOriginType, sentLocalPreference, sentMed, sentOriginatorIp, sentAsPath, sentCommunities, sentClusterList, sentWeight);
                Prefix prefix = remoteRoute.getNetwork();
                boolean isOscillatingPrefix = oscillatingPrefixes.contains(prefix);
                boolean hasAdvertisementPriorityDuringRecovery = hasAdvertisementPriorityDuringRecovery(remoteRoute, dependentRoutesIterations, oscillatingPrefixes, neighbor, remoteBgpNeighbor);
                if (isOscillatingPrefix && !hasAdvertisementPriorityDuringRecovery && !_prevSentBgpAdvertisements.contains(sentAdvert)) {
                    continue;
                }
                _sentBgpAdvertisements.add(sentAdvert);
                /*
           * CREATE INCOMING ROUTE
           */
                boolean acceptIncoming = true;
                if (importPolicyName != null) {
                    RoutingPolicy importPolicy = _c.getRoutingPolicies().get(importPolicyName);
                    if (importPolicy != null) {
                        acceptIncoming = importPolicy.process(transformedOutgoingRoute, transformedIncomingRouteBuilder, remoteBgpNeighbor.getLocalIp(), _key, Direction.IN);
                    }
                }
                if (acceptIncoming) {
                    BgpRoute transformedIncomingRoute = transformedIncomingRouteBuilder.build();
                    BgpAdvertisementType receivedType = ebgpSession ? BgpAdvertisementType.EBGP_RECEIVED : BgpAdvertisementType.IBGP_RECEIVED;
                    Prefix receivedNetwork = sentNetwork;
                    Ip receivedNextHopIp = sentNextHopIp;
                    String receivedSrcNode = sentSrcNode;
                    String receivedSrcVrf = sentSrcVrf;
                    Ip receivedSrcIp = sentSrcIp;
                    String receivedDstNode = sentDstNode;
                    String receivedDstVrf = sentDstVrf;
                    Ip receivedDstIp = sentDstIp;
                    RoutingProtocol receivedSrcProtocol = sentSrcProtocol;
                    OriginType receivedOriginType = transformedIncomingRoute.getOriginType();
                    int receivedLocalPreference = transformedIncomingRoute.getLocalPreference();
                    long receivedMed = transformedIncomingRoute.getMetric();
                    Ip receivedOriginatorIp = sentOriginatorIp;
                    AsPath receivedAsPath = transformedIncomingRoute.getAsPath();
                    SortedSet<Long> receivedCommunities = transformedIncomingRoute.getCommunities();
                    SortedSet<Long> receivedClusterList = sentClusterList;
                    int receivedWeight = transformedIncomingRoute.getWeight();
                    BgpAdvertisement receivedAdvert = new BgpAdvertisement(receivedType, receivedNetwork, receivedNextHopIp, receivedSrcNode, receivedSrcVrf, receivedSrcIp, receivedDstNode, receivedDstVrf, receivedDstIp, receivedSrcProtocol, receivedOriginType, receivedLocalPreference, receivedMed, receivedOriginatorIp, receivedAsPath, receivedCommunities, receivedClusterList, receivedWeight);
                    if (targetRib.mergeRoute(transformedIncomingRoute)) {
                        numRoutes++;
                    }
                    _receivedBgpAdvertisements.add(receivedAdvert);
                }
            }
        }
    }
    return numRoutes;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) Configuration(org.batfish.datamodel.Configuration) BgpAdvertisementType(org.batfish.datamodel.BgpAdvertisement.BgpAdvertisementType) Ip(org.batfish.datamodel.Ip) Vrf(org.batfish.datamodel.Vrf) 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)

Aggregations

BatfishException (org.batfish.common.BatfishException)4 BgpAdvertisement (org.batfish.datamodel.BgpAdvertisement)4 BgpAdvertisementType (org.batfish.datamodel.BgpAdvertisement.BgpAdvertisementType)4 TreeSet (java.util.TreeSet)3 AsPath (org.batfish.datamodel.AsPath)3 BgpNeighbor (org.batfish.datamodel.BgpNeighbor)3 BgpRoute (org.batfish.datamodel.BgpRoute)3 Ip (org.batfish.datamodel.Ip)3 OriginType (org.batfish.datamodel.OriginType)3 Prefix (org.batfish.datamodel.Prefix)3 RoutingProtocol (org.batfish.datamodel.RoutingProtocol)3 RoutingPolicy (org.batfish.datamodel.routing_policy.RoutingPolicy)3 AbstractRoute (org.batfish.datamodel.AbstractRoute)2 Configuration (org.batfish.datamodel.Configuration)2 InterfaceAddress (org.batfish.datamodel.InterfaceAddress)2 Vrf (org.batfish.datamodel.Vrf)2 LinkedHashSet (java.util.LinkedHashSet)1 ImmutableConfiguration (org.apache.commons.configuration2.ImmutableConfiguration)1 CleanBatfishException (org.batfish.common.CleanBatfishException)1 BgpAdvertisementsByVrf (org.batfish.datamodel.collections.BgpAdvertisementsByVrf)1