def send_proxied_message(self, proxy_address, msg): self.log.debug('sending-proxied-message') if isinstance(msg, FlowTable): stub = ponsim_pb2.PonSimStub(self.get_channel()) self.log.info('pushing-onu-flow-table', port=msg.port) res = stub.UpdateFlowTable(msg) self.adapter_agent.receive_proxied_message(proxy_address, res) elif isinstance(msg, PonSimMetricsRequest): stub = ponsim_pb2.PonSimStub(self.get_channel()) self.log.debug('proxying onu stats request', port=msg.port) res = stub.GetStats(msg) self.adapter_agent.receive_proxied_message(proxy_address, res)
def collect_port_metrics(self, channel): rtrn_port_metrics = dict() stub = ponsim_pb2.PonSimStub(channel) stats = stub.GetStats(Empty()) rtrn_port_metrics['pon'] = self.extract_pon_metrics(stats) rtrn_port_metrics['nni'] = self.extract_nni_metrics(stats) return rtrn_port_metrics
def reconcile(self, device): self.log.info('reconciling-OLT-device-starts') 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 try: stub = ponsim_pb2.PonSimStub(self.get_channel()) info = stub.GetDeviceInfo(Empty()) log.info('got-info', info=info) # TODO: Verify we are connected to the same device we are # reconciling - not much data in ponsim to differentiate at the # time device.oper_status = OperStatus.ACTIVE self.adapter_agent.update_device(device) self.ofp_port_no = info.nni_port self.nni_port = self._get_nni_port() except Exception, e: log.exception('device-unreachable', e=e) device.connect_status = ConnectStatus.UNREACHABLE device.oper_status = OperStatus.UNKNOWN self.adapter_agent.update_device(device) return
def update_flow_table(self, flows): stub = ponsim_pb2.PonSimStub(self.get_channel()) self.log.info('pushing-olt-flow-table') for flow in flows: classifier_info = {} for field in fd.get_ofb_fields(flow): if field.type == fd.ETH_TYPE: classifier_info['eth_type'] = field.eth_type self.log.debug('field-type-eth-type', eth_type=classifier_info['eth_type']) elif field.type == fd.IP_PROTO: classifier_info['ip_proto'] = field.ip_proto self.log.debug('field-type-ip-proto', ip_proto=classifier_info['ip_proto']) if ('ip_proto' in classifier_info and (classifier_info['ip_proto'] == 17 or classifier_info['ip_proto'] == 2)) or ( 'eth_type' in classifier_info and classifier_info['eth_type'] == 0x888e): for action in fd.get_actions(flow): if action.type == ofp.OFPAT_OUTPUT: action.output.port = ofp.OFPP_CONTROLLER self.log.info('out_port', out_port=fd.get_out_port(flow)) stub.UpdateFlowTable(FlowTable(port=0, flows=flows)) self.log.info('success')
def update_flow_table(self, flows): stub = ponsim_pb2.PonSimStub(self.get_channel()) self.log.info('pushing-olt-flow-table') stub.UpdateFlowTable(FlowTable( port=0, flows=flows )) self.log.info('success')
def packet_out(self, egress_port, msg): self.log.info('sending-packet-out', egress_port=egress_port, msg=hexify(msg)) pkt = Ether(msg) out_pkt = (Ether(src=pkt.src, dst=pkt.dst) / Dot1Q(vlan=4000) / Dot1Q(vlan=egress_port, type=pkt.type) / pkt.payload) if self.ponsim_comm == 'grpc': # send over grpc stream stub = ponsim_pb2.PonSimStub(self.get_channel()) frame = PonSimFrame(id=self.device_id, payload=str(out_pkt)) stub.SendFrame(frame) else: # send over frameio self.io_port.send(str(out_pkt))
def rcv_grpc(self): """ This call establishes a GRPC stream to receive frames. """ stub = ponsim_pb2.PonSimStub(self.get_channel()) # Attempt to establish a grpc stream with the remote ponsim service self.frames = stub.ReceiveFrames(Empty()) self.log.info('start-receiving-grpc-frames') try: for frame in self.frames: self.log.info('received-grpc-frame', frame_len=len(frame.payload)) self._rcv_frame(frame.payload) except _Rendezvous, e: log.warn('grpc-connection-lost', message=e.message)
def packet_out(self, egress_port, msg): self.log.debug('sending-packet-out', egress_port=egress_port, msg_hex=hexify(msg)) pkt = Ether(msg) out_pkt = pkt if egress_port != self.nni_port.port_no: # don't do the vlan manipulation for the NNI port, vlans are already correct out_pkt = (Ether(src=pkt.src, dst=pkt.dst) / Dot1Q(vlan=egress_port, type=pkt.type) / pkt.payload) # TODO need better way of mapping logical ports to PON ports out_port = self.nni_port.port_no if egress_port == self.nni_port.port_no else 1 if self.ponsim_comm == 'grpc': # send over grpc stream stub = ponsim_pb2.PonSimStub(self.get_channel()) frame = PonSimFrame(id=self.device_id, payload=str(out_pkt), out_port=out_port) stub.SendFrame(frame) else: # send over frameio self.io_port.send(str(out_pkt))
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(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) 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) # 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.log.info('re-enabled', device_id=device.id)