Ejemplo n.º 1
0
    def _message_exchange(self, device):

        # register for receiving async messages
        self.adapter_agent.register_for_proxied_messages(device.proxy_address)

        # reset incoming message queue
        while self.incoming_messages.pending:
            _ = yield self.incoming_messages.get()

        # send out ping frame to ONU device get device information
        ping_frame = (
            EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
            EOAM_DpoeMsg(dpoe_opcode=Dpoe_Opcodes["Get Request"],
                         body=VendorName() /
                              OnuMode() /
                              HardwareVersion() /
                              ManufacturerInfo()
                              ) /
            EndOfPDU()
            )

        log.info('ONU-send-proxied-message to Get Version Info for ONU: {}'.format(device.mac_address))
        self.adapter_agent.send_proxied_message(device.proxy_address, ping_frame)

        # Loop until we have a Get Response
        ack = False
        while not ack:
            frame = yield self.incoming_messages.get()

            respType = get_oam_msg_type(log, frame)
         
            if (respType == RxedOamMsgTypeEnum["DPoE Get Response"]):
                ack = True
            else:
                # Handle unexpected events/OMCI messages
                check_resp(log, frame)

        if ack:
            log.info('ONU-response received for Get Version Info for ONU: {}'.format(device.mac_address))

            self._process_ping_frame_response(device, frame)


        if self.mode.upper()[0] == "G":  # GPON
            # construct multicast LLID set
            msg = (
                EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
                EOAM_DpoeMsg(dpoe_opcode=Dpoe_Opcodes["Multicast Register"],body=MulticastRegisterSet(MulticastLink=0x10bc, UnicastLink=0)
                ))

            # send message
            log.info('ONU-send-proxied-message to Multicast Register Set for ONU: {}'.format(device.mac_address))
            self.adapter_agent.send_proxied_message(device.proxy_address, msg)
Ejemplo n.º 2
0
    def reboot_device(self, device):
        log.info('Rebooting ONU: {}'.format(device.mac_address))

        # Update the operational status to ACTIVATING and connect status to
        # UNREACHABLE
        previous_oper_status = device.oper_status
        previous_conn_status = device.connect_status
        device.oper_status = OperStatus.ACTIVATING
        device.connect_status = ConnectStatus.UNREACHABLE
        self.adapter_agent.update_device(device)

        msg = (
            EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
            EOAM_DpoeMsg(dpoe_opcode = Dpoe_Opcodes["Set Request"],
                         body=DeviceReset())/
            EndOfPDU()
            )

        action = "Device Reset"

        # send message
        log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address))
        self.adapter_agent.send_proxied_message(device.proxy_address, msg)

        rc = []
        yield self._handle_set_resp(device, action, rc)

        # Change the operational status back to its previous state.
        device.oper_status = previous_oper_status
        device.connect_status = previous_conn_status
        self.adapter_agent.update_device(device)

        log.info('ONU Rebooted: {}'.format(device.mac_address))
Ejemplo n.º 3
0
    def _send_clear_static_mac_table(self, device):
        # construct install of igmp query address
        msg = (
            EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
            EOAM_DpoeMsg(dpoe_opcode=Dpoe_Opcodes["Set Request"],body=ClearStaticMacTable()
            ))

        action = "Clear Static MAC Table"

        # send message
        log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address))
        self.adapter_agent.send_proxied_message(device.proxy_address, msg)

        rc = []
        yield self._handle_set_resp(device, action, rc)
Ejemplo n.º 4
0
    def _send_igmp_mcast_addr(self, device):
        # construct install of igmp query address
        msg = (
            EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
            EOAM_DpoeMsg(dpoe_opcode=Dpoe_Opcodes["Set Request"],body=AddStaticMacAddress(mac='01:00:5e:00:00:01')
            ))

        action = "Set Static IGMP MAC address"

        # send message
        log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address))
        self.adapter_agent.send_proxied_message(device.proxy_address, msg)

        rc = []
        yield self._handle_set_resp(device, action, rc)
Ejemplo n.º 5
0
    def update_flows_bulk(self, device, flows, groups):
        log.info('########################################')
        log.info('bulk-flow-update', device_id=device.id,
                 flows=flows, groups=groups)
        assert len(groups.items) == 0, "Cannot yet deal with groups"

        # Only do something if there are flows to program
        if (len(flows.items) > 0):
            # Clear the existing entries in the Static MAC Address Table
            yield self._send_clear_static_mac_table(device)

            # Re-add the IGMP Multicast Address
            yield self._send_igmp_mcast_addr(device)

        Clause = {v: k for k, v in ClauseSubtypeEnum.iteritems()}
        Operator = {v: k for k, v in RuleOperatorEnum.iteritems()}

        for flow in flows.items:
            in_port = get_in_port(flow)
            assert in_port is not None

            precedence = 255 - min(flow.priority / 256, 255)

            if in_port == 2:
                log.info('#### Upstream Rule ####')


                up_req = UserPortObject()
                up_req /= PortIngressRuleHeader(precedence=precedence)

                for field in get_ofb_fields(flow):

                    if field.type == ETH_TYPE:
                        _type = field.eth_type
                        log.info('#### field.type == ETH_TYPE ####',field_type=_type)

                    elif field.type == IP_PROTO:
                        _proto = field.ip_proto
                        log.info('#### field.type == IP_PROTO ####')

                    elif field.type == IN_PORT:
                        _port = field.port
                        log.info('#### field.type == IN_PORT ####', port=_port)

                    elif field.type == VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        log.info('#### field.type == VLAN_VID ####', vlan=_vlan_vid)
                        up_req /= PortIngressRuleClauseMatchLength02(fieldcode=Clause['C-VLAN Tag'], fieldinstance=0,
                                                                     operator=Operator['=='], match=_vlan_vid)

                    elif field.type == VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        log.info('#### field.type == VLAN_PCP ####', pcp=_vlan_pcp)

                    elif field.type == UDP_DST:
                        _udp_dst = field.udp_dst
                        log.info('#### field.type == UDP_DST ####', udp_dst=_udp_dst)

                    elif field.type == IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        log.info('#### field.type == IPV4_DST ####', ipv4_dst=_ipv4_dst)

                    elif field.type == METADATA:
                        _metadata = field.table_metadata
                        log.info('#### field.type == METADATA ####', metadata=_metadata)

                    else:
                        log.info('#### field.type == NOT IMPLEMENTED!! ####')
                        raise NotImplementedError('field.type={}'.format(
                            field.type))

                for action in get_actions(flow):

                    if action.type == OUTPUT:
                        log.info('#### action.type == OUTPUT ####')
                        up_req /= PortIngressRuleResultInsert(fieldcode=Clause['C-VLAN Tag'])

                    elif action.type == POP_VLAN:
                        log.info('#### action.type == POP_VLAN ####')

                    elif action.type == PUSH_VLAN:
                        log.info('#### action.type == PUSH_VLAN ####')
                        up_req /= PortIngressRuleResultInsert(fieldcode=Clause['C-VLAN Tag'])
#                        if action.push.ethertype != 0x8100:
#                            log.error('unhandled-tpid',
#                                      ethertype=action.push.ethertype)

                    elif action.type == SET_FIELD:
                        log.info('#### action.type == SET_FIELD ####')
                        assert (action.set_field.field.oxm_class ==
                                ofp.OFPXMC_OPENFLOW_BASIC)
                        field = action.set_field.field.ofb_field
                        if field.type == VLAN_VID:
                            log.info("#### action.field.vlan {} ####".format(field.vlan_vid & 0xfff))
                            up_req /= PortIngressRuleResultSet(
                                    fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff)
                        else:
                            log.error('unsupported-action-set-field-type',
                                      field_type=field.type)
                    else:
                        log.error('UNSUPPORTED-ACTION-TYPE',
                                  action_type=action.type)

                up_req /= PortIngressRuleTerminator()
                up_req /= AddPortIngressRule()

                msg = (
                    EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
                    EOAM_DpoeMsg(dpoe_opcode = Dpoe_Opcodes["Set Request"], body=up_req)/
                    EndOfPDU()
                )

                # send message
                action = "Set ONU US Rule"
                log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address))
                self.adapter_agent.send_proxied_message(device.proxy_address, msg)

                # Get and process the Set Response
                rc = []
                yield self._handle_set_resp(device, action, rc)


            elif in_port == 1:
                log.info('#### Downstream Rule ####')
                Is_MCast = False

                dn_req = PonPortObject()
                dn_req /= PortIngressRuleHeader(precedence=precedence)

                #### Loop through fields again...

                for field in get_ofb_fields(flow):

                    if field.type == ETH_TYPE:
                        _type = field.eth_type
                        log.info('#### field.type == ETH_TYPE ####', in_port=in_port,
                                 match=_type)

                    elif field.type == IP_PROTO:
                        _proto = field.ip_proto
                        log.info('#### field.type == IP_PROTO ####', in_port=in_port,
                                 ip_proto=_proto)

                    elif field.type == IN_PORT:
                        _port = field.port
                        log.info('#### field.type == IN_PORT ####')

                    elif field.type == VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        log.info('#### field.type == VLAN_VID ####')

                    elif field.type == VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        log.info('#### field.type == VLAN_PCP ####')

                    elif field.type == UDP_DST:
                        _udp_dst = field.udp_dst
                        log.info('#### field.type == UDP_DST ####')

                    elif field.type == IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        log.info('#### field.type == IPV4_DST ####')
                        a = int(hex(_ipv4_dst)[2:4], 16)
                        b = int(hex(_ipv4_dst)[4:6], 16)
                        c = int(hex(_ipv4_dst)[6:8], 16)
                        d = int(hex(_ipv4_dst)[8:], 16)
                        dn_req = AddStaticMacAddress(mac=mcastIp2McastMac('%d.%d.%d.%d' % (a,b,c,d)))
                        Is_MCast = True

                    else:
                        raise NotImplementedError('field.type={}'.format(
                            field.type))

                for action in get_actions(flow):

                    if action.type == OUTPUT:
                        log.info('#### action.type == OUTPUT ####')

                    elif action.type == POP_VLAN:
                        log.info('#### action.type == POP_VLAN ####')
                        dn_req /= PortIngressRuleClauseMatchLength02(fieldcode=Clause['C-VLAN Tag'], fieldinstance=0,
                                                                     operator=Operator['=='], match=_vlan_vid)
                        dn_req /= PortIngressRuleResultReplace(fieldcode=Clause['C-VLAN Tag'])
                        dn_req /= PortIngressRuleResultSet(
                                fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff)

                    elif action.type == PUSH_VLAN:
                        log.info('#### action.type == PUSH_VLAN ####')
                        if action.push.ethertype != 0x8100:
                            log.error('unhandled-ether-type',
                                      ethertype=action.push.ethertype)

                    elif action.type == SET_FIELD:
                        log.info('#### action.type == SET_FIELD ####')
                        assert (action.set_field.field.oxm_class ==
                                ofp.OFPXMC_OPENFLOW_BASIC)
                        field = action.set_field.field.ofb_field
                        if field.type == VLAN_VID:
                            dn_req /= PortIngressRuleClauseMatchLength02(fieldcode=Clause['C-VLAN Tag'], fieldinstance=0,
                                                                         operator=Operator['=='], match=_vlan_vid)
                            dn_req /= PortIngressRuleResultReplace(fieldcode=Clause['C-VLAN Tag'])
                            dn_req /= PortIngressRuleResultSet(
                                    fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff)
                        else:
                            log.error('unsupported-action-set-field-type',
                                      field_type=field.type)

                    else:
                        log.error('UNSUPPORTED-ACTION-TYPE',
                                  action_type=action.type)

                if Is_MCast is True:
                    action = "Set Static IP MCAST address"
                else:
                    dn_req /= PortIngressRuleTerminator()
                    dn_req /= AddPortIngressRule()
                    action = "Set ONU DS Rule"

                msg = (
                    EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
                    EOAM_DpoeMsg(dpoe_opcode = Dpoe_Opcodes["Set Request"], body=dn_req)/
                    EndOfPDU()
                )

                # send message
                log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address))
                self.adapter_agent.send_proxied_message(device.proxy_address, msg)

                # Get and process the Set Response
                rc = []
                yield self._handle_set_resp(device, action, rc)

            else:
                raise Exception('Port should be 1 or 2 by our convention')

        log.info('bulk-flow-update finished', device_id=device.id,
                 flows=flows, groups=groups)
        log.info('########################################')
Ejemplo n.º 6
0
    def _message_exchange(self, device):

        # register for receiving async messages
        self.adapter_agent.register_for_proxied_messages(device.proxy_address)

        # reset incoming message queue
        while self.incoming_messages.pending:
            _ = yield self.incoming_messages.get()

        # construct message
        msg = (
            EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
            EOAM_DpoeMsg(dpoe_opcode=0x01,body=DeviceId())
            )

        # send message
        log.info('ONU-send-proxied-message to Get Device Id for ONU: {}'.format(device.mac_address))

        self.adapter_agent.send_proxied_message(device.proxy_address, msg)

        # wait till we detect incoming message
        yield self.incoming_messages.get()

        log.info('ONU-response received for Get Device Id for ONU: {}'.format(device.mac_address))

        #TODO Add a timeout to the above, if we do not recieve a message

        #The above get request/ get response is done to verify the message exchange is
        #functioning correctly, there is nothing to store from the response

        # construct install of igmp query address
        msg = (
            EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
            EOAM_DpoeMsg(dpoe_opcode=0x03,body=AddStaticMacAddress(mac='01:00:5e:00:00:01')
            ))

        # send message
        log.info('ONU-send-proxied-message to Set Static IGMP MAC address for ONU: {}'.format(device.mac_address))
        self.adapter_agent.send_proxied_message(device.proxy_address, msg)

        # Get and process the Set Response
        ack = False
        start_time = time.time()

        # Loop until we have a set response or timeout
        while not ack:
            frame = yield self.incoming_messages.get()
            #TODO - Need to add propoer timeout functionality
            #if (time.time() - start_time) > TIBIT_MSG_WAIT_TIME or (frame is None):
            #    break  # don't wait forever

            respType = self._get_oam_msg_type(frame)
            log.info('Received OAM Message 0x %s' % str(respType))

            #Check that the message received is a Set Response
            if (respType == RxedOamMsgTypeEnum["DPoE Set Response"]):
                ack = True
            else:
                # Handle unexpected events/OMCI messages
                self._check_resp(frame)

        # Verify Set Response
        if ack:
            log.info('ONU-response received for Set Static IGMP MAC address for ONU: {}'.format(device.mac_address))
            (rc,branch,leaf,status) = self._check_set_resp(frame)
            if (rc == True):
                log.info('Set Response had no errors')
            else:
                log.info('Set Response had errors - Branch 0x{:X} Leaf 0x{:0>4X} {}'.format(branch, leaf, DPoEVariableResponseCodes[status]))

        # construct multicast LLID set
        # TODO - This is needed to support multicast traffic for GPON. This should only be done for a 
        #        a GPON ONU and the UnicastLink value needs to come from the OLT. This will work only for
        #        a single GPON ONU.
        msg = (
            EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
            EOAM_DpoeMsg(dpoe_opcode=0x06,body=MulticastRegisterSet(MulticastLink=0x10bc, UnicastLink=0x1008)
            ))

        # send message
        log.info('ONU-send-proxied-message to Set Static IGMP MAC address for ONU: {}'.format(device.mac_address))
        self.adapter_agent.send_proxied_message(device.proxy_address, msg)
Ejemplo n.º 7
0
    def update_flows_bulk(self, device, flows, groups):
        log.info('########################################')
        log.info('bulk-flow-update', device_id=device.id,
                 flows=flows, groups=groups)
        assert len(groups.items) == 0, "Cannot yet deal with groups"

        Clause = {v: k for k, v in ClauseSubtypeEnum.iteritems()}
        Operator = {v: k for k, v in RuleOperatorEnum.iteritems()}

        for flow in flows.items:
            in_port = get_in_port(flow)
            assert in_port is not None

            precedence = 255 - min(flow.priority / 256, 255)

            if in_port == 2:
                log.info('#### Upstream Rule ####')

                up_req = (
                    EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
                    EOAM_DpoeMsg(dpoe_opcode=0x03)
                    )

                #TODO - There is no body to the message above, is there ever an Upstream Rule

                for field in get_ofb_fields(flow):

                    if field.type == ETH_TYPE:
                        _type = field.eth_type
                        log.info('#### field.type == ETH_TYPE ####',field_type=_type)

                    elif field.type == IP_PROTO:
                        _proto = field.ip_proto
                        log.info('#### field.type == IP_PROTO ####')

                    elif field.type == IN_PORT:
                        _port = field.port
                        log.info('#### field.type == IN_PORT ####', port=_port)

                    elif field.type == VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        log.info('#### field.type == VLAN_VID ####', vlan=_vlan_vid)

                    elif field.type == VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        log.info('#### field.type == VLAN_PCP ####', pcp=_vlan_pcp)

                    elif field.type == UDP_DST:
                        _udp_dst = field.udp_dst
                        log.info('#### field.type == UDP_DST ####')

                    elif field.type == IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        log.info('#### field.type == IPV4_DST ####')

                    else:
                        log.info('#### field.type == NOT IMPLEMENTED!! ####')
                        raise NotImplementedError('field.type={}'.format(
                            field.type))

                for action in get_actions(flow):

                    if action.type == OUTPUT:
                        log.info('#### action.type == OUTPUT ####')

                    elif action.type == POP_VLAN:
                        log.info('#### action.type == POP_VLAN ####')

                    elif action.type == PUSH_VLAN:
                        log.info('#### action.type == PUSH_VLAN ####')
                        if action.push.ethertype != 0x8100:
                            log.error('unhandled-tpid',
                                      ethertype=action.push.ethertype)

                    elif action.type == SET_FIELD:
                        log.info('#### action.type == SET_FIELD ####')
                        assert (action.set_field.field.oxm_class ==
                                ofp.OFPXMC_OPENFLOW_BASIC)
                        field = action.set_field.field.ofb_field
                        if field.type == VLAN_VID:
                            pass
                        else:
                            log.error('unsupported-action-set-field-type',
                                      field_type=field.type)
                    else:
                        log.error('UNSUPPORTED-ACTION-TYPE',
                                  action_type=action.type)

            elif in_port == 1:
                log.info('#### Downstream Rule ####')

                #### Loop through fields again...

                for field in get_ofb_fields(flow):

                    if field.type == ETH_TYPE:
                        _type = field.eth_type
                        log.info('#### field.type == ETH_TYPE ####', in_port=in_port,
                                 match=_type)

                    elif field.type == IP_PROTO:
                        _proto = field.ip_proto
                        log.info('#### field.type == IP_PROTO ####', in_port=in_port,
                                 ip_proto=ip_proto)

                    elif field.type == IN_PORT:
                        _port = field.port
                        log.info('#### field.type == IN_PORT ####')

                    elif field.type == VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        log.info('#### field.type == VLAN_VID ####')

                    elif field.type == VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        log.info('#### field.type == VLAN_PCP ####')

                    elif field.type == UDP_DST:
                        _udp_dst = field.udp_dst
                        log.info('#### field.type == UDP_DST ####')

                    elif field.type == IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        log.info('#### field.type == IPV4_DST ####')
                        a = int(hex(_ipv4_dst)[2:4], 16)
                        b = int(hex(_ipv4_dst)[4:6], 16)
                        c = int(hex(_ipv4_dst)[6:8], 16)
                        d = int(hex(_ipv4_dst)[8:], 16)
                        dn_req = (
                            EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) /
                            EOAM_DpoeMsg(dpoe_opcode=0x03, body=AddStaticMacAddress(mac=mcastIp2McastMac('%d.%d.%d.%d' % (a,b,c,d)))
                            ))
                        
                        # send message

                        log.info('ONU-send-proxied-message to Set Static IP MCAST address for ONU: {}'.format(device.mac_address))
                        self.adapter_agent.send_proxied_message(device.proxy_address,
                                                                dn_req)

                        # Get and process the Set Response
                        ack = False
                        start_time = time.time()

                        # Loop until we have a set response or timeout
                        while not ack:
                            frame = yield self.incoming_messages.get()
                            #TODO - Need to add propoer timeout functionality
                            #if (time.time() - start_time) > TIBIT_MSG_WAIT_TIME or (frame is None):
                            #    break  # don't wait forever

                            respType = self._get_oam_msg_type(frame)
                            log.info('Received OAM Message 0x %s' % str(respType))

                            #Check that the message received is a Set Response
                            if (respType == RxedOamMsgTypeEnum["DPoE Set Response"]):
                                ack = True
                            else:
                                # Handle unexpected events/OMCI messages
                                self._check_resp(frame)

                        # Verify Set Response
                        if ack:
                            log.info('ONU-response received for Set Static IP MCAST address for ONU: {}'.format(device.mac_address))
                            (rc,branch,leaf,status) = self._check_set_resp(frame)
                            if (rc == True):
                                log.info('Set Response had no errors')
                            else:
                                log.info('Set Response had errors - Branch 0x{:X} Leaf 0x{:0>4X} {}'.format(branch, leaf, DPoEVariableResponseCodes[status]))

                    else:
                        raise NotImplementedError('field.type={}'.format(
                            field.type))

                for action in get_actions(flow):

                    if action.type == OUTPUT:
                        log.info('#### action.type == OUTPUT ####')

                    elif action.type == POP_VLAN:
                        log.info('#### action.type == POP_VLAN ####')

                    elif action.type == PUSH_VLAN:
                        log.info('#### action.type == PUSH_VLAN ####')
                        if action.push.ethertype != 0x8100:
                            log.error('unhandled-ether-type',
                                      ethertype=action.push.ethertype)

                    elif action.type == SET_FIELD:
                        log.info('#### action.type == SET_FIELD ####')
                        assert (action.set_field.field.oxm_class ==
                                ofp.OFPXMC_OPENFLOW_BASIC)
                        field = action.set_field.field.ofb_field
                        if field.type == VLAN_VID:
                            pass
                        else:
                            log.error('unsupported-action-set-field-type',
                                      field_type=field.type)

                    else:
                        log.error('UNSUPPORTED-ACTION-TYPE',
                                  action_type=action.type)

            else:
                raise Exception('Port should be 1 or 2 by our convention')