Search in sources :

Example 1 with GraphEdge

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;
}
Also used : IpLink(org.batfish.datamodel.IpLink) Configuration(org.batfish.datamodel.Configuration) HashMap(java.util.HashMap) BgpProcess(org.batfish.datamodel.BgpProcess) Ip(org.batfish.datamodel.Ip) Vrf(org.batfish.datamodel.Vrf) Prefix(org.batfish.datamodel.Prefix) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) TreeSet(java.util.TreeSet) OspfNeighbor(org.batfish.datamodel.OspfNeighbor) OspfProcess(org.batfish.datamodel.OspfProcess) TreeMap(java.util.TreeMap) GraphEdge(org.batfish.symbolic.GraphEdge) Interface(org.batfish.datamodel.Interface)

Example 2 with GraphEdge

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;
}
Also used : SortedSet(java.util.SortedSet) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Stack(java.util.Stack) GraphEdge(org.batfish.symbolic.GraphEdge) HashSet(java.util.HashSet)

Example 3 with GraphEdge

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);
            }
        }
    }
}
Also used : GraphEdge(org.batfish.symbolic.GraphEdge) Tuple(org.batfish.symbolic.utils.Tuple)

Example 4 with GraphEdge

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;
}
Also used : SortedSet(java.util.SortedSet) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Set(java.util.Set) Table2(org.batfish.symbolic.collections.Table2) ArrayList(java.util.ArrayList) List(java.util.List) GraphEdge(org.batfish.symbolic.GraphEdge) HashSet(java.util.HashSet)

Example 5 with GraphEdge

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;
}
Also used : Configuration(org.batfish.datamodel.Configuration) HashMap(java.util.HashMap) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) GraphEdge(org.batfish.symbolic.GraphEdge)

Aggregations

GraphEdge (org.batfish.symbolic.GraphEdge)47 BoolExpr (com.microsoft.z3.BoolExpr)23 HashMap (java.util.HashMap)19 ArrayList (java.util.ArrayList)16 List (java.util.List)16 Graph (org.batfish.symbolic.Graph)14 TreeSet (java.util.TreeSet)13 Prefix (org.batfish.datamodel.Prefix)12 ArithExpr (com.microsoft.z3.ArithExpr)10 Configuration (org.batfish.datamodel.Configuration)10 Protocol (org.batfish.symbolic.Protocol)10 HashSet (java.util.HashSet)8 Interface (org.batfish.datamodel.Interface)8 Context (com.microsoft.z3.Context)7 Map (java.util.Map)7 Ip (org.batfish.datamodel.Ip)7 IpAccessList (org.batfish.datamodel.IpAccessList)7 TreeMap (java.util.TreeMap)6 IpProtocol (org.batfish.datamodel.IpProtocol)6 BitVecExpr (com.microsoft.z3.BitVecExpr)5