def python_check_blackholes(simulation, check_liveness_first=True): '''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! import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa if check_liveness_first: simulation.controller_manager.check_controller_status() if simulation.controller_manager.all_controllers_down(): return simulation.controller_manager.cids 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) violations = [ str(b) for b in blackholes ] violations = list(set(violations)) return violations
def python_check_blackholes(simulation, check_liveness_first=True): '''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! import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa if check_liveness_first: simulation.controller_manager.check_controller_status() if simulation.controller_manager.all_controllers_down(): return simulation.controller_manager.cids 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) violations = [str(b) for b in blackholes] violations = list(set(violations)) return violations
def test_no_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) flow_mod = ofp_flow_mod(xid=124, priority=1, match=ofp_match(in_port=2, nw_src="1.2.3.4"), action=ofp_action_output(port=1)) switch2.table.process_flow_mod(flow_mod) 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([], blackholes)
def python_check_connectivity(simulation, check_liveness_first=True): # Warning! depends on python Hassell -- may be really slow! import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa if check_liveness_first: simulation.controller_manager.check_controller_status() if simulation.controller_manager.all_controllers_down(): return simulation.controller_manager.cids 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"])) unconnected_pairs = InvariantChecker._get_unconnected_pairs( simulation, connected_pairs) violations = [str(pair) for pair in unconnected_pairs] violations = list(set(violations)) return violations
def compute_controller_omega(controller_snapshot, live_switches, live_links, edge_links): import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa 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 python_check_loops(simulation): import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa # 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) violations = [str(l) for l in loops] violations = list(set(violations)) return violations
def compute_controller_omega(controller_snapshot, live_switches, live_links, edge_links): import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa 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 python_check_loops(simulation): import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa # 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) violations = [ str(l) for l in loops ] violations = list(set(violations)) return violations
def python_check_loops(simulation, check_liveness_first=True): import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa if check_liveness_first and simulation.controller_manager.all_controllers_down(): return simulation.controller_manager.cids # 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) violations = [ str(l) for l in loops ] violations = list(set(violations)) return violations
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])] switches = [switch1, switch2] NTF = hsa_topo.generate_NTF(switches) TTF = hsa_topo.generate_TTF(network_links) access_links = [ MockAccessLink(sw, sw.ports[1]) for sw in switches ] blackholes = hsa.find_blackholes(NTF, TTF, access_links) self.assertEqual([(200002, [100001, 100002])], [ s[1:] for s in blackholes])
def python_check_loops(simulation, check_liveness_first=True): import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa if check_liveness_first: simulation.controller_manager.check_controller_status() if simulation.controller_manager.all_controllers_down(): return simulation.controller_manager.cids # 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) violations = [str(l) for l in loops] violations = list(set(violations)) return violations
def test_no_blackhole_without_rules(self): ''' An ingress switch with no rule should not count as a blackhole ''' switch1 = create_switch(1, 2) 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]) ] switches = [switch1, switch2] NTF = hsa_topo.generate_NTF(switches) TTF = hsa_topo.generate_TTF(network_links) access_links = [MockAccessLink(sw, sw.ports[1]) for sw in switches] blackholes = hsa.find_blackholes(NTF, TTF, access_links) self.assertEqual(blackholes, [])
def test_no_blackhole_without_rules(self): """ An ingress switch with no rule should not count as a blackhole """ switch1 = create_switch(1, 2) 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]), ] switches = [switch1, switch2] NTF = hsa_topo.generate_NTF(switches) TTF = hsa_topo.generate_TTF(network_links) access_links = [MockAccessLink(sw, sw.ports[1]) for sw in switches] blackholes = hsa.find_blackholes(NTF, TTF, access_links) self.assertEqual(blackholes, [])
def test_no_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) flow_mod = ofp_flow_mod(xid=124, priority=1, match=ofp_match(in_port=2, nw_src="1.2.3.4"), action=ofp_action_output(port=1)) switch2.table.process_flow_mod(flow_mod) 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([], blackholes)
def _python_get_connected_pairs(simulation): import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa 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"])) return connected_pairs
def test_blackhole_with_no_action_rules(self): """ An ingress switch with an explicit drop rule should count as a blackhole """ switch1 = create_switch(1, 2) flow_mod = ofp_flow_mod( xid=124, priority=1, match=ofp_match(in_port=switch1.ports[1].port_no, nw_src="1.2.3.4") ) 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]), ] switches = [switch1, switch2] NTF = hsa_topo.generate_NTF(switches) TTF = hsa_topo.generate_TTF(network_links) access_links = [MockAccessLink(sw, sw.ports[1]) for sw in switches] blackholes = hsa.find_blackholes(NTF, TTF, access_links) self.assertNotEqual(blackholes, [])
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]) ] switches = [switch1, switch2] NTF = hsa_topo.generate_NTF(switches) TTF = hsa_topo.generate_TTF(network_links) access_links = [MockAccessLink(sw, sw.ports[1]) for sw in switches] blackholes = hsa.find_blackholes(NTF, TTF, access_links) self.assertEqual([(200002, [100001, 100002])], [s[1:] for s in blackholes])
def test_blackhole_with_no_action_rules(self): ''' An ingress switch with an explicit drop rule should count as a blackhole ''' switch1 = create_switch(1, 2) flow_mod = ofp_flow_mod(xid=124, priority=1, match=ofp_match( in_port=switch1.ports[1].port_no, nw_src="1.2.3.4")) 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]) ] switches = [switch1, switch2] NTF = hsa_topo.generate_NTF(switches) TTF = hsa_topo.generate_TTF(network_links) access_links = [MockAccessLink(sw, sw.ports[1]) for sw in switches] blackholes = hsa.find_blackholes(NTF, TTF, access_links) self.assertNotEqual(blackholes, [])
def python_check_connectivity(simulation, check_liveness_first=True): # Warning! depends on python Hassell -- may be really slow! import topology_loader.topology_loader as hsa_topo import headerspace.applications as hsa if check_liveness_first and simulation.controller_manager.all_controllers_down(): return simulation.controller_manager.cids 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"])) unconnected_pairs = InvariantChecker._get_unconnected_pairs(simulation, connected_pairs) violations = [ str(pair) for pair in unconnected_pairs ] violations = list(set(violations)) return violations
def test_python_loop(self): topo = self._create_loopy_network() NTF = hsa_topo.generate_NTF(topo.switches) TTF = hsa_topo.generate_TTF(topo.network_links) loops = hsa.detect_loop(NTF, TTF, topo.switches) self.assertTrue(loops != [])
def _get_transfer_functions(live_switches, live_links): import topology_loader.topology_loader as hsa_topo name_tf_pairs = hsa_topo.generate_tf_pairs(live_switches) TTF = hsa_topo.generate_TTF(live_links) return (name_tf_pairs, TTF)