def __init__(self, **kwargs): super(OpenoltDevice, self).__init__() self.adapter_agent = kwargs['adapter_agent'] self.device_num = kwargs['device_num'] device = kwargs['device'] is_reconciliation = kwargs.get('reconciliation', False) self.device_id = device.id self.host_and_port = device.host_and_port self.log = structlog.get_logger(id=self.device_id, ip=self.host_and_port) self.proxy = registry('core').get_proxy('/') # Device already set in the event of reconciliation if not is_reconciliation: # It is a new device # Update device device.root = True device.serial_number = self.host_and_port # FIXME device.connect_status = ConnectStatus.UNREACHABLE device.oper_status = OperStatus.ACTIVATING self.adapter_agent.update_device(device) # If logical device does not exist create it if not device.parent_id: dpid = '00:00:' + self.ip_hex(self.host_and_port.split(":")[0]) # Create logical OF device ld = LogicalDevice( root_device_id=self.device_id, 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 ) ), desc=ofp_desc( serial_num=device.serial_number ) ) ld_init = self.adapter_agent.create_logical_device(ld, dpid=dpid) self.logical_device_id = ld_init.id else: # logical device already exists self.logical_device_id = device.parent_id if is_reconciliation: self.adapter_agent.reconcile_logical_device( self.logical_device_id) # Initialize the OLT state machine self.machine = Machine(model=self, states=OpenoltDevice.states, transitions=OpenoltDevice.transitions, send_event=True, initial='state_null') self.go_state_init()
def create_logical_device(self): log.debug('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=self.device.vendor, hw_desc=self.device.hardware_version, sw_desc=self.device.firmware_version, 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=self.device.id ) self.logical_device = self.adapter_agent.create_logical_device(ld, dpid=self.device.mac_address)
def olt_indication_up(self, event): olt_indication = event.kwargs.get('ind', None) self.log.debug("olt indication", olt_ind=olt_indication) device = self.adapter_agent.get_device(self.device_id) # If logical device does not exist create it if len(device.parent_id) == 0: dpid = '00:00:' + self.ip_hex(self.host_and_port.split(":")[0]) # Create logical OF device ld = LogicalDevice( root_device_id=self.device_id, 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))) ld_initialized = self.adapter_agent.create_logical_device( ld, dpid=dpid) self.logical_device_id = ld_initialized.id # Update phys OF device device.parent_id = self.logical_device_id device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device)
def create_logical_device(self, device_info): dpid = device_info.device_id serial_number = device_info.device_serial_number if dpid is None: dpid = self.dpid if serial_number is None: serial_number = self.serial_number if dpid == None or dpid == '': uri = self.host_and_port.split(":")[0] try: socket.inet_pton(socket.AF_INET, uri) dpid = '00:00:' + self.ip_hex(uri) except socket.error: # this is not an IP dpid = self.stringToMacAddr(uri) if serial_number == None or serial_number == '': serial_number = self.host_and_port self.log.info('creating-openolt-logical-device', dp_id=dpid, serial_number=serial_number) mfr_desc = device_info.vendor sw_desc = device_info.firmware_version hw_desc = device_info.model if device_info.hardware_version: hw_desc += '-' + device_info.hardware_version # Create logical OF device ld = LogicalDevice( root_device_id=self.device_id, 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)), desc=ofp_desc(mfr_desc=mfr_desc, hw_desc=hw_desc, sw_desc=sw_desc, serial_num=serial_number)) ld_init = self.adapter_agent.create_logical_device(ld, dpid=dpid) self.logical_device_id = ld_init.id device = self.adapter_agent.get_device(self.device_id) device.serial_number = serial_number self.adapter_agent.update_device(device) self.dpid = dpid self.serial_number = serial_number self.log.info('created-openolt-logical-device', logical_device_id=ld_init.id)
def olt_create(self, device_info): if self.logical_device_id is not None: return dpid = device_info.device_id serial_number = device_info.device_serial_number if dpid is None or dpid == '': uri = self.device.host_and_port.split(":")[0] try: socket.inet_pton(socket.AF_INET, uri) dpid = '00:00:' + OpenoltUtils.ip_hex(uri) except socket.error: # this is not an IP dpid = OpenoltUtils.str_to_mac(uri) self.log.info('creating-openolt-logical-device', dp_id=dpid, serial_number=serial_number) hw_desc = device_info.model if device_info.hardware_version: hw_desc += '-' + device_info.hardware_version # Create logical OF device ld = LogicalDevice( root_device_id=self.device.id, 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 ) ), desc=ofp_desc( serial_num=serial_number ) ) self.logical_device_id = \ self.adapter_agent.create_logical_device(ld, dpid=dpid).id self.device.vendor = device_info.vendor self.device.model = device_info.model self.device.hardware_version = device_info.hardware_version self.device.firmware_version = device_info.firmware_version self.device.connect_status = ConnectStatus.REACHABLE self.device.serial_number = serial_number self.adapter_agent.update_device(self.device) self.log.info('created-openolt-logical-device', logical_device_id=self.logical_device_id) return self.logical_device_id
def __init__(self, **kwargs): super(OpenoltDevice, self).__init__() self.adapter_agent = kwargs['adapter_agent'] device = kwargs['device'] self.device_id = device.id self.host_and_port = device.host_and_port self.log = structlog.get_logger(id=self.device_id, ip=self.host_and_port) self.oper_state = 'unknown' self.nni_oper_state = dict() #intf_id -> oper_state self.onus = {} # Onu -> serial_number self.uni_port_num = 20 # FIXME # Create logical device ld = LogicalDevice( desc=ofp_desc(mfr_desc='FIXME', hw_desc='FIXME', sw_desc='FIXME', serial_num='FIXME', dp_desc='n/a'), switch_features=ofp_switch_features( n_buffers=256, n_tables=2, capabilities=(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_GROUP_STATS | OFPC_PORT_STATS)), root_device_id=self.device_id) # FIXME ld_initialized = self.adapter_agent.create_logical_device( ld, dpid='de:ad:be:ef:fe:ed') # FIXME self.logical_device_id = ld_initialized.id # Update device device.root = True device.vendor = 'Edgecore' device.model = 'ASFvOLT16' device.serial_number = self.host_and_port # FIXME device.parent_id = self.logical_device_id device.connect_status = ConnectStatus.REACHABLE device.oper_status = OperStatus.ACTIVATING self.adapter_agent.update_device(device) # Initialize gRPC self.channel = grpc.insecure_channel(self.host_and_port) self.channel_ready_future = grpc.channel_ready_future(self.channel) # Start indications thread self.indications_thread = threading.Thread( target=self.process_indications) self.indications_thread.daemon = True self.indications_thread.start()
def add_logical_device(self, device_id): self.log.info('adding-logical-device', device_id=device_id) 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 Edgecore ASFvOLT16 OLT', 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) return ld_initialized.id
def create_logical_device(self, device): version = device.images.image[0].version ld = LogicalDevice( # NOTE: not setting id and datapath_id will let the adapter agent pick id desc=ofp_desc(mfr_desc=device.vendor, hw_desc=device.hardware_version, sw_desc=version, serial_num=device.serial_number, dp_desc='n/a'), switch_features=ofp_switch_features(n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_GROUP_STATS | OFPC_PORT_STATS)), root_device_id=device.id) ld_initialized = self.adapter_agent.create_logical_device(ld) return ld_initialized
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 _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 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') 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 _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.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): """ Activate the OLT device :param device: A voltha.Device object, with possible device-type specific extensions. """ self.log.info('AdtranDeviceHandler.activating', device=device) if self.logical_device_id is None: if not device.host_and_port: self.activate_failed(device, 'No host_and_port field provided') pattern = '(?P<host>[^:/ ]+).?(?P<port>[0-9]*).*' info = re.match(pattern, device.host_and_port) if not info or len(info.group('host')) == 0 or len(info.group('port')) == 0 or \ (int(info.group('port')) if info.group('port') else None) is None: self.activate_failed(device, 'Invalid Host or Port provided', reachable=False) self.ip_address = str(info.group('host')) self.rest_port = int(info.group('port')) ############################################################################ # Start initial discovery of RESTCONF support (if any) self.rest_client = AdtranRestClient(self.ip_address, self.rest_port, self.rest_username, self.rest_password, self.rest_timeout) try: # content: (dict) Modules from the hello message self.startup = self.rest_client.request('GET', self.HELLO_URI, name='hello') results = yield self.startup self.log.debug('HELLO Contents: {}'.format( pprint.PrettyPrinter().pformat(results))) except Exception as e: results = None self.log.exception('Initial RESTCONF adtran-hello failed', e=e) self.activate_failed(device, e.message, reachable=False) ############################################################################ # TODO: Get these six via NETCONF and from the derived class device.model = 'TODO: Adtran PizzaBox, YUM' device.hardware_version = 'TODO: H/W Version' device.firmware_version = 'TODO: S/W Version' device.software_version = 'TODO: S/W Version' device.serial_number = 'TODO: Serial Number' device.root = True device.vendor = 'Adtran, Inc.' device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) try: # Enumerate and create Northbound NNI interfaces self.startup = self.enumerate_northbound_ports(device) results = yield self.startup self.startup = self.process_northbound_ports(device, results) yield self.startup for port in self.northbound_ports.itervalues(): self.adapter_agent.add_port(device.id, port.get_port()) except Exception as e: self.log.exception( 'Northbound port enumeration and creation failed', e=e) self.activate_failed(device, e.message) results = None try: # Enumerate and create southbound interfaces self.startup = self.enumerate_southbound_ports(device) results = yield self.startup self.startup = self.process_southbound_ports(device, results) yield self.startup for port in self.southbound_ports.itervalues(): self.adapter_agent.add_port(device.id, port.get_port()) except Exception as e: self.log.exception( 'Southbound port enumeration and creation failed', e=e) self.activate_failed(device, e.message) # Complete activation by setting up logical device for this OLT and saving # off the devices parent_id ld = LogicalDevice( # NOTE: not setting id and datapath_id will let the adapter agent pick id desc=ofp_desc(mfr_desc=device.vendor, hw_desc=device.hardware_version, sw_desc=device.software_version, serial_num=device.serial_number, dp_desc='n/a'), switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS)), # TODO and ditto root_device_id=device.id) ld_initialized = self.adapter_agent.create_logical_device(ld) # Create logical ports for all southbound and northbound interfaces for port in self.northbound_ports.itervalues(): lp = port.get_logical_port() if lp is not None: self.adapter_agent.add_logical_port(ld_initialized.id, lp) for port in self.southbound_ports.itervalues(): lp = port.get_logical_port() if lp is not None: self.adapter_agent.add_logical_port(ld_initialized.id, lp) # Set the downlinks in a known good initial state try: for port in self.southbound_ports.itervalues(): self.startup = port.reset() yield self.startup except Exception as e: self.log.exception( 'Failed to reset southbound ports to known good initial state', e=e) self.activate_failed(device, e.message) # Start/stop the interfaces as needed try: for port in self.northbound_ports.itervalues(): self.startup = port.start() yield self.startup except Exception as e: self.log.exception('Failed to start northbound port(s)', e=e) self.activate_failed(device, e.message) try: start_downlinks = self.initial_port_state == AdminState.ENABLED for port in self.southbound_ports.itervalues(): self.startup = port.start( ) if start_downlinks else port.stop() yield self.startup except Exception as e: self.log.exception('Failed to start southbound port(s)', e=e) self.activate_failed(device, e.message) # Complete device specific steps try: self.startup = self.complete_device_specific_activation( device, results) if self.startup is not None: yield self.startup except Exception as e: self.log.exception('Device specific activation failed', e=e) self.activate_failed(device, e.message) # Schedule the heartbeat for the device self.start_heartbeat(delay=10) # Save off logical ID and specify that we active self.logical_device_id = ld_initialized.id 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)
def __init__(self, **kwargs): super(OpenoltDevice, self).__init__() self.adapter_agent = kwargs['adapter_agent'] self.device_num = kwargs['device_num'] device = kwargs['device'] is_reconciliation = kwargs.get('reconciliation', False) self.device_id = device.id self.host_and_port = device.host_and_port self.log = structlog.get_logger(id=self.device_id, ip=self.host_and_port) self.proxy = registry('core').get_proxy('/') # Device already set in the event of reconciliation if not is_reconciliation: # It is a new device # Update device device.root = True device.serial_number = self.host_and_port # FIXME device.connect_status = ConnectStatus.REACHABLE device.oper_status = OperStatus.ACTIVATING self.adapter_agent.update_device(device) # Initialize the OLT state machine self.machine = Machine(model=self, states=OpenoltDevice.states, transitions=OpenoltDevice.transitions, send_event=True, initial='down', ignore_invalid_triggers=True) self.machine.add_transition(trigger='olt_ind_up', source='down', dest='up') self.machine.add_transition(trigger='olt_ind_loss', source='up', dest='down') # If logical device does not exist create it if len(device.parent_id) == 0: dpid = '00:00:' + self.ip_hex(self.host_and_port.split(":")[0]) # Create logical OF device ld = LogicalDevice( root_device_id=self.device_id, 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))) ld_init = self.adapter_agent.create_logical_device(ld, dpid=dpid) self.logical_device_id = ld_init.id else: # logical device already exists self.logical_device_id = device.parent_id if is_reconciliation: self.adapter_agent.reconcile_logical_device( self.logical_device_id) # Initialize gRPC self.channel = grpc.insecure_channel(self.host_and_port) self.channel_ready_future = grpc.channel_ready_future(self.channel) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) self.flow_mgr = OpenOltFlowMgr(self.log, self.stub, self.device_id) # Indications thread plcaholder (started by heartbeat thread) self.indications_thread = None self.indications_thread_active = False # Start heartbeat thread self.heartbeat_thread = threading.Thread(target=self.heartbeat) self.heartbeat_thread.setDaemon(True) self.heartbeat_thread_active = True self.heartbeat_miss = 0 self.heartbeat_signature = None self.heartbeat_thread.start() if is_reconciliation: # Put state machine in state up reactor.callFromThread(self.olt_up, reconciliation=True) self.log.debug('openolt-device-created', device_id=self.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)