Esempio n. 1
0
 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)
Esempio n. 2
0
 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
Esempio n. 3
0
    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
Esempio n. 4
0
    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')
Esempio n. 5
0
 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')
Esempio n. 6
0
    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))
Esempio n. 7
0
    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)
Esempio n. 8
0
    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))
Esempio n. 9
0
    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)
Esempio n. 10
0
    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)