Search in sources :

Example 11 with AbstractRoute

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

the class BdpDataPlanePluginTest method testEbgpAcceptSameNeighborID.

@Test
public void testEbgpAcceptSameNeighborID() throws IOException {
    String testrigName = "ebgp-accept-routerid-match";
    List<String> configurationNames = ImmutableList.of("r1", "r2", "r3");
    Batfish batfish = BatfishTestUtils.getBatfishFromTestrigText(TestrigText.builder().setConfigurationText(TESTRIGS_PREFIX + testrigName, configurationNames).build(), _folder);
    BdpDataPlanePlugin dataPlanePlugin = new BdpDataPlanePlugin();
    dataPlanePlugin.initialize(batfish);
    batfish.computeDataPlane(false);
    SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>> routes = dataPlanePlugin.getRoutes(batfish.loadDataPlane());
    SortedSet<AbstractRoute> r1Routes = routes.get("r1").get(DEFAULT_VRF_NAME);
    SortedSet<AbstractRoute> r3Routes = routes.get("r3").get(DEFAULT_VRF_NAME);
    Set<Prefix> r1Prefixes = r1Routes.stream().map(r -> r.getNetwork()).collect(Collectors.toSet());
    Set<Prefix> r3Prefixes = r3Routes.stream().map(r -> r.getNetwork()).collect(Collectors.toSet());
    Prefix r1Loopback0Prefix = Prefix.parse("1.0.0.1/32");
    Prefix r3Loopback0Prefix = Prefix.parse("3.0.0.3/32");
    // Ensure that r3loopback was accepted by r1
    assertThat(r3Loopback0Prefix, isIn(r1Prefixes));
    // Check the other direction (r1loopback is accepted by r3)
    assertThat(r1Loopback0Prefix, isIn(r3Prefixes));
}
Also used : AbstractRoute(org.batfish.datamodel.AbstractRoute) Matchers.isA(org.hamcrest.Matchers.isA) SortedSet(java.util.SortedSet) Matchers.not(org.hamcrest.Matchers.not) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Collections.singletonList(java.util.Collections.singletonList) CoreMatchers.notNullValue(org.hamcrest.CoreMatchers.notNullValue) Interface(org.batfish.datamodel.Interface) Assert.assertThat(org.junit.Assert.assertThat) Flow(org.batfish.datamodel.Flow) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Topology(org.batfish.datamodel.Topology) Map(java.util.Map) RoutesByVrf(org.batfish.datamodel.collections.RoutesByVrf) Vrf(org.batfish.datamodel.Vrf) ConfigurationFormat(org.batfish.datamodel.ConfigurationFormat) ImmutableMap(com.google.common.collect.ImmutableMap) Matchers.allOf(org.hamcrest.Matchers.allOf) Collection(java.util.Collection) Set(java.util.Set) Collectors(java.util.stream.Collectors) OriginType(org.batfish.datamodel.OriginType) AsPath(org.batfish.datamodel.AsPath) Settings(org.batfish.config.Settings) List(java.util.List) Stream(java.util.stream.Stream) SourceNat(org.batfish.datamodel.SourceNat) MultipathEquivalentAsPathMatchMode(org.batfish.datamodel.MultipathEquivalentAsPathMatchMode) Assert.assertFalse(org.junit.Assert.assertFalse) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Matchers.is(org.hamcrest.Matchers.is) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) Matchers.containsString(org.hamcrest.Matchers.containsString) SetDefaultPolicy(org.batfish.datamodel.routing_policy.statement.SetDefaultPolicy) SortedMap(java.util.SortedMap) BatfishLogger(org.batfish.common.BatfishLogger) Ip(org.batfish.datamodel.Ip) BatfishTestUtils(org.batfish.main.BatfishTestUtils) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) BdpAnswerElement(org.batfish.datamodel.answers.BdpAnswerElement) HashMap(java.util.HashMap) BatfishException(org.batfish.common.BatfishException) BgpProcess(org.batfish.datamodel.BgpProcess) IpAccessList(org.batfish.datamodel.IpAccessList) DataPlanePlugin(org.batfish.common.plugin.DataPlanePlugin) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Lists(com.google.common.collect.Lists) DEFAULT_VRF_NAME(org.batfish.datamodel.Configuration.DEFAULT_VRF_NAME) ImmutableList(com.google.common.collect.ImmutableList) AbstractRoute(org.batfish.datamodel.AbstractRoute) Matchers.lessThan(org.hamcrest.Matchers.lessThan) Configuration(org.batfish.datamodel.Configuration) Matchers.hasSize(org.hamcrest.Matchers.hasSize) BgpRoute(org.batfish.datamodel.BgpRoute) LineAction(org.batfish.datamodel.LineAction) Batfish(org.batfish.main.Batfish) Matchers.isIn(org.hamcrest.Matchers.isIn) TestrigText(org.batfish.main.TestrigText) ExpectedException(org.junit.rules.ExpectedException) CoreMatchers.nullValue(org.hamcrest.CoreMatchers.nullValue) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Before(org.junit.Before) NetworkFactory(org.batfish.datamodel.NetworkFactory) StaticRoute(org.batfish.datamodel.StaticRoute) Route(org.batfish.datamodel.Route) Assert.assertTrue(org.junit.Assert.assertTrue) IOException(java.io.IOException) Test(org.junit.Test) BdpOscillationException(org.batfish.common.BdpOscillationException) FeatureMatcher(org.hamcrest.FeatureMatcher) Rule(org.junit.Rule) TreeMap(java.util.TreeMap) IpAccessListLine(org.batfish.datamodel.IpAccessListLine) Matcher(org.hamcrest.Matcher) Collections(java.util.Collections) TemporaryFolder(org.junit.rules.TemporaryFolder) Prefix(org.batfish.datamodel.Prefix) SortedMap(java.util.SortedMap) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Matchers.containsString(org.hamcrest.Matchers.containsString) Prefix(org.batfish.datamodel.Prefix) Batfish(org.batfish.main.Batfish) Test(org.junit.Test)

Example 12 with AbstractRoute

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

the class OspfTest method assertNoRoute.

private static void assertNoRoute(SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>> routesByNode, String hostname, InterfaceAddress address) {
    Prefix prefix = address.getPrefix();
    assertThat(routesByNode, hasKey(hostname));
    SortedMap<String, SortedSet<AbstractRoute>> routesByVrf = routesByNode.get(hostname);
    assertThat(routesByVrf, hasKey(Configuration.DEFAULT_VRF_NAME));
    SortedSet<AbstractRoute> routes = routesByVrf.get(Configuration.DEFAULT_VRF_NAME);
    assertThat(routes, not(hasItem(hasPrefix(prefix))));
}
Also used : AbstractRoute(org.batfish.datamodel.AbstractRoute) AbstractRouteMatchers.hasPrefix(org.batfish.datamodel.matchers.AbstractRouteMatchers.hasPrefix) Prefix(org.batfish.datamodel.Prefix) SortedSet(java.util.SortedSet)

Example 13 with AbstractRoute

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

the class BatfishCompressionTest method testCompressionFibs_diamondNetwork.

/**
 * Test the following invariant: if a FIB appears on concrete router “r”, then a corresponding
 * abstract FIB appears on one of these representatives. For example, if there is a concrete FIB
 * from C to D, then there should be an abstract FIB from A to B, where A is in representatives(C)
 * and B is in representatives(D).
 */
@Test
public void testCompressionFibs_diamondNetwork() throws IOException {
    IpAccessListLine line = new IpAccessListLine();
    line.setDstIps(ImmutableList.of(new IpWildcard(Prefix.parse("4.4.4.4/32"))));
    SortedMap<String, Configuration> origConfigs = diamondNetwork();
    DataPlane origDataPlane = getDataPlane(origConfigs);
    Map<String, Map<String, Fib>> origFibs = origDataPlane.getFibs();
    Topology origTopology = new Topology(origDataPlane.getTopologyEdges());
    /* Node A should have a route with C as a next hop. */
    assertThat(origFibs, hasEntry(equalTo("A"), hasEntry(equalTo(Configuration.DEFAULT_VRF_NAME), hasNextHopInterfaces(hasValue(hasKey(withNode("A", isNeighborOfNode(origTopology, "C"))))))));
    // compress a new copy since it will get mutated.
    SortedMap<String, Configuration> compressedConfigs = new TreeMap<>(compressNetwork(diamondNetwork(), line));
    DataPlane compressedDataPlane = getDataPlane(compressedConfigs);
    compressedConfigs.values().forEach(BatfishCompressionTest::assertIsCompressedConfig);
    assertThat(compressedConfigs.values(), hasSize(3));
    SortedMap<String, SortedMap<String, GenericRib<AbstractRoute>>> origRibs = origDataPlane.getRibs();
    SortedMap<String, SortedMap<String, GenericRib<AbstractRoute>>> compressedRibs = compressedDataPlane.getRibs();
    compressedRibs.forEach((hostname, compressedRibsByVrf) -> compressedRibsByVrf.forEach((vrf, compressedRib) -> {
        GenericRib<AbstractRoute> origRib = origRibs.get(hostname).get(vrf);
        Set<AbstractRoute> origRoutes = origRib.getRoutes();
        Set<AbstractRoute> compressedRoutes = compressedRib.getRoutes();
        for (AbstractRoute route : compressedRoutes) {
            /* Every compressed route should appear in original RIB */
            assertThat(origRoutes, hasItem(route));
        }
    }));
    /* Compression removed B or C entirely (but not both) */
    assertThat(compressedRibs, either(not(hasKey("B"))).or(not(hasKey("C"))));
    assertThat(compressedRibs, either(hasKey("B")).or(hasKey("C")));
    String remains = compressedConfigs.containsKey("B") ? "B" : "C";
    /* The remaining node is unchanged. */
    assertThat(origRibs.get(remains).get(Configuration.DEFAULT_VRF_NAME).getRoutes(), equalTo(compressedRibs.get(remains).get(Configuration.DEFAULT_VRF_NAME).getRoutes()));
}
Also used : DataPlane(org.batfish.datamodel.DataPlane) AbstractRoute(org.batfish.datamodel.AbstractRoute) BatfishTestUtils(org.batfish.main.BatfishTestUtils) FibMatchers.hasNextHopInterfaces(org.batfish.datamodel.matchers.FibMatchers.hasNextHopInterfaces) BdpDataPlanePlugin(org.batfish.bdp.BdpDataPlanePlugin) HeaderSpace(org.batfish.datamodel.HeaderSpace) Matchers.either(org.hamcrest.Matchers.either) If(org.batfish.datamodel.routing_policy.statement.If) TopologyMatchers.isNeighborOfNode(org.batfish.datamodel.matchers.TopologyMatchers.isNeighborOfNode) Matchers.not(org.hamcrest.Matchers.not) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Matchers.hasValue(org.hamcrest.Matchers.hasValue) Matchers.hasKey(org.hamcrest.Matchers.hasKey) Interface(org.batfish.datamodel.Interface) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) TestCase.assertNotNull(junit.framework.TestCase.assertNotNull) ImmutableList(com.google.common.collect.ImmutableList) AbstractRoute(org.batfish.datamodel.AbstractRoute) Topology(org.batfish.datamodel.Topology) TopologyMatchers.withNode(org.batfish.datamodel.matchers.TopologyMatchers.withNode) Map(java.util.Map) Configuration(org.batfish.datamodel.Configuration) Matchers.hasSize(org.hamcrest.Matchers.hasSize) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Batfish(org.batfish.main.Batfish) Vrf(org.batfish.datamodel.Vrf) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Matchers.hasEntry(org.hamcrest.Matchers.hasEntry) ConfigurationFormat(org.batfish.datamodel.ConfigurationFormat) DataPlane(org.batfish.datamodel.DataPlane) NetworkFactory(org.batfish.datamodel.NetworkFactory) StaticRoute(org.batfish.datamodel.StaticRoute) Fib(org.batfish.datamodel.Fib) Set(java.util.Set) GenericRib(org.batfish.datamodel.GenericRib) IOException(java.io.IOException) Test(org.junit.Test) IBatfish(org.batfish.common.plugin.IBatfish) Matchers.hasItem(org.hamcrest.Matchers.hasItem) TreeMap(java.util.TreeMap) IpAccessListLine(org.batfish.datamodel.IpAccessListLine) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Assert.assertEquals(org.junit.Assert.assertEquals) SortedMap(java.util.SortedMap) IpWildcard(org.batfish.datamodel.IpWildcard) TemporaryFolder(org.junit.rules.TemporaryFolder) Prefix(org.batfish.datamodel.Prefix) Set(java.util.Set) Configuration(org.batfish.datamodel.Configuration) GenericRib(org.batfish.datamodel.GenericRib) Topology(org.batfish.datamodel.Topology) TreeMap(java.util.TreeMap) IpWildcard(org.batfish.datamodel.IpWildcard) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) SortedMap(java.util.SortedMap) IpAccessListLine(org.batfish.datamodel.IpAccessListLine) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) Test(org.junit.Test)

Example 14 with AbstractRoute

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

the class BatfishCompressionTest method testCompressionFibs_simpleNetwork.

/**
 * Test that compression doesn't change the fibs for this network.
 */
@Test
public void testCompressionFibs_simpleNetwork() throws IOException {
    DataPlane origDataPlane = getDataPlane(simpleNetwork());
    SortedMap<String, Configuration> compressedConfigs = compressNetwork(simpleNetwork(), new HeaderSpace());
    DataPlane compressedDataPlane = getDataPlane(compressedConfigs);
    SortedMap<String, SortedMap<String, GenericRib<AbstractRoute>>> origRibs = origDataPlane.getRibs();
    SortedMap<String, SortedMap<String, GenericRib<AbstractRoute>>> compressedRibs = compressedDataPlane.getRibs();
    compressedRibs.forEach((hostname, compressedRibsByVrf) -> compressedRibsByVrf.forEach((vrf, compressedRib) -> {
        GenericRib<AbstractRoute> origRib = origRibs.get(hostname).get(vrf);
        Set<AbstractRoute> origRoutes = origRib.getRoutes();
        Set<AbstractRoute> compressedRoutes = compressedRib.getRoutes();
        for (AbstractRoute route : compressedRoutes) {
            /* Every compressed route should appear in original RIB */
            assertThat(origRoutes, hasItem(route));
        }
    }));
    compressedConfigs.values().forEach(BatfishCompressionTest::assertIsCompressedConfig);
    /* No nodes should be missing */
    assertThat(origRibs.keySet(), equalTo(compressedRibs.keySet()));
}
Also used : DataPlane(org.batfish.datamodel.DataPlane) AbstractRoute(org.batfish.datamodel.AbstractRoute) BatfishTestUtils(org.batfish.main.BatfishTestUtils) FibMatchers.hasNextHopInterfaces(org.batfish.datamodel.matchers.FibMatchers.hasNextHopInterfaces) BdpDataPlanePlugin(org.batfish.bdp.BdpDataPlanePlugin) HeaderSpace(org.batfish.datamodel.HeaderSpace) Matchers.either(org.hamcrest.Matchers.either) If(org.batfish.datamodel.routing_policy.statement.If) TopologyMatchers.isNeighborOfNode(org.batfish.datamodel.matchers.TopologyMatchers.isNeighborOfNode) Matchers.not(org.hamcrest.Matchers.not) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Matchers.hasValue(org.hamcrest.Matchers.hasValue) Matchers.hasKey(org.hamcrest.Matchers.hasKey) Interface(org.batfish.datamodel.Interface) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) TestCase.assertNotNull(junit.framework.TestCase.assertNotNull) ImmutableList(com.google.common.collect.ImmutableList) AbstractRoute(org.batfish.datamodel.AbstractRoute) Topology(org.batfish.datamodel.Topology) TopologyMatchers.withNode(org.batfish.datamodel.matchers.TopologyMatchers.withNode) Map(java.util.Map) Configuration(org.batfish.datamodel.Configuration) Matchers.hasSize(org.hamcrest.Matchers.hasSize) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Batfish(org.batfish.main.Batfish) Vrf(org.batfish.datamodel.Vrf) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Matchers.hasEntry(org.hamcrest.Matchers.hasEntry) ConfigurationFormat(org.batfish.datamodel.ConfigurationFormat) DataPlane(org.batfish.datamodel.DataPlane) NetworkFactory(org.batfish.datamodel.NetworkFactory) StaticRoute(org.batfish.datamodel.StaticRoute) Fib(org.batfish.datamodel.Fib) Set(java.util.Set) GenericRib(org.batfish.datamodel.GenericRib) IOException(java.io.IOException) Test(org.junit.Test) IBatfish(org.batfish.common.plugin.IBatfish) Matchers.hasItem(org.hamcrest.Matchers.hasItem) TreeMap(java.util.TreeMap) IpAccessListLine(org.batfish.datamodel.IpAccessListLine) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Assert.assertEquals(org.junit.Assert.assertEquals) SortedMap(java.util.SortedMap) IpWildcard(org.batfish.datamodel.IpWildcard) TemporaryFolder(org.junit.rules.TemporaryFolder) Prefix(org.batfish.datamodel.Prefix) Set(java.util.Set) Configuration(org.batfish.datamodel.Configuration) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) SortedMap(java.util.SortedMap) GenericRib(org.batfish.datamodel.GenericRib) HeaderSpace(org.batfish.datamodel.HeaderSpace) Test(org.junit.Test)

Example 15 with AbstractRoute

use of org.batfish.datamodel.AbstractRoute 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

AbstractRoute (org.batfish.datamodel.AbstractRoute)27 Prefix (org.batfish.datamodel.Prefix)18 SortedMap (java.util.SortedMap)16 SortedSet (java.util.SortedSet)13 TreeMap (java.util.TreeMap)12 Set (java.util.Set)11 Ip (org.batfish.datamodel.Ip)10 Batfish (org.batfish.main.Batfish)10 TreeSet (java.util.TreeSet)9 InterfaceAddress (org.batfish.datamodel.InterfaceAddress)9 Test (org.junit.Test)9 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)8 Map (java.util.Map)8 Configuration (org.batfish.datamodel.Configuration)8 Interface (org.batfish.datamodel.Interface)8 ImmutableSortedSet (com.google.common.collect.ImmutableSortedSet)7 StaticRoute (org.batfish.datamodel.StaticRoute)7 Vrf (org.batfish.datamodel.Vrf)7 ImmutableList (com.google.common.collect.ImmutableList)6 IOException (java.io.IOException)6