def __add_logical_port(self, port_no, intf_id, oper_state): self.log.info('adding-logical-port', port_no=port_no) label = OpenoltUtils.port_name(port_no, Port.ETHERNET_NNI) cap = OFPPF_1GB_FD | OFPPF_FIBER curr_speed = OFPPF_1GB_FD max_speed = OFPPF_1GB_FD if oper_state == OperStatus.ACTIVE: of_oper_state = OFPPS_LIVE else: of_oper_state = OFPPS_LINK_DOWN ofp = ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple( OpenoltUtils.make_mac_from_port_no(port_no)), name=label, config=0, state=of_oper_state, curr=cap, advertised=cap, peer=cap, curr_speed=curr_speed, max_speed=max_speed) ofp_stats = ofp_port_stats(port_no=port_no) logical_port = LogicalPort( id=label, ofp_port=ofp, device_id=self.device.id, device_port_no=port_no, root_port=True, ofp_port_stats=ofp_stats) self.adapter_agent.add_logical_port(self.logical_device_id, logical_port)
def add_logical_port(self, port_no): self.log.info('adding-logical-port', port_no=port_no) label = self.port_name(port_no, Port.ETHERNET_NNI) cap = OFPPF_1GB_FD | OFPPF_FIBER curr_speed = OFPPF_1GB_FD max_speed = OFPPF_1GB_FD ofp = ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % port_no), name=label, config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=curr_speed, max_speed=max_speed) logical_port = LogicalPort(id=label, ofp_port=ofp, device_id=self.device_id, device_port_no=port_no, root_port=True) self.adapter_agent.add_logical_port(self.logical_device_id, logical_port)
def get_logical_port(self): """ Get the VOLTHA logical port for this port :return: VOLTHA logical port or None if not supported """ if self._logical_port is None: openflow_port = ofp_port(port_no=self._port_no, hw_addr=mac_str_to_tuple( self._mac_address), name=self._logical_port_name, config=0, state=self._ofp_state, curr=self._ofp_capabilities, advertised=self._ofp_capabilities, peer=self._ofp_capabilities, curr_speed=self._current_speed, max_speed=self._max_speed) self._logical_port = LogicalPort( id=self._logical_port_name, ofp_port=openflow_port, device_id=self._parent.device_id, device_port_no=self._device_port_no, root_port=True) return self._logical_port
def add_logical_port(self, openflow_port_no, subscriber_vlan=None, capabilities=OFPPF_10GB_FD | OFPPF_FIBER, speed=OFPPF_10GB_FD): self.log.debug('function-entry') if self._logical_port_number is not None: # delete old logical port if it exists try: port = self._handler.adapter_agent.get_logical_port(self._handler.logical_device_id, self.port_id_name()) self._handler.adapter_agent.delete_logical_port(self._handler.logical_device_id, port) except Exception as e: # assume this exception was because logical port does not already exist pass self._logical_port_number = None port_no = openflow_port_no or self._ofp_port_no vlan = subscriber_vlan or self._subscriber_vlan if self._logical_port_number is None and port_no is not None: self._logical_port_number = port_no self._subscriber_vlan = vlan device = self._handler.adapter_agent.get_device(self._handler.device_id) if vlan is not None and device.vlan != vlan: device.vlan = vlan self._handler.adapter_agent.update_device(device) # leave the ports down until omci mib download has finished. otherwise flows push before time openflow_port = ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple('08:00:%02x:%02x:%02x:%02x' % ((device.parent_port_no >> 8 & 0xff), device.parent_port_no & 0xff, (port_no >> 8) & 0xff, port_no & 0xff)), name=device.serial_number, config=0, state=OFPPS_LINK_DOWN, curr=capabilities, advertised=capabilities, peer=capabilities, curr_speed=speed, max_speed=speed ) self._handler.adapter_agent.add_logical_port(self._handler.logical_device_id, LogicalPort( id=self.port_id_name(), ofp_port=openflow_port, device_id=device.id, device_port_no=self._port_number)) self.log.debug('logical-port', openflow_port=openflow_port)
def reenable(self): self.log.info('re-enabling', device_id=self.device_id) # Get the latest device reference device = self.adapter_agent.get_device(self.device_id) # First we verify that we got parent reference and proxy info assert self.uni_port assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # Re-register for proxied messages right away self.proxy_address = device.proxy_address self.adapter_agent.register_for_proxied_messages(device.proxy_address) # Re-enable the ports on that device self.adapter_agent.enable_all_ports(self.device_id) # Add the pon port reference to the parent self.adapter_agent.add_port_reference_to_parent(device.id, self.pon_port) # Update the connect status to REACHABLE device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # re-add uni port to logical device parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id port_no = device.proxy_address.channel_id cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port(logical_device_id, LogicalPort( id='uni-{}'.format(port_no), ofp_port=ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % port_no), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD ), device_id=device.id, device_port_no=self.uni_port.port_no )) device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) self.log.info('re-enabled', device_id=device.id)
def add_logical_port(self, openflow_port_no, subscriber_vlan=None, capabilities=OFPPF_10GB_FD | OFPPF_FIBER, speed=OFPPF_10GB_FD): if self._logical_port_number is not None: # delete old logical port if it exists try: port = self.adapter_agent.get_logical_port( self._handler.logical_device_id, self.port_id_name()) self.adapter_agent.delete_logical_port( self._handler.logical_device_id, port) except Exception as e: # assume this exception was because logical port does not already exist pass self._logical_port_number = None # Use vENET provisioned values if none supplied port_no = openflow_port_no or self._ofp_port_no vlan = subscriber_vlan or self._subscriber_vlan if self._logical_port_number is None and port_no is not None: self._logical_port_number = port_no self._subscriber_vlan = vlan device = self._handler.adapter_agent.get_device( self._handler.device_id) if vlan is not None and device.vlan != vlan: device.vlan = vlan self._handler.adapter_agent.update_device(device) openflow_port = ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple( '08:00:%02x:%02x:%02x:%02x' % ((device.parent_port_no >> 8 & 0xff), device.parent_port_no & 0xff, (port_no >> 8) & 0xff, port_no & 0xff)), name=self.port_id_name(), config=0, state=OFPPS_LIVE, curr=capabilities, advertised=capabilities, peer=capabilities, curr_speed=speed, max_speed=speed) self._handler.adapter_agent.add_logical_port( self._handler.logical_device_id, LogicalPort(id=self.port_id_name(), ofp_port=openflow_port, device_id=device.id, device_port_no=self._port_number))
def add_port(self, port): self.adapter_agent.add_port(self.device.id, port) cap = OFPPF_10GB_FD | OFPPF_FIBER logical_port = LogicalPort( id='uni', ofp_port=ofp_port(port_no=port.port_no, hw_addr=mac_str_to_tuple( self.device.mac_address), name='{}-{}'.format(port.label, port.port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_10GB_FD, max_speed=OFPPF_10GB_FD)) self.adapter_agent.add_logical_port(self.logical_device.id, logical_port)
def add_logical_port(self, openflow_port_no, subscriber_vlan=None, capabilities=OFPPF_10GB_FD | OFPPF_FIBER, speed=OFPPF_10GB_FD): # Use vENET provisioned values if none supplied port_no = openflow_port_no or self._ofp_port_no vlan = subscriber_vlan or self._subscriber_vlan if self._logical_port_number is None and port_no is not None: self._logical_port_number = port_no self._subscriber_vlan = vlan device = self._handler.adapter_agent.get_device( self._handler.device_id) if vlan is not None and device.vlan != vlan: device.vlan = vlan self._handler.adapter_agent.update_device(device) openflow_port = ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple( '08:00:%02x:%02x:%02x:%02x' % ((device.parent_port_no >> 8 & 0xff), device.parent_port_no & 0xff, (port_no >> 8) & 0xff, port_no & 0xff)), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=capabilities, advertised=capabilities, peer=capabilities, curr_speed=speed, max_speed=speed) self._handler.adapter_agent.add_logical_port( self._handler.logical_device_id, LogicalPort(id='uni-{}'.format(port_no), ofp_port=openflow_port, device_id=device.id, device_port_no=self._port_number))
def add_logical_port(self, openflow_port_no, control_vlan=None, capabilities=OFPPF_10GB_FD | OFPPF_FIBER, speed=OFPPF_10GB_FD): if self._logical_port_number is None: self._logical_port_number = openflow_port_no self._control_vlan = control_vlan device = self._handler.adapter_agent.get_device( self._handler.device_id) if control_vlan is not None and device.vlan != control_vlan: device.vlan = control_vlan self._handler.adapter_agent.update_device(device) openflow_port = ofp_port( port_no=openflow_port_no, hw_addr=mac_str_to_tuple( '08:00:%02x:%02x:%02x:%02x' % ((device.parent_port_no >> 8 & 0xff), device.parent_port_no & 0xff, (openflow_port_no >> 8) & 0xff, openflow_port_no & 0xff)), name='uni-{}'.format(openflow_port_no), config=0, state=OFPPS_LIVE, curr=capabilities, advertised=capabilities, peer=capabilities, curr_speed=speed, max_speed=speed) self._handler.adapter_agent.add_logical_port( self._handler.logical_device_id, LogicalPort(id='uni-{}'.format(openflow_port), ofp_port=openflow_port, device_id=device.id, device_port_no=self._port_number))
def add_logical_upstream_port(self, port): cap = OFPPF_10GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port(self.logical_device.id, LogicalPort( id='nni', ofp_port=ofp_port( port_no=port, # hw_addr=mac_str_to_tuple(self.device.serial_number)[2:8], hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % port), name='nni', config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_10GB_FD, max_speed=OFPPF_10GB_FD ), device_id=self.device.id, device_port_no=port, root_port=True ))
def _onu_device_activation(self, device): # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # TODO: For now, pretend that we were able to contact the device and obtain # additional information about it. Should add real message. device.vendor = 'Tibit Communications, Inc.' device.model = '10G GPON ONU' device.hardware_version = 'fa161020' device.firmware_version = '16.12.02' device.software_version = '1.0' device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # then shortly after we create some ports for the device uni_port = Port(port_no=2, label='UNI facing Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) self.adapter_agent.add_port( device.id, Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ])) # TODO adding vports to the logical device shall be done by agent? # then we create the logical device port that corresponds to the UNI # port of the device # obtain logical device id parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id # we are going to use the proxy_address.channel_id as unique number # and name for the virtual ports, as this is guaranteed to be unique # in the context of the OLT port, so it is also unique in the context # of the logical device port_no = device.proxy_address.channel_id cap = OFPPF_10GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id=str(port_no), ofp_port=ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple( device.mac_address), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_10GB_FD, max_speed=OFPPF_10GB_FD), device_id=device.id, device_port_no=uni_port.port_no)) # simulate a proxied message sending and receving a reply reply = yield self._message_exchange(device) # and finally update to "ACTIVE" device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) self.start_kpi_collection(device.id)
def _simulate_device_activation(self, device): # first we pretend that we were able to contact the device and obtain # additional information about it device.root = True device.vendor = 'simulated' device.model = 'n/a' device.hardware_version = 'n/a' device.firmware_version = 'n/a' device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE image1 = Image(name="olt_candidate1", version="1.0", hash="", install_datetime=datetime.datetime.utcnow().isoformat(), is_active=True, is_committed=True, is_valid=True) image2 = Image(name="olt_candidate2", version="1.0", hash="", install_datetime=datetime.datetime.utcnow().isoformat(), is_active=False, is_committed=False, is_valid=True) device.images.image.extend([image1, image2]) self.adapter_agent.update_device(device) # Now set the initial PM configuration for this device self.pm_metrics = AdapterPmMetrics(device) pm_config = self.pm_metrics.make_proto() log.info("initial-pm-config", pm_config=pm_config) self.adapter_agent.update_device_pm_config(pm_config, init=True) # then shortly after we create some ports for the device yield asleep(0.05) nni_port = Port(port_no=2, label='NNI facing Ethernet port', type=Port.ETHERNET_NNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, nni_port) self.adapter_agent.add_port( device.id, Port(port_no=1, label='PON port', type=Port.PON_OLT, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE)) # then shortly after we create the logical device with one port # that will correspond to the NNI port yield asleep(0.05) logical_device_id = uuid4().hex[:12] ld = LogicalDevice( # not setting id and datapth_id will let the adapter agent pick id desc=ofp_desc(mfr_desc='cord porject', hw_desc='simualted pon', sw_desc='simualted pon', serial_num=uuid4().hex, dp_desc='n/a'), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS)), root_device_id=device.id) ld_initialized = self.adapter_agent.create_logical_device(ld) cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( ld_initialized.id, LogicalPort(id='nni', ofp_port=ofp_port(port_no=129, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % 129), name='nni', config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=nni_port.port_no, root_port=True)) # and finally update to active device = self.adapter_agent.get_device(device.id) device.parent_id = ld_initialized.id device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) reactor.callLater(0.1, self._simulate_detection_of_onus, device.id) self.start_kpi_collection(device.id) self.start_alarm_simulation(device.id)
def _tmp_populate_stuff(self): """ pretend that we discovered some devices and create: - devices - device ports for each - logical device - logical device ports """ olt = Device(id='simulated_olt_1', type='simulated_olt', root=True, vendor='simulated', model='n/a', hardware_version='n/a', firmware_version='n/a', software_version='1.0', serial_number=uuid4().hex, adapter=self.name, oper_status=OperStatus.DISCOVERED) self.adapter_agent.add_device(olt) self.adapter_agent.add_port( olt.id, Port(port_no=1, label='pon', type=Port.PON_OLT)) self.adapter_agent.add_port( olt.id, Port(port_no=2, label='eth', type=Port.ETHERNET_NNI)) onu1 = Device(id='simulated_onu_1', type='simulated_onu', root=False, parent_id=olt.id, parent_port_no=1, vendor='simulated', model='n/a', hardware_version='n/a', firmware_version='n/a', software_version='1.0', serial_number=uuid4().hex, adapter='simulated_onu', oper_status=OperStatus.DISCOVERED, vlan=101) self.adapter_agent.add_device(onu1) self.adapter_agent.add_port( onu1.id, Port(port_no=2, label='eth', type=Port.ETHERNET_UNI)) self.adapter_agent.add_port( onu1.id, Port(port_no=1, label='pon', type=Port.PON_ONU, peers=[Port.PeerPort(device_id=olt.id, port_no=1)])) onu2 = Device(id='simulated_onu_2', type='simulated_onu', root=False, parent_id=olt.id, parent_port_no=1, vendor='simulated', model='n/a', hardware_version='n/a', firmware_version='n/a', software_version='1.0', serial_number=uuid4().hex, adapter='simulated_onu', oper_status=OperStatus.DISCOVERED, vlan=102) self.adapter_agent.add_device(onu2) self.adapter_agent.add_port( onu2.id, Port(port_no=2, label='eth', type=Port.ETHERNET_UNI)) self.adapter_agent.add_port( onu2.id, Port(port_no=1, label='pon', type=Port.PON_ONU, peers=[Port.PeerPort(device_id=olt.id, port_no=1)])) ld = LogicalDevice( id='simulated1', datapath_id=1, desc=ofp_desc(mfr_desc='cord project', hw_desc='simualted pon', sw_desc='simualted pon', serial_num=uuid4().hex, dp_desc='n/a'), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS)), root_device_id=olt.id) self.adapter_agent.create_logical_device(ld) cap = OFPPF_1GB_FD | OFPPF_FIBER for port_no, name, device_id, device_port_no, root_port in [ (1, 'onu1', onu1.id, 2, False), (2, 'onu2', onu2.id, 2, False), (129, 'olt1', olt.id, 2, True) ]: port = LogicalPort(id=name, ofp_port=ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % port_no), name=name, config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device_id, device_port_no=device_port_no, root_port=root_port) self.adapter_agent.add_logical_port(ld.id, port) olt.parent_id = ld.id self.adapter_agent.update_device(olt)
def _simulate_device_activation(self, device): # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # we pretend that we were able to contact the device and obtain # additional information about it device.vendor = 'simulated onu adapter' device.model = 'n/a' device.hardware_version = 'n/a' device.firmware_version = 'n/a' device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE image1 = Image(name="onu_candidate1", version="1.0", hash="1234567892", install_datetime=datetime.datetime.utcnow().isoformat(), is_active=True, is_committed=True, is_valid=True) image2 = Image(name="onu_candidate2", version="1.0", hash="1234567893", install_datetime=datetime.datetime.utcnow().isoformat(), is_active=False, is_committed=False, is_valid=True) device.images.image.extend([image1, image2]) self.adapter_agent.update_device(device) # then shortly after we create some ports for the device yield asleep(0.05) uni_port = Port(port_no=2, label='UNI facing Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) self.adapter_agent.add_port( device.id, Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ])) # TODO adding vports to the logical device shall be done by agent? # then we create the logical device port that corresponds to the UNI # port of the device yield asleep(0.05) # obtain logical device id parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id # we are going to use the proxy_address.channel_id as unique number # and name for the virtual ports, as this is guaranteed to be unique # in the context of the OLT port, so it is also unique in the context # of the logical device port_no = device.proxy_address.channel_id cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id=str(port_no), ofp_port=ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % port_no), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=uni_port.port_no)) # simulate a proxied message sending and receving a reply reply = yield self._simulate_message_exchange(device) # and finally update to "ACTIVE" device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)
def reenable(self): self.log.info('re-enabling', device_id=self.device_id) # Get the latest device reference device = self.adapter_agent.get_device(self.device_id) # Update the connect status to REACHABLE device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # Set all ports to enabled self.adapter_agent.enable_all_ports(self.device_id) ld = LogicalDevice( # not setting id and datapth_id will let the adapter agent pick id desc=ofp_desc( mfr_desc='cord porject', hw_desc='simulated pon', sw_desc='simulated pon', serial_num=uuid4().hex, dp_desc='n/a' ), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS ) ), root_device_id=device.id ) ld_initialized = self.adapter_agent.create_logical_device(ld) cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port(ld_initialized.id, LogicalPort( id='nni', ofp_port=ofp_port( port_no=self.ofp_port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % self.ofp_port_no), name='nni', config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD ), device_id=device.id, device_port_no=self.nni_port.port_no, root_port=True )) device = self.adapter_agent.get_device(device.id) device.parent_id = ld_initialized.id device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) self.logical_device_id = ld_initialized.id # Reenable all child devices self.adapter_agent.update_child_devices_state(device.id, admin_state=AdminState.ENABLED) # finally, open the frameio port to receive in-band packet_in messages self.log.info('registering-frameio') self.io_port = registry('frameio').open_port( self.interface, self.rcv_io, is_inband_frame) self.log.info('registered-frameio') self.log.info('re-enabled', device_id=device.id)
def activate(self, device): self.log.info('activating') # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # register for proxied messages right away self.proxy_address = device.proxy_address self.adapter_agent.register_for_proxied_messages(device.proxy_address) # populate device info device.root = False device.vendor = 'ponsim' device.model = 'n/a' device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # Now set the initial PM configuration for this device self.pm_metrics = AdapterPmMetrics(device) pm_config = self.pm_metrics.make_proto() log.info("initial-pm-config", pm_config=pm_config) self.adapter_agent.update_device_pm_config(pm_config, init=True) # register physical ports self.uni_port = Port(port_no=2, label='UNI facing Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.pon_port = Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ]) self.adapter_agent.add_port(device.id, self.uni_port) self.adapter_agent.add_port(device.id, self.pon_port) # add uni port to logical device parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id port_no = device.proxy_address.channel_id cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id='uni-{}'.format(port_no), ofp_port=ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % port_no), name=device.serial_number, config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=self.uni_port.port_no)) device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) # Start collecting stats from the device after a brief pause self.start_kpi_collection(device.id)
def _launch_device_activation(self, device): try: log.debug('launch_dev_activation') # prepare receive queue self.incoming_queues[device.mac_address] = DeferredQueue(size=100) # add mac_address to device_ids table olt_mac = device.mac_address self.device_ids[olt_mac] = device.id # send out ping to OLT device ping_frame = self._make_ping_frame(mac_address=olt_mac) self.io_port.send(ping_frame) # wait till we receive a response ## TODO add timeout mechanism so we can signal if we cannot reach ##device while True: response = yield self.incoming_queues[olt_mac].get() # verify response and if not the expected response if 1: # TODO check if it is really what we expect, and wait if not break except Exception as e: log.exception('launch device failed', e=e) # if we got response, we can fill out the device info, mark the device # reachable jdev = json.loads(response.payload.payload.body.load) device.root = True device.vendor = 'Tibit Communications, Inc.' device.model = jdev.get('results', {}).get('device', 'DEVICE_UNKNOWN') device.hardware_version = jdev['results']['datecode'] device.firmware_version = jdev['results']['firmware'] device.software_version = jdev['results']['modelversion'] device.serial_number = jdev['results']['manufacturer'] device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # then shortly after we create some ports for the device log.info('create-port') nni_port = Port( port_no=2, label='NNI facing Ethernet port', type=Port.ETHERNET_NNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE ) self.adapter_agent.add_port(device.id, nni_port) self.adapter_agent.add_port(device.id, Port( port_no=1, label='PON port', type=Port.PON_OLT, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE )) log.info('create-logical-device') # then shortly after we create the logical device with one port # that will correspond to the NNI port ld = LogicalDevice( desc=ofp_desc( mfr_desc=device.vendor, hw_desc=jdev['results']['device'], sw_desc=jdev['results']['firmware'], serial_num=uuid4().hex, dp_desc='n/a' ), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS ) ), root_device_id=device.id ) ld_initialized = self.adapter_agent.create_logical_device(ld) cap = OFPPF_10GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port(ld_initialized.id, LogicalPort( id='nni', ofp_port=ofp_port( port_no=0, hw_addr=mac_str_to_tuple(device.mac_address), name='nni', config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_10GB_FD, max_speed=OFPPF_10GB_FD ), device_id=device.id, device_port_no=nni_port.port_no, root_port=True )) # and finally update to active device = self.adapter_agent.get_device(device.id) device.parent_id = ld_initialized.id device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) # Just transitioned to ACTIVE, wait a tenth of second # before checking for ONUs reactor.callLater(0.1, self._detect_onus, device)
def activate(self, device): self.log.info('activating') if not device.host_and_port: device.oper_status = OperStatus.FAILED device.reason = 'No host_and_port field provided' self.adapter_agent.update_device(device) return stub = ponsim_pb2.PonSimStub(self.get_channel()) info = stub.GetDeviceInfo(Empty()) log.info('got-info', info=info) device.root = True device.vendor = 'ponsim' device.model = 'n/a' device.serial_number = device.host_and_port device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # Now set the initial PM configuration for this device self.pm_metrics = AdapterPmMetrics(device) pm_config = self.pm_metrics.make_proto() log.info("initial-pm-config", pm_config=pm_config) self.adapter_agent.update_device_pm_config(pm_config, init=True) # Setup alarm handler self.alarms = AdapterAlarms(self.adapter, device) nni_port = Port( port_no=2, label='NNI facing Ethernet port', type=Port.ETHERNET_NNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE ) self.nni_port = nni_port self.adapter_agent.add_port(device.id, nni_port) self.adapter_agent.add_port(device.id, Port( port_no=1, label='PON port', type=Port.PON_OLT, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE )) ld = LogicalDevice( # not setting id and datapth_id will let the adapter agent pick id desc=ofp_desc( mfr_desc='cord porject', hw_desc='simualted pon', sw_desc='simualted pon', serial_num=uuid4().hex, dp_desc='n/a' ), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS ) ), root_device_id=device.id ) ld_initialized = self.adapter_agent.create_logical_device(ld) cap = OFPPF_1GB_FD | OFPPF_FIBER self.ofp_port_no = info.nni_port self.adapter_agent.add_logical_port(ld_initialized.id, LogicalPort( id='nni', ofp_port=ofp_port( port_no=info.nni_port, hw_addr=mac_str_to_tuple( '00:00:00:00:00:%02x' % info.nni_port), name='nni', config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD ), device_id=device.id, device_port_no=nni_port.port_no, root_port=True )) device = self.adapter_agent.get_device(device.id) device.parent_id = ld_initialized.id device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) self.logical_device_id = ld_initialized.id # register ONUS per uni port for port_no in info.uni_ports: vlan_id = port_no self.adapter_agent.child_device_detected( parent_device_id=device.id, parent_port_no=1, child_device_type='ponsim_onu', proxy_address=Device.ProxyAddress( device_id=device.id, channel_id=vlan_id ), vlan=vlan_id ) # finally, open the frameio port to receive in-band packet_in messages self.log.info('registering-frameio') self.io_port = registry('frameio').open_port( self.interface, self.rcv_io, is_inband_frame) self.log.info('registered-frameio') # Start collecting stats from the device after a brief pause self.start_kpi_collection(device.id)
def reenable(self): self.log.info('re-enabling', device_id=self.device_id) # Get the latest device reference device = self.adapter_agent.get_device(self.device_id) # Set the ofp_port_no and nni_port in case we bypassed the reconcile # process if the device was in DISABLED state on voltha restart if not self.ofp_port_no and not self.nni_port: stub = ponsim_pb2.PonSimStub(self.get_channel()) info = stub.GetDeviceInfo(Empty()) log.info('got-info', info=info) self.ofp_port_no = info.nni_port self.nni_port = self._get_nni_port() # Update the connect status to REACHABLE device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # Set all ports to enabled self.adapter_agent.enable_all_ports(self.device_id) ld = LogicalDevice( # not setting id and datapth_id will let the adapter agent pick id desc=ofp_desc(hw_desc='simulated pon', sw_desc='simulated pon', serial_num=uuid4().hex, dp_desc='n/a'), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS)), root_device_id=device.id) mac_address = "AA:BB:CC:DD:EE:FF" ld_initialized = self.adapter_agent.create_logical_device( ld, dpid=mac_address) cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( ld_initialized.id, LogicalPort(id='nni', ofp_port=ofp_port( port_no=self.ofp_port_no, hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % self.ofp_port_no), name='nni', config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=self.nni_port.port_no, root_port=True)) device = self.adapter_agent.get_device(device.id) device.parent_id = ld_initialized.id device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) self.logical_device_id = ld_initialized.id # Reenable all child devices self.adapter_agent.update_child_devices_state( device.id, admin_state=AdminState.ENABLED) if self.ponsim_comm == 'grpc': # establish frame grpc-stream reactor.callInThread(self.rcv_grpc) else: # finally, open the frameio port to receive in-band packet_in messages self.io_port = registry('frameio').open_port( self.interface, self.rcv_io, is_inband_frame) self.start_kpi_collection(device.id) self.log.info('re-enabled', device_id=device.id)
def activate(self, device): self.log.info('activating') # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id # register for proxied messages right away self.proxy_address = device.proxy_address self.adapter_agent.register_for_proxied_messages(device.proxy_address) # populate device info device.root = True device.vendor = 'Broadcom' device.model = 'n/a' device.hardware_version = 'to be filled' device.firmware_version = 'to be filled' device.software_version = 'to be filled' device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # register physical ports uni_port = Port(port_no=2, label='UNI facing Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) self.adapter_agent.add_port( device.id, Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ])) # add uni port to logical device parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id port_no = device.proxy_address.channel_id cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id='uni-{}'.format(port_no), ofp_port=ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple( '00:00:00:00:%02x:%02x' % ((port_no >> 8) & 0xff, port_no & 0xff)), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=uni_port.port_no)) reactor.callLater(10, self.message_exchange) device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)
def activate(self, device): self.log.info('activating') if not device.ipv4_address: device.oper_status = OperStatus.FAILED device.reason = 'No ipv4_address field provided' self.adapter_agent.update_device(device) return self.log.info('initiating-connection-to-olt', device_id=device.id, ipv4=device.ipv4_address, port=self.pbc_port) reactor.connectTCP(device.ipv4_address, self.pbc_port, self.pbc_factory) try: self.channel = yield self.pbc_factory.getRootObject() self.log.info('connected-to-olt', device_id=device.id, ipv4=device.ipv4_address, port=self.pbc_port) except Exception as e: self.log.info('get-channel-exception', exc=str(e)) yield self.send_set_remote() yield self.send_connect_olt(0) yield self.send_activate_olt(0) device.root = True device.vendor = 'Broadcom' device.model = 'bcm68620' device.serial_number = device.ipv4_address device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) nni_port = Port(port_no=2, label='NNI facing Ethernet port', type=Port.ETHERNET_NNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, nni_port) self.adapter_agent.add_port( device.id, Port(port_no=1, label='PON port', type=Port.PON_OLT, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE)) ld = LogicalDevice( # not setting id and datapth_id will let the adapter agent pick id desc=ofp_desc(mfr_desc='cord project', hw_desc='n/a', sw_desc='logical device for Maple-based PON', serial_num=uuid4().hex, dp_desc='n/a'), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS)), root_device_id=device.id) ld_initialized = self.adapter_agent.create_logical_device(ld) cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( ld_initialized.id, LogicalPort( id='nni', ofp_port=ofp_port( port_no=0, # is 0 OK? hw_addr=mac_str_to_tuple('00:00:00:00:00:%02x' % 129), name='nni', config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=nni_port.port_no, root_port=True)) device = self.adapter_agent.get_device(device.id) device.parent_id = ld_initialized.id device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) self.logical_device_id = ld_initialized.id # register ONUS per uni port until done asynchronously for onu_no in [1]: vlan_id = self.get_vlan_from_onu(onu_no) yield self.send_create_onu(0, onu_no, '4252434d', '12345678') yield self.send_configure_alloc_id(0, onu_no, vlan_id) yield self.send_configure_unicast_gem(0, onu_no, vlan_id) yield self.send_configure_multicast_gem(0, onu_no, 4000) yield self.send_activate_onu(0, onu_no) self.adapter_agent.child_device_detected( parent_device_id=device.id, parent_port_no=1, child_device_type='broadcom_onu', proxy_address=Device.ProxyAddress(device_id=device.id, channel_id=vlan_id), vlan=vlan_id) # finally, open the frameio port to receive in-band packet_in messages self.log.info('registering-frameio') self.io_port = registry('frameio').open_port(self.interface, self.rcv_io, is_inband_frame)
def activate(self, device): self.log.info('activating') # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id # register for proxied messages right away self.proxy_address = device.proxy_address self.adapter_agent.register_for_proxied_messages(device.proxy_address) # populate device info device.root = True device.vendor = 'Adtran Inc.' device.model = '10G GPON ONU' # TODO: get actual number device.hardware_version = 'NOT AVAILABLE' device.firmware_version = 'NOT AVAILABLE' # TODO: Support more versions as needed images = Image(version='NOT AVAILABLE') device.images.image.extend([images]) device.serial_number = uuid4().hex device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) # register physical ports nni_port = Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no)]) self.adapter_agent.add_port(device.id, nni_port) uni_port = Port(port_no=2, label='Ethernet port', type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) # add uni port to logical device parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id port_no = device.proxy_address.channel_id log.info('ONU OPENFLOW PORT WILL BE {}'.format(port_no)) cap = OFPPF_10GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port(logical_device_id, LogicalPort( id='uni-{}'.format(port_no), ofp_port=ofp_port( port_no=port_no, hw_addr=mac_str_to_tuple('08:00:%02x:%02x:%02x:%02x' % ((device.parent_port_no >> 8 & 0xff), device.parent_port_no & 0xff, (port_no >> 8) & 0xff, port_no & 0xff)), name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_10GB_FD, max_speed=OFPPF_10GB_FD ), device_id=device.id, device_port_no=uni_port.port_no )) # Begin ONU Activation sequence reactor.callLater(0, self.message_exchange) device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)
class TestFlowDecomposer(FlowHelpers, FlowDecomposer): def setUp(self): self.logical_device_id = 'pon' self._nni_logical_port_no = None # methods needed by FlowDecomposer; faking real lookups _devices = { 'olt': Device(id='olt', root=True, parent_id='logical_device', ports=[ Port(port_no=1, label='pon'), Port(port_no=2, label='nni'), ]), 'onu1': Device(id='onu1', parent_id='olt', ports=[ Port(port_no=1, label='pon'), Port(port_no=2, label='uni'), ]), 'onu2': Device(id='onu2', parent_id='olt', ports=[ Port(port_no=1, label='pon'), Port(port_no=2, label='uni'), ]), 'onu3': Device(id='onu3', parent_id='olt', ports=[ Port(port_no=1, label='pon'), Port(port_no=2, label='uni'), ]), 'onu4': Device(id='onu4', parent_id='olt', ports=[ Port(port_no=1, label='pon'), Port(port_no=2, label='uni'), ]), } _logical_ports = { 0: LogicalPort(id='0', device_id='olt', device_port_no=2), 1: LogicalPort(id='1', device_id='onu1', device_port_no=2), 2: LogicalPort(id='2', device_id='onu2', device_port_no=2), 3: LogicalPort(id='3', device_id='onu3', device_port_no=2), 4: LogicalPort(id='4', device_id='onu4', device_port_no=2), } def get_wildcard_input_ports(self, exclude_port=None): logical_ports = self._logical_ports.iterkeys() return [ port_no for port_no in logical_ports if port_no != exclude_port ] _routes = { # DOWNSTREAM ROUTES (0, 1): [ RouteHop(_devices['olt'], _devices['olt'].ports[1], _devices['olt'].ports[0]), RouteHop(_devices['onu1'], _devices['onu1'].ports[0], _devices['onu1'].ports[1]), ], (0, 2): [ RouteHop(_devices['olt'], _devices['olt'].ports[1], _devices['olt'].ports[0]), RouteHop(_devices['onu2'], _devices['onu2'].ports[0], _devices['onu2'].ports[1]), ], (0, 3): [ RouteHop(_devices['olt'], _devices['olt'].ports[1], _devices['olt'].ports[0]), RouteHop(_devices['onu3'], _devices['onu3'].ports[0], _devices['onu3'].ports[1]), ], (0, 4): [ RouteHop(_devices['olt'], _devices['olt'].ports[1], _devices['olt'].ports[0]), RouteHop(_devices['onu4'], _devices['onu4'].ports[0], _devices['onu4'].ports[1]), ], # UPSTREAM DATA PLANE (1, 0): [ RouteHop(_devices['onu1'], _devices['onu1'].ports[1], _devices['onu1'].ports[0]), RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]), ], (2, 0): [ RouteHop(_devices['onu2'], _devices['onu2'].ports[1], _devices['onu2'].ports[0]), RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]), ], (3, 0): [ RouteHop(_devices['onu3'], _devices['onu3'].ports[1], _devices['onu3'].ports[0]), RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]), ], (4, 0): [ RouteHop(_devices['onu4'], _devices['onu4'].ports[1], _devices['onu4'].ports[0]), RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]), ], # UPSTREAM NEXT TABLE BASED (1, None): [ RouteHop(_devices['onu1'], _devices['onu1'].ports[1], _devices['onu1'].ports[0]), RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]), ], (2, None): [ RouteHop(_devices['onu2'], _devices['onu2'].ports[1], _devices['onu2'].ports[0]), RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]), ], (3, None): [ RouteHop(_devices['onu3'], _devices['onu3'].ports[1], _devices['onu3'].ports[0]), RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]), ], (4, None): [ RouteHop(_devices['onu4'], _devices['onu4'].ports[1], _devices['onu4'].ports[0]), RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]), ], # DOWNSTREAM NEXT TABLE BASED (0, None): [ RouteHop(_devices['olt'], _devices['olt'].ports[1], _devices['olt'].ports[0]), None # 2nd hop is not known yet ], # UPSTREAM WILD-CARD (None, 0): [ None, # 1st hop is wildcard RouteHop(_devices['olt'], _devices['olt'].ports[0], _devices['olt'].ports[1]) ] } _default_rules = { 'onu1': (OrderedDict((f.id, f) for f in [ mk_flow_stat(match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0) ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)), output(1) ]) ]), OrderedDict()), 'onu2': (OrderedDict((f.id, f) for f in [ mk_flow_stat(match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0) ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 102)), output(1) ]) ]), OrderedDict()), 'onu3': (OrderedDict((f.id, f) for f in [ mk_flow_stat(match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0) ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 103)), output(1) ]) ]), OrderedDict()), 'onu4': (OrderedDict((f.id, f) for f in [ mk_flow_stat(match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0) ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 104)), output(1) ]) ]), OrderedDict()) } def get_all_default_rules(self): return self._default_rules def get_default_rules(self, device_id): return self._default_rules[device_id] def get_route(self, in_port_no, out_port_no): if out_port_no is not None and \ (out_port_no & 0x7fffffff) == ofp.OFPP_CONTROLLER: # treat it as if the output port is the NNI of the OLT out_port_no = 0 # OLT NNI port return self._routes[(in_port_no, out_port_no)] # ~~~~~~~~~~~~~~~~~~~~~~~~ ACTUAL TEST CASES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def test_eapol_reroute_rule_decomposition(self): flow = mk_flow_stat(match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 0), eth_type(0x888e) ], actions=[output(ofp.OFPP_CONTROLLER)], priority=1000) device_rules = self.decompose_rules([flow], []) onu1_flows, onu1_groups = device_rules['onu1'] olt_flows, olt_groups = device_rules['olt'] self.assertEqual(len(onu1_flows), 1) self.assertEqual(len(onu1_groups), 0) self.assertEqual(len(olt_flows), 2) self.assertEqual(len(olt_groups), 0) self.assertFlowsEqual( onu1_flows.values()[0], mk_flow_stat(match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0), ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)), output(1) ])) self.assertFlowsEqual( olt_flows.values()[0], mk_flow_stat(priority=1000, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 1), eth_type(0x888e) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)), output(2) ])) self.assertFlowsEqual( olt_flows.values()[1], mk_flow_stat(priority=1000, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000), vlan_pcp(0), metadata(1) ], actions=[pop_vlan(), output(1)])) def test_dhcp_reroute_rule_decomposition(self): flow = mk_flow_stat(match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 0), eth_type(0x0800), ipv4_dst(0xffffffff), ip_proto(17), udp_src(68), udp_dst(67) ], actions=[output(ofp.OFPP_CONTROLLER)], priority=1000) device_rules = self.decompose_rules([flow], []) onu1_flows, onu1_groups = device_rules['onu1'] olt_flows, olt_groups = device_rules['olt'] self.assertEqual(len(onu1_flows), 1) self.assertEqual(len(onu1_groups), 0) self.assertEqual(len(olt_flows), 2) self.assertEqual(len(olt_groups), 0) self.assertFlowsEqual( onu1_flows.values()[0], mk_flow_stat(match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0), ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)), output(1) ])) self.assertFlowsEqual( olt_flows.values()[0], mk_flow_stat(priority=1000, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 1), eth_type(0x0800), ipv4_dst(0xffffffff), ip_proto(17), udp_src(68), udp_dst(67) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)), output(2) ])) self.assertFlowsEqual( olt_flows.values()[1], mk_flow_stat(priority=1000, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000), vlan_pcp(0), metadata(1) ], actions=[pop_vlan(), output(1)])) @nottest def test_igmp_reroute_rule_decomposition(self): flow = mk_flow_stat(match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 0), eth_type(0x0800), ip_proto(2) ], actions=[output(ofp.OFPP_CONTROLLER)], priority=1000) device_rules = self.decompose_rules([flow], []) onu1_flows, onu1_groups = device_rules['onu1'] olt_flows, olt_groups = device_rules['olt'] self.assertEqual(len(onu1_flows), 2) self.assertEqual(len(onu1_groups), 0) self.assertEqual(len(olt_flows), 2) self.assertEqual(len(olt_groups), 0) self.assertFlowsEqual( onu1_flows.values()[0], mk_flow_stat(match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0), ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)), output(1) ])) self.assertFlowsEqual( olt_flows.values()[0], mk_flow_stat(priority=1000, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 1), eth_type(0x0800), ip_proto(2) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)), output(2) ])) self.assertFlowsEqual( olt_flows.values()[1], mk_flow_stat(priority=1000, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000), vlan_pcp(0), metadata(1) ], actions=[pop_vlan(), output(1)])) @nottest def test_wildcarded_igmp_reroute_rule_decomposition(self): flow = mk_flow_stat(match_fields=[eth_type(0x0800), ip_proto(2)], actions=[output(ofp.OFPP_CONTROLLER)], priority=2000, cookie=140) device_rules = self.decompose_rules([flow], []) onu1_flows, onu1_groups = device_rules['onu1'] olt_flows, olt_groups = device_rules['olt'] self.assertEqual(len(onu1_flows), 1) self.assertEqual(len(onu1_groups), 0) self.assertEqual(len(olt_flows), 8) self.assertEqual(len(olt_groups), 0) self.assertFlowsEqual( onu1_flows.values()[0], mk_flow_stat( match_fields=[in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0)], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)), output(1) ])) self.assertFlowsEqual( olt_flows.values()[0], mk_flow_stat(priority=2000, cookie=140, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 0), eth_type(0x0800), ip_proto(2) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)), output(2) ])) self.assertFlowsEqual( olt_flows.values()[1], mk_flow_stat(priority=2000, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000), vlan_pcp(0), metadata(0) ], actions=[pop_vlan(), output(1)])) self.assertFlowsEqual( olt_flows.values()[2], mk_flow_stat(priority=2000, cookie=140, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 1), eth_type(0x0800), ip_proto(2) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)), output(2) ])) self.assertFlowsEqual( olt_flows.values()[3], mk_flow_stat(priority=2000, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000), vlan_pcp(0), metadata(1) ], actions=[pop_vlan(), output(1)])) self.assertFlowsEqual( olt_flows.values()[4], mk_flow_stat(priority=2000, cookie=140, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 3), eth_type(0x0800), ip_proto(2) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)), output(2) ])) self.assertFlowsEqual( olt_flows.values()[5], mk_flow_stat(priority=2000, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000), vlan_pcp(0), metadata(3) ], actions=[pop_vlan(), output(1)])) self.assertFlowsEqual( olt_flows.values()[6], mk_flow_stat(priority=2000, cookie=140, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 4), eth_type(0x0800), ip_proto(2) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 4000)), output(2) ])) self.assertFlowsEqual( olt_flows.values()[7], mk_flow_stat(priority=2000, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 4000), vlan_pcp(0), metadata(4) ], actions=[pop_vlan(), output(1)])) def test_unicast_upstream_rule_decomposition(self): flow1 = mk_flow_stat(priority=500, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 0), vlan_pcp(0) ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)), ], next_table_id=1) flow2 = mk_flow_stat(priority=500, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 101), vlan_pcp(0) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 1000)), set_field(vlan_pcp(0)), output(0) ]) device_rules = self.decompose_rules([flow1, flow2], []) onu1_flows, onu1_groups = device_rules['onu1'] olt_flows, olt_groups = device_rules['olt'] self.assertEqual(len(onu1_flows), 2) self.assertEqual(len(onu1_groups), 0) self.assertEqual(len(olt_flows), 1) self.assertEqual(len(olt_groups), 0) self.assertFlowsEqual( onu1_flows.values()[1], mk_flow_stat(priority=500, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 0), vlan_pcp(0) ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 101)), output(1) ])) self.assertFlowsEqual( olt_flows.values()[0], mk_flow_stat(priority=500, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 101), vlan_pcp(0) ], actions=[ push_vlan(0x8100), set_field(vlan_vid(ofp.OFPVID_PRESENT | 1000)), set_field(vlan_pcp(0)), output(2) ])) def test_unicast_downstream_rule_decomposition(self): flow1 = mk_flow_stat(match_fields=[ in_port(0), vlan_vid(ofp.OFPVID_PRESENT | 1000), vlan_pcp(0) ], actions=[ pop_vlan(), ], next_table_id=1, priority=500) flow2 = mk_flow_stat( match_fields=[ in_port(0), vlan_vid(ofp.OFPVID_PRESENT | 101), vlan_pcp(0) ], actions=[set_field(vlan_vid(ofp.OFPVID_PRESENT | 0)), output(1)], priority=500) device_rules = self.decompose_rules([flow1, flow2], []) onu1_flows, onu1_groups = device_rules['onu1'] olt_flows, olt_groups = device_rules['olt'] self.assertEqual(len(onu1_flows), 2) self.assertEqual(len(onu1_groups), 0) self.assertEqual(len(olt_flows), 1) self.assertEqual(len(olt_groups), 0) self.assertFlowsEqual( olt_flows.values()[0], mk_flow_stat(priority=500, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 1000), vlan_pcp(0) ], actions=[pop_vlan(), output(1)])) self.assertFlowsEqual( onu1_flows.values()[1], mk_flow_stat(priority=500, match_fields=[ in_port(1), vlan_vid(ofp.OFPVID_PRESENT | 101), vlan_pcp(0) ], actions=[ set_field(vlan_vid(ofp.OFPVID_PRESENT | 0)), output(2) ])) def test_multicast_downstream_rule_decomposition(self): flow = mk_flow_stat(match_fields=[ in_port(0), vlan_vid(ofp.OFPVID_PRESENT | 170), vlan_pcp(0), eth_type(0x800), ipv4_dst(0xe00a0a0a) ], actions=[group(10)], priority=500) grp = mk_group_stat( group_id=10, buckets=[ofp.ofp_bucket(actions=[pop_vlan(), output(1)])]) device_rules = self.decompose_rules([flow], [grp]) onu1_flows, onu1_groups = device_rules['onu1'] olt_flows, olt_groups = device_rules['olt'] self.assertEqual(len(onu1_flows), 2) self.assertEqual(len(onu1_groups), 0) self.assertEqual(len(olt_flows), 1) self.assertEqual(len(olt_groups), 0) self.assertFlowsEqual( olt_flows.values()[0], mk_flow_stat(priority=500, match_fields=[ in_port(2), vlan_vid(ofp.OFPVID_PRESENT | 170), vlan_pcp(0), eth_type(0x800), ipv4_dst(0xe00a0a0a) ], actions=[pop_vlan(), output(1)])) self.assertFlowsEqual( onu1_flows.values()[1], mk_flow_stat(priority=500, match_fields=[ in_port(1), eth_type(0x800), ipv4_dst(0xe00a0a0a) ], actions=[output(2)]))
def setUp(self): self.setup_mock_registry() self.flows = Flows(items=[]) self.groups = FlowGroups(items=[]) self.ld_ports = [ LogicalPort(id='0', device_id='olt', device_port_no=0, root_port=True, ofp_port=ofp.ofp_port(port_no=0)), LogicalPort(id='1', device_id='onu1', device_port_no=0, ofp_port=ofp.ofp_port(port_no=1)), LogicalPort(id='2', device_id='onu2', device_port_no=0, ofp_port=ofp.ofp_port(port_no=2)) ] self.devices = { 'olt': Device(id='olt', root=True, parent_id='id'), 'onu1': Device(id='onu1', parent_id='olt', parent_port_no=1, vlan=101), 'onu2': Device(id='onu2', parent_id='olt', parent_port_no=1, vlan=102), } self.ports = { 'olt': [ Port(port_no=0, type=Port.ETHERNET_NNI, device_id='olt'), Port(port_no=1, type=Port.PON_OLT, device_id='olt', peers=[ Port.PeerPort(device_id='onu1', port_no=1), Port.PeerPort(device_id='onu2', port_no=1) ]) ], 'onu1': [ Port(port_no=0, type=Port.ETHERNET_UNI, device_id='onu1'), Port(port_no=1, type=Port.PON_ONU, device_id='onu1', peers=[ Port.PeerPort(device_id='olt', port_no=1), ]) ], 'onu2': [ Port(port_no=0, type=Port.ETHERNET_UNI, device_id='onu2'), Port(port_no=1, type=Port.PON_ONU, device_id='onu2', peers=[ Port.PeerPort(device_id='olt', port_no=1), ]) ], } self.device_flows = {'olt': Flows(), 'onu1': Flows(), 'onu2': Flows()} self.device_groups = { 'olt': FlowGroups(), 'onu1': FlowGroups(), 'onu2': FlowGroups() } self.ld = LogicalDevice(id='id', root_device_id='olt') self.root_proxy = Mock() def get_devices(path): if path == '': return self.devices.values() if path.endswith('/ports'): return self.ports[path[:-len('/ports')]] elif path.find('/') == -1: return self.devices[path] else: raise Exception( 'Nothing to yield for path /devices/{}'.format(path)) def update_devices(path, data): if path.endswith('/flows'): self.device_flows[path[:-len('/flows')]] = data elif path.endswith('/flow_groups'): self.device_groups[path[:-len('/flow_groups')]] = data else: raise NotImplementedError( 'not handling path /devices/{}'.format(path)) self.root_proxy.get = lambda p: \ get_devices(p[len('/devices/'):]) if p.startswith('/devices') \ else None self.root_proxy.update = lambda p, d: \ update_devices(p[len('/devices/'):], d) \ if p.startswith('/devices') \ else None self.ld_proxy = Mock() self.ld_proxy.get = lambda p: \ self.ld_ports if p == '/ports' else ( self.ld if p == '/' else None ) self.flows_proxy = Mock() self.flows_proxy.get = lambda _: self.flows # always '/' path def update_flows(_, flows): # always '/' path self.flows = flows self.flows_proxy.update = update_flows self.groups_proxy = Mock() self.groups_proxy.get = lambda _: self.groups # always '/' path def update_groups(_, groups): # always '/' path self.groups = groups self.groups_proxy.update = update_groups self.core = Mock() self.core.get_proxy = lambda path: \ self.root_proxy if path == '/' else ( self.ld_proxy if path.endswith('id') else ( self.flows_proxy if path.endswith('flows') else self.groups_proxy ) ) self.lda = LogicalDeviceAgent(self.core, self.ld)
def _onu_device_activation(self, device): # first we verify that we got parent reference and proxy info assert device.parent_id assert device.proxy_address.device_id assert device.proxy_address.channel_id == 0 device.model = 'GPON ONU' device.hardware_version = 'tbd' device.firmware_version = 'tbd' device.software_version = 'tbd' device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) uni_port = Port( port_no=1000, # FIXME It becomes the alloc_id label="{} ONU".format('PMCS'), type=Port.ETHERNET_UNI, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE) self.adapter_agent.add_port(device.id, uni_port) pon_port = Port(port_no=1, label='PON port', type=Port.PON_ONU, admin_state=AdminState.ENABLED, oper_status=OperStatus.ACTIVE, peers=[ Port.PeerPort(device_id=device.parent_id, port_no=device.parent_port_no) ]) self.adapter_agent.add_port(device.id, pon_port) # obtain logical device id parent_device = self.adapter_agent.get_device(device.parent_id) logical_device_id = parent_device.parent_id assert logical_device_id # we are going to use the proxy_address.channel_id as unique number # and name for the virtual ports, as this is guaranteed to be unique # in the context of the OLT port, so it is also unique in the context # of the logical device port_no = device.proxy_address.channel_id # FIXME this may need to be fixed cap = OFPPF_1GB_FD | OFPPF_FIBER self.adapter_agent.add_logical_port( logical_device_id, LogicalPort(id=str(port_no), ofp_port=ofp_port(port_no=port_no, hw_addr=mac_str_to_tuple( device.serial_number)[2:8], name='uni-{}'.format(port_no), config=0, state=OFPPS_LIVE, curr=cap, advertised=cap, peer=cap, curr_speed=OFPPF_1GB_FD, max_speed=OFPPF_1GB_FD), device_id=device.id, device_port_no=uni_port.port_no)) yield self._initialize_onu(device) # and finally update to "ACTIVE" device = self.adapter_agent.get_device(device.id) device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)