use of org.batfish.symbolic.GraphEdge in project batfish by batfish.
the class AbstractionBuilder method createAbstractConfig.
/*
* Creates a new Configuration from an old one for an abstract router
* by copying the old configuration, but removing any concrete interfaces,
* neighbors etc that do not correpond to any abstract neighbors.
*/
private Configuration createAbstractConfig(Set<String> abstractRouters, Configuration conf) {
Configuration abstractConf = new Configuration(conf.getHostname(), conf.getConfigurationFormat());
abstractConf.setDnsServers(conf.getDnsServers());
abstractConf.setDnsSourceInterface(conf.getDnsSourceInterface());
abstractConf.setDomainName(conf.getDomainName());
abstractConf.setAuthenticationKeyChains(conf.getAuthenticationKeyChains());
abstractConf.setIkeGateways(conf.getIkeGateways());
abstractConf.setDefaultCrossZoneAction(conf.getDefaultCrossZoneAction());
abstractConf.setIkePolicies(conf.getIkePolicies());
abstractConf.setIkeProposals(conf.getIkeProposals());
abstractConf.setDefaultInboundAction(conf.getDefaultInboundAction());
abstractConf.setIpAccessLists(conf.getIpAccessLists());
abstractConf.setIp6AccessLists(conf.getIp6AccessLists());
abstractConf.setRouteFilterLists(conf.getRouteFilterLists());
abstractConf.setRoute6FilterLists(conf.getRoute6FilterLists());
abstractConf.setIpsecPolicies(conf.getIpsecPolicies());
abstractConf.setIpsecProposals(conf.getIpsecProposals());
abstractConf.setIpsecVpns(conf.getIpsecVpns());
abstractConf.setLoggingServers(conf.getLoggingServers());
abstractConf.setLoggingSourceInterface(conf.getLoggingSourceInterface());
abstractConf.setNormalVlanRange(conf.getNormalVlanRange());
abstractConf.setNtpServers(conf.getNtpServers());
abstractConf.setNtpSourceInterface(conf.getNtpSourceInterface());
abstractConf.setRoles(conf.getRoles());
abstractConf.setSnmpSourceInterface(conf.getSnmpSourceInterface());
abstractConf.setSnmpTrapServers(conf.getSnmpTrapServers());
abstractConf.setTacacsServers(conf.getTacacsServers());
abstractConf.setTacacsSourceInterface(conf.getTacacsSourceInterface());
abstractConf.setVendorFamily(conf.getVendorFamily());
abstractConf.setZones(conf.getZones());
abstractConf.setCommunityLists(conf.getCommunityLists());
abstractConf.setRoutingPolicies(conf.getRoutingPolicies());
abstractConf.setRoute6FilterLists(conf.getRoute6FilterLists());
SortedSet<Interface> toRetain = new TreeSet<>();
SortedSet<IpLink> ipNeighbors = new TreeSet<>();
SortedSet<BgpNeighbor> bgpNeighbors = new TreeSet<>();
List<GraphEdge> edges = _graph.getEdgeMap().get(conf.getName());
for (GraphEdge ge : edges) {
boolean leavesNetwork = (ge.getPeer() == null);
if (leavesNetwork || (abstractRouters.contains(ge.getRouter()) && abstractRouters.contains(ge.getPeer()))) {
toRetain.add(ge.getStart());
Ip start = ge.getStart().getAddress().getIp();
if (!leavesNetwork) {
Ip end = ge.getEnd().getAddress().getIp();
ipNeighbors.add(new IpLink(start, end));
}
BgpNeighbor n = _graph.getEbgpNeighbors().get(ge);
if (n != null) {
bgpNeighbors.add(n);
}
}
}
// Update interfaces
NavigableMap<String, Interface> abstractInterfaces = new TreeMap<>();
for (Entry<String, Interface> entry : conf.getInterfaces().entrySet()) {
String name = entry.getKey();
Interface iface = entry.getValue();
if (toRetain.contains(iface)) {
abstractInterfaces.put(name, iface);
}
}
abstractConf.setInterfaces(abstractInterfaces);
// Update VRFs
Map<String, Vrf> abstractVrfs = new HashMap<>();
for (Entry<String, Vrf> entry : conf.getVrfs().entrySet()) {
String name = entry.getKey();
Vrf vrf = entry.getValue();
Vrf abstractVrf = new Vrf(name);
abstractVrf.setStaticRoutes(vrf.getStaticRoutes());
abstractVrf.setIsisProcess(vrf.getIsisProcess());
abstractVrf.setRipProcess(vrf.getRipProcess());
abstractVrf.setSnmpServer(vrf.getSnmpServer());
NavigableMap<String, Interface> abstractVrfInterfaces = new TreeMap<>();
for (Entry<String, Interface> entry2 : vrf.getInterfaces().entrySet()) {
String iname = entry2.getKey();
Interface iface = entry2.getValue();
if (toRetain.contains(iface)) {
abstractVrfInterfaces.put(iname, iface);
}
}
abstractVrf.setInterfaces(abstractVrfInterfaces);
abstractVrf.setInterfaceNames(new TreeSet<>(abstractVrfInterfaces.keySet()));
OspfProcess ospf = vrf.getOspfProcess();
if (ospf != null) {
OspfProcess abstractOspf = new OspfProcess();
abstractOspf.setAreas(ospf.getAreas());
abstractOspf.setExportPolicy(ospf.getExportPolicy());
abstractOspf.setReferenceBandwidth(ospf.getReferenceBandwidth());
abstractOspf.setRouterId(ospf.getRouterId());
// Copy over neighbors
Map<IpLink, OspfNeighbor> abstractNeighbors = new HashMap<>();
if (ospf.getOspfNeighbors() != null) {
for (Entry<IpLink, OspfNeighbor> entry2 : ospf.getOspfNeighbors().entrySet()) {
IpLink link = entry2.getKey();
OspfNeighbor neighbor = entry2.getValue();
if (ipNeighbors.contains(link)) {
abstractNeighbors.put(link, neighbor);
}
}
}
abstractOspf.setOspfNeighbors(abstractNeighbors);
abstractVrf.setOspfProcess(abstractOspf);
}
BgpProcess bgp = vrf.getBgpProcess();
if (bgp != null) {
BgpProcess abstractBgp = new BgpProcess();
abstractBgp.setMultipathEbgp(bgp.getMultipathEbgp());
abstractBgp.setMultipathIbgp(bgp.getMultipathIbgp());
abstractBgp.setRouterId(bgp.getRouterId());
abstractBgp.setOriginationSpace(bgp.getOriginationSpace());
// TODO: set bgp neighbors accordingly
// Copy over neighbors
SortedMap<Prefix, BgpNeighbor> abstractBgpNeighbors = new TreeMap<>();
if (bgp.getNeighbors() != null) {
for (Entry<Prefix, BgpNeighbor> entry2 : bgp.getNeighbors().entrySet()) {
Prefix prefix = entry2.getKey();
BgpNeighbor neighbor = entry2.getValue();
if (bgpNeighbors.contains(neighbor)) {
abstractBgpNeighbors.put(prefix, neighbor);
}
}
}
abstractBgp.setNeighbors(abstractBgpNeighbors);
abstractVrf.setBgpProcess(abstractBgp);
}
abstractVrfs.put(name, abstractVrf);
}
abstractConf.setVrfs(abstractVrfs);
return abstractConf;
}
use of org.batfish.symbolic.GraphEdge in project batfish by batfish.
the class AbstractionBuilder method pickCanonicalRouters.
/*
* Given a collection of abstract roles, selects a set of canonical
* representatives from each role that serve as the abstraction.
*/
private Map<Integer, Set<String>> pickCanonicalRouters() {
Table2<String, Integer, Set<String>> neighborByAbstractId = collectNeighborByAbstractId();
Map<Integer, Set<String>> chosen = new HashMap<>();
Stack<String> stack = new Stack<>();
List<String> options = new ArrayList<>();
if (_destinations.isEmpty()) {
// When destination only can be from external
// Pick a representative from each externally-facing abstract group
Set<Integer> picked = new HashSet<>();
for (GraphEdge ge : _graph.getAllRealEdges()) {
if (_graph.isExternal(ge)) {
String d = ge.getRouter();
Integer i = _abstractGroups.getHandle(d);
if (!picked.contains(i)) {
Set<String> dest = new HashSet<>();
dest.add(d);
stack.push(d);
chosen.put(i, dest);
picked.add(i);
}
}
}
} else {
// Start with the concrete nodes
for (String d : _destinations) {
stack.push(d);
Set<String> dest = new HashSet<>();
dest.add(d);
chosen.put(_abstractGroups.getHandle(d), dest);
}
}
// Need to choose representatives that are connected
while (!stack.isEmpty()) {
String router = stack.pop();
Map<Integer, Set<String>> neighbors = neighborByAbstractId.get(router);
if (neighbors == null) {
continue;
}
for (Entry<Integer, Set<String>> entry : neighbors.entrySet()) {
Integer j = entry.getKey();
Set<String> peers = entry.getValue();
Set<String> chosenPeers = chosen.computeIfAbsent(j, k -> new HashSet<>());
// Find how many choices we need, and collect the options
int numNeeded = _possibleFailures + 1;
options.clear();
for (String x : peers) {
if (chosenPeers.contains(x)) {
numNeeded--;
} else {
options.add(x);
}
}
// Add new neighbors until satisfied
for (int k = 0; k < Math.min(numNeeded, options.size()); k++) {
String y = options.get(k);
chosenPeers.add(y);
stack.push(y);
}
}
}
return chosen;
}
use of org.batfish.symbolic.GraphEdge in project batfish by batfish.
the class AbstractionBuilder method collectInterfaceInformation.
private void collectInterfaceInformation(Set<String> partition, boolean isUniversal) {
for (String router : partition) {
List<GraphEdge> edges = _graph.getEdgeMap().get(router);
for (GraphEdge edge : edges) {
String peer = edge.getPeer();
InterfacePolicy ipol = _importPol.get(edge);
GraphEdge otherEnd = _graph.getOtherEnd().get(edge);
InterfacePolicy epol = null;
if (otherEnd != null) {
epol = _exportPol.get(otherEnd);
}
// Update the existential map
Integer peerGroup = (peer == null ? (_graph.isExternal(edge) ? EBGP_INDEX : HOST_OR_LOOPBACK_INDEX) : _abstractGroups.getHandle(peer));
EdgePolicy pair = new EdgePolicy(ipol, epol);
EdgePolicyToRole ee = new EdgePolicyToRole(peerGroup, pair);
if (isUniversal) {
// Universal abstraction
Tuple<String, EdgePolicyToRole> tup = new Tuple<>(peer, ee);
Set<Tuple<String, EdgePolicyToRole>> group = _universalMap.computeIfAbsent(router, k -> new HashSet<>());
group.add(tup);
} else {
// Existential abstraction
Integer i = _existentialMap.get(router, ee);
i = (i == null ? 1 : i + 1);
_existentialMap.put(router, ee, i);
}
// Update the id map
if (peerGroup >= 0) {
Set<EdgePolicyToRole> x = _eeMap.computeIfAbsent(router, peerGroup, (k1, k2) -> new HashSet<>());
x.add(ee);
Set<EdgePolicy> y = _polMap.computeIfAbsent(router, peerGroup, (k1, k2) -> new HashSet<>());
y.add(pair);
}
}
}
}
use of org.batfish.symbolic.GraphEdge in project batfish by batfish.
the class AbstractionBuilder method collectNeighborByAbstractId.
/*
* Collect concrete neighbors by their abstract ids
*/
private Table2<String, Integer, Set<String>> collectNeighborByAbstractId() {
// organize neighbors by abstract id
Table2<String, Integer, Set<String>> neighborByAbstractId = new Table2<>();
for (Entry<String, List<GraphEdge>> entry : _graph.getEdgeMap().entrySet()) {
String router = entry.getKey();
List<GraphEdge> edges = entry.getValue();
for (GraphEdge ge : edges) {
String peer = ge.getPeer();
if (peer != null) {
Integer j = _abstractGroups.getHandle(peer);
Set<String> existing = neighborByAbstractId.get(router, j);
if (existing != null) {
existing.add(peer);
} else {
Set<String> neighbors = new HashSet<>();
neighbors.add(peer);
neighborByAbstractId.put(router, j, neighbors);
}
}
}
}
return neighborByAbstractId;
}
use of org.batfish.symbolic.GraphEdge in project batfish by batfish.
the class BatfishCompressor method applyFilters.
/**
* Update RoutingPolicies to filter traffic according to filtersByRouter. This mutates the
* _graph's configurations.
*
* @param filtersByRouter Filters for each router/graph edge.
* @return A new network with the updated configs.
*/
private Map<String, Configuration> applyFilters(Table2<String, GraphEdge, EquivalenceClassFilter> filtersByRouter) {
Map<String, Configuration> newConfigs = new HashMap<>();
for (Entry<String, Configuration> entry : _graph.getConfigurations().entrySet()) {
String router = entry.getKey();
Map<GraphEdge, EquivalenceClassFilter> filters = filtersByRouter.get(router);
if (filters != null) {
Configuration config = entry.getValue();
// Include this config in the compressed network.
newConfigs.put(router, config);
// Mutate the config by adding import/export filters
for (GraphEdge ge : _graph.getEdgeMap().get(router)) {
EquivalenceClassFilter tup = filters.get(ge);
RoutingPolicy ipol = _graph.findImportRoutingPolicy(router, Protocol.BGP, ge);
if (ipol != null) {
RoutingPolicy newIpol = new RoutingPolicy(ipol.getName(), config);
newIpol.setStatements(applyFilters(ipol.getStatements(), tup));
config.getRoutingPolicies().put(newIpol.getName(), newIpol);
}
RoutingPolicy epol = _graph.findExportRoutingPolicy(router, Protocol.BGP, ge);
if (epol != null) {
RoutingPolicy newEpol = new RoutingPolicy(epol.getName(), config);
newEpol.setStatements(applyFilters(epol.getStatements(), tup));
config.getRoutingPolicies().put(newEpol.getName(), newEpol);
}
}
}
}
return newConfigs;
}
Aggregations