Exemple #1
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 ####')
                dn_req = EOAMPayload(body=CablelabsOUI() /
                                     DPoEOpcode_SetRequest())

                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(
                            body=CablelabsOUI() / DPoEOpcode_SetRequest() /
                            AddStaticMacAddress(
                                mac=mcastIp2McastMac('%d.%d.%d.%d' %
                                                     (a, b, c, d))))
                        # send message
                        log.info('ONU-send-proxied-message')
                        self.adapter_agent.send_proxied_message(
                            device.proxy_address, dn_req)

                    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')
Exemple #2
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('########################################')
Exemple #3
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)

        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=RuleClauses['C-VLAN Tag'],
                            fieldinstance=0,
                            operator=RuleOperators['=='],
                            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=RuleClauses['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=RuleClauses['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))
                            # need to convert value in Set to a variable length value
                            ctagStr = struct.pack('>H',
                                                  (field.vlan_vid & 0xfff))

                            up_req /= PortIngressRuleResultSet(
                                fieldcode=RuleClauses['C-VLAN Tag'],
                                value=ctagStr)
                        else:
                            raise NotImplementedError(
                                'unsupported-action-set-field-type={}'.format(
                                    field.type))
                    else:
                        raise NotImplementedError(
                            'unsupported-action-type={}'.format(action.type))

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

                # send message
                action = "Set ONU US Rule"
                rc = []
                yield self._set_req_rsp(device, action, up_req, 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 ####')
                        dn_req /= PortIngressRuleClauseMatchLength02(
                            fieldcode=RuleClauses['C-VLAN Tag'],
                            fieldinstance=0,
                            operator=RuleOperators['=='],
                            match=_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 ####')

                        # TODO - This is not the correct operation for a POP operation.
                        #        This should be a Delete result
                        dn_req /= PortIngressRuleResultReplace(
                            fieldcode=RuleClauses['C-VLAN Tag'])
                        # need to convert value in Set to a variable length value
                        ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff))
                        dn_req /= PortIngressRuleResultSet(
                            fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr)

                    elif action.type == PUSH_VLAN:
                        log.info('#### action.type == PUSH_VLAN ####')
                        if action.push.ethertype != 0x8100:
                            raise NotImplementedError(
                                'unhandled-ether-type={}'.format(
                                    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))

                            # TODO - Currently only support setting the VID in the DS to zero (clearing the VID)
                            if ((field.vlan_vid & 0xfff) == 0):
                                dn_req /= PortIngressRuleResultReplace(
                                    fieldcode=RuleClauses['C-VLAN Tag'])
                                # need to convert value in Set to a variable length value
                                ctagStr = struct.pack('>H',
                                                      (field.vlan_vid & 0xfff))
                                dn_req /= PortIngressRuleResultSet(
                                    fieldcode=RuleClauses['C-VLAN Tag'],
                                    value=ctagStr)
                            else:
                                raise NotImplementedError(
                                    'unsupported-set-vlan-id={}'.format(
                                        field.vlan_vid & 0xfff))
                        else:
                            raise NotImplementedError(
                                'unsupported-action-set-field-type={}'.format(
                                    field.type))
                    else:
                        raise NotImplementedError(
                            'unsupported-action-type={}'.format(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"

                # send message
                rc = []
                yield self._set_req_rsp(device, action, dn_req, 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('########################################')
Exemple #4
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')
Exemple #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)

        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=RuleClauses['C-VLAN Tag'], fieldinstance=0,
                                                                     operator=RuleOperators['=='], 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=RuleClauses['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=RuleClauses['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))
                            # need to convert value in Set to a variable length value
                            ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff))

                            up_req /= PortIngressRuleResultSet(
                                    fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr)
                        else:
                            raise NotImplementedError('unsupported-action-set-field-type={}'.format(field.type))
                    else:
                        raise NotImplementedError('unsupported-action-type={}'.format(action.type))

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

                # send message
                action = "Set ONU US Rule"
                rc = []
                yield self._set_req_rsp(device, action, up_req, 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 ####')
                        dn_req /= PortIngressRuleClauseMatchLength02(fieldcode=RuleClauses['C-VLAN Tag'], fieldinstance=0,
                                                                     operator=RuleOperators['=='], match=_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 ####')

                        # TODO - This is not the correct operation for a POP operation.
                        #        This should be a Delete result
                        dn_req /= PortIngressRuleResultReplace(fieldcode=RuleClauses['C-VLAN Tag'])
                        # need to convert value in Set to a variable length value
                        ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff))
                        dn_req /= PortIngressRuleResultSet(
                                fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr)

                    elif action.type == PUSH_VLAN:
                        log.info('#### action.type == PUSH_VLAN ####')
                        if action.push.ethertype != 0x8100:
                            raise NotImplementedError('unhandled-ether-type={}'.format(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))

                            # TODO - Currently only support setting the VID in the DS to zero (clearing the VID)
                            if ((field.vlan_vid & 0xfff) == 0):
                                dn_req /= PortIngressRuleResultReplace(fieldcode=RuleClauses['C-VLAN Tag'])
                                # need to convert value in Set to a variable length value
                                ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff))
                                dn_req /= PortIngressRuleResultSet(
                                        fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr)
                            else:
                                raise NotImplementedError('unsupported-set-vlan-id={}'.format(field.vlan_vid & 0xfff))
                        else:
                            raise NotImplementedError('unsupported-action-set-field-type={}'.format(field.type))
                    else:
                        raise NotImplementedError('unsupported-action-type={}'.format(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"

                # send message
                rc = []
                yield self._set_req_rsp(device, action, dn_req, 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('########################################')