use of com.google.common.graph.ValueGraph in project batfish by batfish.
the class BgpSessionCompatibilityAnswerer method getRows.
/**
* Return the answer for {@link BgpSessionCompatibilityQuestion} -- a set of BGP sessions and
* their compatibility.
*/
private List<Row> getRows(NetworkSnapshot snapshot, BgpSessionCompatibilityQuestion question) {
Map<String, Configuration> configurations = _batfish.loadConfigurations(snapshot);
NetworkConfigurations nc = NetworkConfigurations.of(configurations);
SpecifierContext specifierContext = _batfish.specifierContext(snapshot);
Set<String> nodes = question.getNodeSpecifier().resolve(specifierContext);
Set<String> remoteNodes = question.getRemoteNodeSpecifier().resolve(specifierContext);
L3Adjacencies l3Adjacencies = _batfish.getTopologyProvider().getInitialL3Adjacencies(snapshot);
Map<Ip, Map<String, Set<String>>> ipVrfOwners = _batfish.getTopologyProvider().getInitialIpOwners(snapshot).getIpVrfOwners();
ValueGraph<BgpPeerConfigId, BgpSessionProperties> configuredTopology = BgpTopologyUtils.initBgpTopology(configurations, ipVrfOwners, true, l3Adjacencies).getGraph();
// Generate answer row for each BGP peer (or rows, for dynamic peers with multiple remotes)
return configuredTopology.nodes().stream().flatMap(peerId -> {
switch(peerId.getType()) {
case ACTIVE:
BgpActivePeerConfig activePeer = nc.getBgpPointToPointPeerConfig(peerId);
assert activePeer != null;
return Stream.of(getActivePeerRow(peerId, activePeer, ipVrfOwners, configuredTopology));
case DYNAMIC:
BgpPassivePeerConfig passivePeer = nc.getBgpDynamicPeerConfig(peerId);
assert passivePeer != null;
return getPassivePeerRows(peerId, passivePeer, nc, configuredTopology).stream();
case UNNUMBERED:
BgpUnnumberedPeerConfig unnumPeer = nc.getBgpUnnumberedPeerConfig(peerId);
assert unnumPeer != null;
return Stream.of(getUnnumberedPeerRow(peerId, unnumPeer, configuredTopology));
default:
throw new BatfishException(String.format("Unsupported type of BGP peer config: %s", peerId.getType()));
}
}).filter(row -> matchesQuestionFilters(row, nodes, remoteNodes, question)).collect(ImmutableList.toImmutableList());
}
use of com.google.common.graph.ValueGraph in project batfish by batfish.
the class BgpSessionCompatibilityAnswerer method getPassivePeerRows.
@Nonnull
@VisibleForTesting
static List<Row> getPassivePeerRows(BgpPeerConfigId passiveId, BgpPassivePeerConfig passivePeer, NetworkConfigurations nc, ValueGraph<BgpPeerConfigId, BgpSessionProperties> configuredTopology) {
// Start row with base columns. Need to add status.
// If there are compatible peers, will also add remote node and replace:
// - local IP, with the remote node's remote IP
// - remote AS
// - remote IP
// - session type
// Local and remote interface will not be filled in (reserved for unnumbered peers).
Row.TypedRowBuilder rb = Row.builder(METADATA_MAP).put(COL_LOCAL_AS, passivePeer.getLocalAs()).put(COL_LOCAL_IP, passivePeer.getLocalIp()).put(COL_NODE, new Node(passiveId.getHostname())).put(COL_REMOTE_AS, passivePeer.getRemoteAsns().toString()).put(COL_REMOTE_IP, new SelfDescribingObject(Schema.PREFIX, passivePeer.getPeerPrefix())).put(COL_ADDRESS_FAMILIES, ImmutableSet.of()).put(COL_SESSION_TYPE, SessionType.UNSET).put(COL_VRF, passiveId.getVrfName());
// If peer has null remote prefix or empty remote AS list, generate one row
ConfiguredSessionStatus brokenStatus = getLocallyBrokenStatus(passivePeer);
if (brokenStatus != null) {
return ImmutableList.of(rb.put(COL_CONFIGURED_STATUS, brokenStatus).build());
}
// Create a row for each valid remote peer compatible with this peer
List<Row> rows = configuredTopology.adjacentNodes(passiveId).stream().filter(remoteId -> configuredTopology.inDegree(remoteId) == 1).map(remoteId -> {
BgpSessionProperties sessionProps = configuredTopology.edgeValue(passiveId, remoteId).orElse(null);
assert sessionProps != null;
BgpActivePeerConfig activeRemote = nc.getBgpPointToPointPeerConfig(remoteId);
assert activeRemote != null;
return rb.put(COL_CONFIGURED_STATUS, DYNAMIC_MATCH).put(COL_ADDRESS_FAMILIES, sessionProps.getAddressFamilies()).put(COL_LOCAL_IP, sessionProps.getLocalIp()).put(COL_LOCAL_AS, sessionProps.getLocalAs()).put(COL_REMOTE_AS, Long.toString(sessionProps.getRemoteAs())).put(COL_REMOTE_NODE, new Node(remoteId.getHostname())).put(COL_REMOTE_IP, new SelfDescribingObject(Schema.IP, sessionProps.getRemoteIp())).put(COL_SESSION_TYPE, getSessionType(activeRemote)).build();
}).collect(ImmutableList.toImmutableList());
// If no compatible neighbors were found, generate one NO_MATCH_FOUND row
return rows.isEmpty() ? ImmutableList.of(rb.put(COL_CONFIGURED_STATUS, NO_MATCH_FOUND).build()) : rows;
}
use of com.google.common.graph.ValueGraph in project batfish by batfish.
the class BgpSessionStatusAnswerer method getPassivePeerRows.
@Nonnull
@VisibleForTesting
static List<Row> getPassivePeerRows(BgpPeerConfigId passiveId, BgpPassivePeerConfig passivePeer, NetworkConfigurations nc, ValueGraph<BgpPeerConfigId, BgpSessionProperties> configuredTopology, ValueGraph<BgpPeerConfigId, BgpSessionProperties> establishedTopology) {
// Start row with base columns. Need to add status.
// If there are compatible peers, will also add remote node and replace:
// - local IP, with the remote node's remote IP
// - remote AS
// - remote IP
// - session type
// Local and remote interface will not be filled in (reserved for unnumbered peers).
Row.TypedRowBuilder rb = Row.builder(METADATA_MAP).put(COL_ADDRESS_FAMILIES, ImmutableSet.of()).put(COL_LOCAL_AS, passivePeer.getLocalAs()).put(COL_LOCAL_IP, passivePeer.getLocalIp()).put(COL_NODE, new Node(passiveId.getHostname())).put(COL_REMOTE_AS, passivePeer.getRemoteAsns().toString()).put(COL_REMOTE_IP, new SelfDescribingObject(Schema.PREFIX, passivePeer.getPeerPrefix())).put(COL_SESSION_TYPE, SessionType.UNSET).put(COL_VRF, passiveId.getVrfName());
// If peer is locally misconfigured (missing remote prefix or local/remote AS) generate one row
if (getLocallyBrokenStatus(passivePeer) != null) {
return ImmutableList.of(rb.put(COL_ESTABLISHED_STATUS, NOT_COMPATIBLE).build());
}
// Find all correctly configured remote peers compatible with this peer
Set<BgpPeerConfigId> compatibleRemotes = configuredTopology.adjacentNodes(passiveId);
// If no compatible neighbors exist, generate one NOT_ESTABLISHED row
if (compatibleRemotes.isEmpty()) {
return ImmutableList.of(rb.put(COL_ESTABLISHED_STATUS, NOT_ESTABLISHED).build());
}
// Find all remote peers that established a session with this peer. Passive peer will not be in
// establishedBgpTopology at all it was invalid according to bgpConfigPassesSanityChecks()
Set<BgpPeerConfigId> establishedRemotes = establishedTopology.nodes().contains(passiveId) ? establishedTopology.adjacentNodes(passiveId) : ImmutableSet.of();
// Compatible remotes exist. Generate a row for each.
return compatibleRemotes.stream().map(remoteId -> {
BgpSessionProperties sessionProps = configuredTopology.edgeValue(passiveId, remoteId).orElse(null);
assert sessionProps != null;
BgpActivePeerConfig activeRemote = nc.getBgpPointToPointPeerConfig(remoteId);
assert activeRemote != null;
BgpSessionStatus status = establishedRemotes.contains(remoteId) ? ESTABLISHED : NOT_ESTABLISHED;
return rb.put(COL_ESTABLISHED_STATUS, status).put(COL_ADDRESS_FAMILIES, sessionProps.getAddressFamilies()).put(COL_LOCAL_IP, sessionProps.getLocalIp()).put(COL_LOCAL_AS, sessionProps.getLocalAs()).put(COL_REMOTE_AS, Long.toString(sessionProps.getRemoteAs())).put(COL_REMOTE_NODE, new Node(remoteId.getHostname())).put(COL_REMOTE_IP, new SelfDescribingObject(Schema.IP, sessionProps.getRemoteIp())).put(COL_SESSION_TYPE, sessionProps.getSessionType()).build();
}).collect(ImmutableList.toImmutableList());
}
use of com.google.common.graph.ValueGraph in project batfish by batfish.
the class BgpSessionStatusAnswerer method getRows.
/**
* Return the answer for {@link BgpSessionStatusQuestion} -- a set of BGP sessions and their
* status.
*/
private List<Row> getRows(NetworkSnapshot snapshot, BgpSessionStatusQuestion question) {
Map<String, Configuration> configurations = _batfish.loadConfigurations(snapshot);
NetworkConfigurations nc = NetworkConfigurations.of(configurations);
SpecifierContext specifierContext = _batfish.specifierContext(snapshot);
Set<String> nodes = question.getNodeSpecifier().resolve(specifierContext);
Set<String> remoteNodes = question.getRemoteNodeSpecifier().resolve(specifierContext);
TopologyProvider topologyProvider = _batfish.getTopologyProvider();
Map<Ip, Map<String, Set<String>>> ipVrfOwners = topologyProvider.getInitialIpOwners(snapshot).getIpVrfOwners();
L3Adjacencies adjacencies = topologyProvider.getL3Adjacencies(snapshot);
ValueGraph<BgpPeerConfigId, BgpSessionProperties> configuredTopology = BgpTopologyUtils.initBgpTopology(configurations, ipVrfOwners, true, adjacencies).getGraph();
ValueGraph<BgpPeerConfigId, BgpSessionProperties> establishedTopology = topologyProvider.getBgpTopology(snapshot).getGraph();
// Generate answer row for each BGP peer (or rows, for dynamic peers with multiple remotes)
return configuredTopology.nodes().stream().flatMap(peerId -> {
switch(peerId.getType()) {
case ACTIVE:
BgpActivePeerConfig activePeer = nc.getBgpPointToPointPeerConfig(peerId);
assert activePeer != null;
return Stream.of(getActivePeerRow(peerId, activePeer, ipVrfOwners, configuredTopology, establishedTopology));
case DYNAMIC:
BgpPassivePeerConfig passivePeer = nc.getBgpDynamicPeerConfig(peerId);
assert passivePeer != null;
return getPassivePeerRows(peerId, passivePeer, nc, configuredTopology, establishedTopology).stream();
case UNNUMBERED:
BgpUnnumberedPeerConfig unnumPeer = nc.getBgpUnnumberedPeerConfig(peerId);
assert unnumPeer != null;
return Stream.of(getUnnumberedPeerRow(peerId, unnumPeer, configuredTopology, establishedTopology));
default:
throw new BatfishException(String.format("Unsupported type of BGP peer config: %s", peerId.getType()));
}
}).filter(row -> matchesQuestionFilters(row, nodes, remoteNodes, question)).collect(ImmutableList.toImmutableList());
}
use of com.google.common.graph.ValueGraph in project batfish by batfish.
the class AristaGrammarTest method testBgpLocalAs.
@Test
public void testBgpLocalAs() throws IOException {
String testrigName = "arista-bgp-local-as";
List<String> configurationNames = ImmutableList.of("r1", "r2");
Batfish batfish = BatfishTestUtils.getBatfishFromTestrigText(TestrigText.builder().setConfigurationFiles(SNAPSHOTS_PREFIX + testrigName, configurationNames).build(), _folder);
Map<String, Configuration> configurations = batfish.loadConfigurations(batfish.getSnapshot());
assertTrue(configurations.values().stream().allMatch(c -> c.getConfigurationFormat() == ARISTA));
Map<Ip, Map<String, Set<String>>> ipOwners = batfish.getTopologyProvider().getInitialIpOwners(batfish.getSnapshot()).getIpVrfOwners();
ValueGraph<BgpPeerConfigId, BgpSessionProperties> bgpTopology = BgpTopologyUtils.initBgpTopology(configurations, ipOwners, false, null).getGraph();
// Edge one direction
assertThat(bgpTopology.adjacentNodes(new BgpPeerConfigId("r1", DEFAULT_VRF_NAME, Prefix.parse("1.2.0.2/32"), false)).iterator().next(), equalTo(new BgpPeerConfigId("r2", DEFAULT_VRF_NAME, Prefix.parse("1.2.0.1/32"), false)));
// Edge the other direction
assertThat(bgpTopology.adjacentNodes(new BgpPeerConfigId("r2", DEFAULT_VRF_NAME, Prefix.parse("1.2.0.1/32"), false)).iterator().next(), equalTo(new BgpPeerConfigId("r1", DEFAULT_VRF_NAME, Prefix.parse("1.2.0.2/32"), false)));
}
Aggregations