Esempio n. 1
0
    def generate_ecmp_smt(self, paths):
        src, dst = paths[0][0], paths[0][-1]
        path_costs = [self._get_path_cost(path) for path in paths]
        path_names = [get_path_name(path) for path in paths]
        cuttoff = self.gen_paths
        count = 0
        path_key_req = tuple(paths[0])
        if path_key_req not in self.saved_path_gen:
            self.saved_path_gen[path_key_req] = self.generate_random_paths(
                src, dst, 0.6, self.random_gen)
        elif path_key_req not in self.counter_examples:
            return
        primary_name = path_names[0]
        primary_cost = path_costs[0]
        if not is_symbolic(primary_cost):
            var = z3.Const("%s_cost" % path_names[0], z3.IntSort())
            self.solver.add(var == primary_cost)
            primary_cost_var = var

        # Assert ECMP
        for p_index in range(1, len(paths)):
            path_name = path_names[p_index]
            track_name = '%s_ISEQUAL_%s' % (primary_name, path_name)
            if track_name in self._names_cache:
                continue
            else:
                self._names_cache.append(track_name)
            cost = path_costs[p_index]
            if is_symbolic(cost) or is_symbolic(primary_cost):
                self.solver.assert_and_track(primary_cost == cost, track_name)
            else:
                if cost != primary_cost:
                    self.solver.assert_and_track(primary_cost_var == cost,
                                                 track_name)

        for rand_path in self.saved_path_gen[path_key_req]:
            # Skip if we generated the same path as the requirement
            if rand_path in paths:
                continue
            if rand_path:
                rand_path_name = get_path_name(rand_path)
                rand_path_cost = self._get_path_cost(rand_path)
                track_name = '%s_ISLESS_%s' % (primary_name, rand_path_name)
                if track_name in self._names_cache:
                    continue
                else:
                    self._names_cache.append(track_name)
                if is_symbolic(rand_path_cost) or is_symbolic(primary_cost):
                    self.solver.assert_and_track(primary_cost < rand_path_cost,
                                                 track_name)
                else:
                    if not (primary_cost < rand_path_cost):
                        self.solver.assert_and_track(
                            primary_cost_var < rand_path_cost, track_name)
            count += 1
            if count > cuttoff:
                break
Esempio n. 2
0
    def generate_kconnected_smt(self, paths):
        src, dst = paths[0][0], paths[0][-1]
        path_costs = [self._get_path_cost(path) for path in paths]
        path_names = [get_path_name(path) for path in paths]
        cuttoff = self.gen_paths
        count = 0
        path_key_req = tuple(paths[0])
        if path_key_req not in self.saved_path_gen:
            self.saved_path_gen[path_key_req] = self.generate_random_paths(
                src, dst, 0.6, self.random_gen)
        elif path_key_req not in self.counter_examples:
            return
        path_costs_var = []
        for index, cost in enumerate(path_costs):
            if is_symbolic(cost):
                path_costs_var.append(cost)
                continue
            var = z3.Const("%s_cost" % path_names[index], z3.IntSort())
            self.solver.add(var == cost)
            path_costs_var.append(var)

        for rand_path in self.saved_path_gen[path_key_req]:
            # Skip if we generated the same path as the requirement
            if rand_path in paths:
                continue
            if rand_path:
                for index, path in enumerate(paths):
                    path_name = path_names[index]
                    path_cost = path_costs[index]
                    rand_path_name = get_path_name(rand_path)
                    rand_path_cost = self._get_path_cost(rand_path)
                    track_name = '%s_ISLESS_%s' % (path_name, rand_path_name)
                    if track_name in self._names_cache:
                        continue
                    else:
                        self._names_cache.append(track_name)
                    if is_symbolic(path_cost) or is_symbolic(rand_path_cost):
                        self.solver.assert_and_track(
                            path_cost < rand_path_cost, track_name)
                    else:
                        if not (path_cost < rand_path_cost):
                            path_cost_var = path_costs_var[index]
                            self.solver.assert_and_track(
                                path_cost_var < rand_path_cost, track_name)
            count += 1
            if count > cuttoff:
                break
Esempio n. 3
0
def load_graph_constrains(solver, graph):
    """Add constrains specific to the OSPF graph"""
    for src, dst in graph.edges():
        cost = graph[src][dst]['cost']
        if is_empty(cost):
            cost = None
        if is_symbolic(cost):
            solver.add(cost > 0)
Esempio n. 4
0
def get_output_configs(model, ospf_graph):
    """Returns list of (src, dst, cost)"""
    outputs = []
    for src, dst in ospf_graph.edges():
        cost = ospf_graph[src][dst]['cost']
        if is_symbolic(cost):
            cost = model.eval(cost).as_long()
            ospf_graph[src][dst]['cost'] = cost
        outputs.append((src, dst, cost))
    return outputs
Esempio n. 5
0
    def generate_path_smt(self, path):
        src, dst = path[0], path[-1]
        path_cost = self._get_path_cost(path)
        cuttoff = self.gen_paths
        count = 0
        path_key_req = tuple(path)
        if path_key_req not in self.saved_path_gen:
            self.saved_path_gen[path_key_req] = self.generate_random_paths(
                src, dst, 0.6, self.random_gen)
        elif path_key_req not in self.counter_examples:
            return
        path_name = get_path_name(path)

        if not is_symbolic(path_cost):
            var = z3.Const("%s_cost" % path_name, z3.IntSort())
            self.solver.add(var == path_cost)
            path_cost_var = var

        for rand_path in self.saved_path_gen[path_key_req]:
            # Skip if we generated the same path as the requirement
            if path == rand_path:
                continue
            if rand_path:
                rand_path_name = get_path_name(rand_path)
                rand_path_cost = self._get_path_cost(rand_path)
                track_name = '%s_ISLESS_%s' % (path_name, rand_path_name)
                if track_name in self._names_cache:
                    continue
                else:
                    self._names_cache.append(track_name)
                if is_symbolic(rand_path_cost) or is_symbolic(path_cost):
                    self.solver.assert_and_track(path_cost < rand_path_cost,
                                                 track_name)
                else:
                    if not (path_cost < rand_path_cost):
                        self.solver.assert_and_track(
                            path_cost_var < rand_path_cost, track_name)
            count += 1
            if count > cuttoff:
                break
Esempio n. 6
0
    def generate_path_order_smt(self, paths):
        src, dst = paths[0][0], paths[0][-1]
        path_costs = [self._get_path_cost(path) for path in paths]
        path_names = [get_path_name(path) for path in paths]
        cuttoff = self.gen_paths
        count = 0
        path_key_req = tuple(paths[0])
        if path_key_req not in self.saved_path_gen:
            self.saved_path_gen[path_key_req] = self.generate_random_paths(
                src, dst, 0.6, self.random_gen)
        elif path_key_req not in self.counter_examples:
            return

        path_costs_var = []
        for index, cost in enumerate(path_costs):
            if is_symbolic(cost):
                path_costs_var.append(cost)
                continue
            var = z3.Const("%s_cost" % path_names[index], z3.IntSort())
            self.solver.add(var == cost)
            path_costs_var.append(var)

        # Assert Ordering
        for p0, p1 in zip(range(len(paths))[0::1], range(len(paths))[1::1]):
            p0_name = get_path_name(paths[p0])
            p1_name = get_path_name(paths[p1])
            track_name = '%s_ORDER_%s' % (p0_name, p1_name)
            p0_cost = path_costs[p0]
            p1_cost = path_costs[p1]
            if is_symbolic(p0_cost) or is_symbolic(p1_cost):
                self.solver.assert_and_track(p0_cost < p1_cost, track_name)
            else:
                if not (p0_cost < p1_cost):
                    p0_var = z3.Const("%s_cost2" % p0_name, z3.IntSort())
                    self.solver.add(p0_var == p0_cost)
                    self.solver.assert_and_track(p0_var < p1_cost, track_name)

        for rand_path in self.saved_path_gen[path_key_req]:
            # Skip if we generated the same path as the requirement
            if rand_path in paths:
                continue
            if rand_path:
                for index in range(len(paths)):
                    rand_path_name = get_path_name(rand_path)
                    rand_path_cost = self._get_path_cost(rand_path)
                    path_cost = path_costs[index]
                    path_name = path_names[index]
                    track_name = '%s_ISLESS_%s' % (path_name, rand_path_name)
                    if track_name in self._names_cache:
                        continue
                    else:
                        self._names_cache.append(track_name)
                    if is_symbolic(path_cost) or is_symbolic(rand_path_cost):
                        self.solver.assert_and_track(
                            path_cost < rand_path_cost, track_name)
                    else:
                        path_cost_var = path_costs_var[index]
                        if not (path_cost < rand_path_cost):
                            self.solver.assert_and_track(
                                path_cost_var < rand_path_cost, track_name)
            count += 1
            if count > cuttoff:
                break