def set_switch_options(self, dpid): """Update the switch settings based on kytos.conf options. Args: dpid (str): dpid used to identify a switch. """ switch = self.switches.get(dpid) if not switch: return vlan_pool = {} try: vlan_pool = json.loads(self.options.vlan_pool) if not vlan_pool: return except (TypeError, json.JSONDecodeError) as err: self.log.error("Invalid vlan_pool settings: %s", err) if vlan_pool.get(dpid): self.log.info(f"Loading vlan_pool configuration for dpid {dpid}") for intf_num, port_list in vlan_pool[dpid].items(): if not switch.interfaces.get((intf_num)): vlan_ids = set() for vlan_range in port_list: (vlan_begin, vlan_end) = (vlan_range[0:2]) for vlan_id in range(vlan_begin, vlan_end): vlan_ids.add(vlan_id) intf_num = int(intf_num) intf = Interface(name=intf_num, port_number=intf_num, switch=switch) intf.set_available_tags(vlan_ids) switch.update_interface(intf)
def get_uni_mocked(**kwargs): """Create an uni mocked. Args: interface_name(str): Interface name. Defaults to "eth1". interface_port(int): Interface pror. Defaults to 1. tag_type(int): Type of a tag. Defaults to 1. tag_value(int): Value of a tag. Defaults to 81 is_valid(bool): Value returned by is_valid method. Defaults to False. """ interface_name = kwargs.get("interface_name", "eth1") interface_port = kwargs.get("interface_port", 1) tag_type = kwargs.get("tag_type", 1) tag_value = kwargs.get("tag_value", 81) is_valid = kwargs.get("is_valid", False) switch = Mock(spec=Switch) switch.id = kwargs.get("switch_id", "custom_switch_id") switch.dpid = kwargs.get("switch_dpid", "custom_switch_dpid") interface = Interface(interface_name, interface_port, switch) tag = TAG(tag_type, tag_value) uni = Mock(spec=UNI, interface=interface, user_tag=tag) uni.is_valid.return_value = is_valid uni.as_dict.return_value = { "interface_id": f'switch_mock:{interface_port}', "tag": tag.as_dict() } return uni
def get_interface_mock(interface_name, port, *args, **kwargs): """Return a interface mock.""" switch = get_switch_mock switch.connection = Mock() switch.connection.protocol.version = 0x04 iface = Interface(interface_name, port, switch, *args, **kwargs) return iface
def addInterfaces(count, switch, interfaces): for x in range(1, count + 1): str1 = "{}:{}".format(switch.dpid, x) print("Creating Interface: ", str1) iFace = Interface(str1, x, switch) interfaces[str1] = iFace switch.update_interface(iFace)
def setUp(self): """Create UNI object.""" switch = MagicMock() switch.dpid = '00:00:00:00:00:00:00:01' interface = Interface('name', 1, switch) user_tag = TAG(1, 123) self.uni = UNI(interface, user_tag)
def test__eq__(self): """Test __eq__ method.""" user_tag = TAG(2, 456) interface = Interface('name', 2, MagicMock()) other = UNI(interface, user_tag) self.assertFalse(self.uni.__eq__(other))
def test_switch_vlan_pool_options(self): """Test switch with the example from kytos.conf.""" dpid = "00:00:00:00:00:00:00:01" vlan_pool_json = '{"00:00:00:00:00:00:00:01": ' \ + '{"1": [[1, 2], [5, 10]], "4": [[3, 4]]}}' self.controller.switches[dpid] = self.switch self.options.vlan_pool = vlan_pool_json self.controller.get_switch_or_create(dpid, self.switch.connection) port_id = 1 intf = self.controller.switches[dpid].interfaces[port_id] tag_values = [tag.value for tag in intf.available_tags] self.assertEqual(tag_values, [1, 5, 6, 7, 8, 9]) port_id = 4 intf = self.controller.switches[dpid].interfaces[port_id] tag_values = [tag.value for tag in intf.available_tags] self.assertEqual(tag_values, [3]) # this port number doesn't exist yet. port_7 = 7 intf = Interface("test", port_7, self.switch) # no attr filters, so should associate as it is self.controller.switches[dpid].update_interface(intf) intf_obj = self.controller.switches[dpid].interfaces[port_7] self.assertEqual(intf_obj, intf) # assert default vlan_pool range (1, 4096) tag_values = [tag.value for tag in intf_obj.available_tags] self.assertEqual(tag_values, list(range(1, 4096)))
def get_topology_with_metadata(): """Create a topology with metadata.""" switches = {} interfaces = {} links = {} links_to_interfaces, links_to_metadata, switches_to_interface_counts = topology_setting( ) for switch in switches_to_interface_counts: switches[switch] = Switch(switch) for key, value in switches_to_interface_counts.items(): switches[key].interfaces = {} for i in range(1, value + 1): str1 = "{}:{}".format(switches[key].dpid, i) interface = Interface(str1, i, switches[key]) switches[key].update_interface(interface) interfaces[interface.id] = interface i = 0 for interfaces_str in links_to_interfaces: interface_a = interfaces[interfaces_str[0]] interface_b = interfaces[interfaces_str[1]] links[str(i)] = Link(interface_a, interface_b) links[str(i)].metadata = links_to_metadata[i] i += 1 topology = MagicMock() topology.links = links topology.switches = switches return topology
def handle_port_desc(controller, switch, port_list): """Update interfaces on switch based on port_list information.""" for port in port_list: interface = switch.get_interface_by_port_no(port.port_no.value) if interface: interface.name = port.name.value interface.address = port.hw_addr.value interface.state = port.state.value interface.features = port.curr else: interface = Interface(name=port.name.value, address=port.hw_addr.value, port_number=port.port_no.value, switch=switch, state=port.state.value, features=port.curr) switch.update_interface(interface) port_event = KytosEvent(name='kytos/of_core.switch.port.created', content={ 'switch': switch.id, 'port': port.port_no.value, 'port_description': { 'alias': port.name.value, 'mac': port.hw_addr.value, 'state': port.state.value } }) controller.buffers.app.put(port_event)
def add_interfaces(count, switch, interfaces): """Add a new interface to the list of interfaces""" for i in range(1, count + 1): str1 = "{}:{}".format(switch.dpid, i) interface = Interface(str1, i, switch) interfaces[str1] = interface switch.update_interface(interface)
def test_update_or_create_interface_case1(self): """Test update_or_create_interface method.""" interface_1 = Interface(name='interface_2', port_number=2, switch=self.switch) self.switch.interfaces = {2: interface_1} self.switch.update_or_create_interface(2, name='new_interface_2') self.assertEqual(self.switch.interfaces[2].name, 'new_interface_2')
def get_link_mocked(**kwargs): """Return a link mocked. Args: link_dict: Python dict returned after call link.as_dict() """ switch_a = kwargs.get("switch_a", Switch("00:00:00:00:00:01")) switch_b = kwargs.get("switch_b", Switch("00:00:00:00:00:02")) endpoint_a = Interface( kwargs.get("endpoint_a_name", "eth0"), kwargs.get("endpoint_a_port", 1), switch_a, ) endpoint_b = Interface( kwargs.get("endpoint_b_name", "eth1"), kwargs.get("endpoint_b_port", 2), switch_b, ) link = Mock(spec=Link, endpoint_a=endpoint_a, endpoint_b=endpoint_b) link.endpoint_a.link = link link.endpoint_b.link = link link.as_dict.return_value = kwargs.get("link_dict", {"id": kwargs.get("link_id", 1)}) link.status = kwargs.get("status", EntityStatus.DOWN) metadata = kwargs.get("metadata", {}) def side_effect(key): """Mock Link get metadata.""" return Mock(value=metadata.get(key)) link.get_metadata = Mock(side_effect=side_effect) return link
def handle_features_reply(controller, event): """Handle OF v0x01 features_reply message events. This is the end of the Handshake workflow of the OpenFlow Protocol. Parameters: controller (Controller): Controller being used. event (KytosEvent): Event with features reply message. """ connection = event.source features_reply = event.content['message'] dpid = features_reply.datapath_id.value switch = controller.get_switch_or_create(dpid=dpid, connection=connection) for port in features_reply.ports: interface = switch.get_interface_by_port_no(port.port_no.value) if interface: interface.name = port.name.value interface.address = port.hw_addr.value interface.state = port.state.value interface.features = port.curr else: interface = Interface(name=port.name.value, address=port.hw_addr.value, port_number=port.port_no.value, switch=switch, state=port.state.value, features=port.curr) switch.update_interface(interface) port_event = KytosEvent(name='kytos/of_core.switch.port.created', content={ 'switch': switch.id, 'port': port.port_no.value, 'port_description': { 'alias': port.name.value, 'mac': port.hw_addr.value, 'state': port.state.value } }) controller.buffers.app.put(port_event) switch.update_features(features_reply) return switch
def handle_port_desc(controller, switch, port_list): """Update interfaces on switch based on port_list information.""" for port in port_list: interface = switch.get_interface_by_port_no(port.port_no.value) config = port.config if (port.supported == 0 and port.curr_speed.value == 0 and port.max_speed.value == 0): config = PortConfig.OFPPC_NO_FWD if interface: interface.name = port.name.value interface.address = port.hw_addr.value interface.state = port.state.value interface.features = port.curr interface.config = config interface.set_custom_speed(port.curr_speed.value) else: interface = Interface(name=port.name.value, address=port.hw_addr.value, port_number=port.port_no.value, switch=switch, state=port.state.value, features=port.curr, speed=port.curr_speed.value, config=config) switch.update_interface(interface) event_name = 'kytos/of_core.switch.interface.created' interface_event = KytosEvent(name=event_name, content={'interface': interface}) port_event = KytosEvent(name='kytos/of_core.switch.port.created', content={ 'switch': switch.id, 'port': port.port_no.value, 'port_description': { 'alias': port.name.value, 'mac': port.hw_addr.value, 'state': port.state.value } }) controller.buffers.app.put(port_event) controller.buffers.app.put(interface_event)
def update_port_status(self, port_status, source): """Dispatch 'port.*' events. Current events: created|deleted|link_up|link_down|modified Args: port_status: python openflow (pyof) PortStatus object. source: kytos.core.switch.Connection instance. Dispatch: `kytos/of_core.switch.port.[created|modified|deleted]`: { switch : <switch.id>, port: <port.port_no> port_description: {<description of the port>} } """ reason = port_status.reason.enum_ref(port_status.reason.value).name port = port_status.desc event_name = 'kytos/of_core.switch.interface.' if reason == 'OFPPR_ADD': status = 'created' interface = Interface(name=port.name.value, address=port.hw_addr.value, port_number=port.port_no.value, switch=source.switch, state=port.state.value, features=port.curr) source.switch.update_interface(interface) elif reason == 'OFPPR_MODIFY': status = 'modified' interface = Interface(name=port.name.value, address=port.hw_addr.value, port_number=port.port_no.value, switch=source.switch, state=port.state.value, features=port.curr) current_interface = source.switch.get_interface_by_port_no(port.port_no.value) source.switch.update_interface(interface) self._send_specific_port_mod(port, interface, current_interface) elif reason == 'OFPPR_DELETE': status = 'deleted' interface = source.switch.get_interface_by_port_no( port.port_no.value) source.switch.remove_interface(interface) event_name += status content = {'interface': interface} event = KytosEvent(name=event_name, content=content) self.controller.buffers.app.put(event) msg = 'The port %s from switch %s was %s.' log.debug(msg, port_status.desc.port_no, source.switch.id, status)
def _get_v0x04_iface(*args, **kwargs): """Create a v0x04 interface object with optional extra arguments.""" switch = Switch('dpid') switch.connection = Mock() switch.connection.protocol.version = 0x04 return Interface('name', 42, switch, *args, **kwargs)
def _uni_from_dict_side_effect(self, uni_dict): interface_id = uni_dict.get("interface_id") tag_dict = uni_dict.get("tag") interface = Interface(interface_id, "0", "switch") return UNI(interface, tag_dict)
def get_interface_mock(interface_name, port, *args, **kwargs): """Return a interface mock.""" switch = get_switch_mock(0x04) switch.connection = Mock() iface = Interface(interface_name, port, switch, *args, **kwargs) return iface