def check_blackholes(simulation): '''Do any switches: - send packets into a down link? - drop packets that are supposed to go out their in_port? This method double checks whether it's possible for any packets to fall into the blackhole in the first place. Slightly different than check_connectivity. blackholes imply no connectivity, but not vice versa. No connectivity could also be due to: - a loop - PacketIn-based reactive routing ''' # TODO(cs): just realized -- the C-version of Hassell might be configured to # *stop* as soon as it gets to an edge port. At least, this is the # behavior of the find_reachability function in python Hassell. So we'd # have to do an iterative computation: all switches that are one # hop away, then two hops, etc. Otherwise we wouldn't find blackholes in # the middle of the network. # For now, use a python method that explicitly # finds blackholes rather than inferring them from check_reachability # Warning! depends on python Hassell -- may be really slow! NTF = hsa_topo.generate_NTF(simulation.topology.live_switches) TTF = hsa_topo.generate_TTF(simulation.topology.live_links) blackholes = hsa.find_blackholes(NTF, TTF, simulation.topology.access_links) return blackholes
def python_check_connectivity(simulation): # Warning! depends on python Hassell -- may be really slow! NTF = hsa_topo.generate_NTF(simulation.topology.live_switches) TTF = hsa_topo.generate_TTF(simulation.topology.live_links) paths = hsa.find_reachability(NTF, TTF, simulation.topology.access_links) # Paths is: in_port -> [p_node1, p_node2] # Where p_node is a hash: # "hdr" -> foo # "port" -> foo # "visits" -> foo connected_pairs = set() for in_port, p_nodes in paths.iteritems(): for p_node in p_nodes: connected_pairs.add((in_port, p_node["port"])) all_pairs = InvariantChecker._get_all_pairs(simulation) remaining_pairs = all_pairs - connected_pairs partitioned_pairs = check_partitions(simulation.topology.switches, simulation.topology.live_links, simulation.topology.access_links) if len(partitioned_pairs) != 0: log.info("Partitioned pairs! %s" % str(partitioned_pairs)) remaining_pairs -= partitioned_pairs # TODO(cs): don't print results here if len(remaining_pairs) > 0: msg.fail("Not all %d pairs are connected! (%d missing)" % (len(all_pairs),len(remaining_pairs))) log.info("remaining_pairs: %s" % (str(remaining_pairs))) else: msg.success("Fully connected!") return list(remaining_pairs)
def compute_controller_omega(controller_snapshot, live_switches, live_links, edge_links): name_tf_pairs = hsa_topo.tf_pairs_from_snapshot( controller_snapshot, live_switches) # Frenetic doesn't store any link or host information. # No virtualization though, so we can assume the same TTF. TODO(cs): for now... TTF = hsa_topo.generate_TTF(live_links) return hsa.compute_omega(name_tf_pairs, TTF, edge_links)
def check_loops(simulation): # Always check liveness down_controllers = InvariantChecker.check_liveness(simulation) if down_controllers != []: return down_controllers # Warning! depends on python Hassell -- may be really slow! NTF = hsa_topo.generate_NTF(simulation.topology.live_switches) TTF = hsa_topo.generate_TTF(simulation.topology.live_links) loops = hsa.detect_loop(NTF, TTF, simulation.topology.access_links) return loops
def test_blackhole(self): switch1 = create_switch(1, 2) flow_mod = ofp_flow_mod(xid=124, priority=1, match=ofp_match(in_port=1, nw_src="1.2.3.4"), action=ofp_action_output(port=2)) switch1.table.process_flow_mod(flow_mod) switch2 = create_switch(2, 2) network_links = [Link(switch1, switch1.ports[2], switch2, switch2.ports[2]), Link(switch2, switch2.ports[2], switch1, switch1.ports[2])] NTF = hsa_topo.generate_NTF([switch1, switch2]) TTF = hsa_topo.generate_TTF(network_links) access_links = [MockAccessLink(switch1, switch1.ports[1]), MockAccessLink(switch2, switch2.ports[1])] blackholes = hsa.find_blackholes(NTF, TTF, access_links) self.assertEqual([(100002, [100001, 100002])], blackholes)
def check_loops(simulation): # Always check liveness if there is a single controllers # Dynamic imports to allow this method to be serialized import sts.headerspace.topology_loader.topology_loader as hsa_topo import sts.headerspace.headerspace.applications as hsa if len(simulation.controller_manager.controllers) == 1: down_controllers = InvariantChecker.check_liveness(simulation) if down_controllers != []: return down_controllers # Warning! depends on python Hassell -- may be really slow! NTF = hsa_topo.generate_NTF(simulation.topology.live_switches) TTF = hsa_topo.generate_TTF(simulation.topology.live_links) loops = hsa.detect_loop(NTF, TTF, simulation.topology.live_switches) return loops
def _get_transfer_functions(live_switches, live_links): name_tf_pairs = hsa_topo.generate_tf_pairs(live_switches) TTF = hsa_topo.generate_TTF(live_links) return (name_tf_pairs, TTF)
def compute_controller_omega(controller_snapshot, live_switches, live_links, edge_links): name_tf_pairs = hsa_topo.tf_pairs_from_snapshot(controller_snapshot, live_switches) # Frenetic doesn't store any link or host information. # No virtualization though, so we can assume the same TTF. TODO(cs): for now... TTF = hsa_topo.generate_TTF(live_links) return hsa.compute_omega(name_tf_pairs, TTF, edge_links)