Exemple #1
0
    def flow_extract_info(self, flow, flow_direction):
        uni_port_no = None
        if flow_direction == "upstream":
            for field in fd.get_ofb_fields(flow):
                if field.type == fd.IN_PORT:
                    uni_port_no = field.port
                    break
        elif flow_direction == "downstream":
            for field in fd.get_ofb_fields(flow):
                if field.type == fd.METADATA:
                    uni_port_no = field.table_metadata & 0xFFFFFFFF
                    break

            if uni_port_no is None:
                for action in fd.get_actions(flow):
                    if action.type == fd.OUTPUT:
                        uni_port_no = action.output.port
                        break

            if uni_port_no is None:
                uni_port_no = fd.get_metadata_from_write_metadata(
                    flow) & 0xFFFFFFFF

        if uni_port_no is None:
            raise ValueError

        pon_intf = self.intf_id_from_uni_port_num(uni_port_no)
        onu_id = self.onu_id_from_uni_port_num(uni_port_no)
        uni_id = self.uni_id_from_port_num(uni_port_no)

        return int(pon_intf), int(onu_id), int(uni_id)
Exemple #2
0
    def _decode_traffic_selector(self):
        """
        Extract EVC related traffic selection settings
        """
        self.in_port = fd.get_in_port(self._flow)

        if self.in_port > OFPP_MAX:
            log.warn('logical-input-ports-not-supported')
            return False

        for field in fd.get_ofb_fields(self._flow):
            if field.type == IN_PORT:
                assert self.in_port == field.port, 'Multiple Input Ports found in flow rule'

                if self._handler.is_nni_port(self.in_port):
                    self._logical_port = self.in_port       # TODO: This should be a lookup

            elif field.type == VLAN_VID:
                # log.info('*** field.type == VLAN_VID', value=field.vlan_vid & 0xfff)
                self.vlan_id = field.vlan_vid & 0xfff
                self._is_multicast = self.vlan_id in self._handler.multicast_vlans

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

            elif field.type == ETH_TYPE:
                # log.info('*** field.type == ETH_TYPE', value=field.eth_type)
                self.eth_type = field.eth_type

            elif field.type == IP_PROTO:
                # log.info('*** field.type == IP_PROTO', value=field.ip_proto)
                self.ip_protocol = field.ip_proto

                if self.ip_protocol not in _supported_ip_protocols:
                    # log.error('Unsupported IP Protocol')
                    return False

            elif field.type == IPV4_DST:
                # log.info('*** field.type == IPV4_DST', value=field.ipv4_dst)
                self.ipv4_dst = field.ipv4_dst

            elif field.type == UDP_DST:
                # log.info('*** field.type == UDP_DST', value=field.udp_dst)
                self.udp_dst = field.udp_dst

            elif field.type == UDP_SRC:
                # log.info('*** field.type == UDP_SRC', value=field.udp_src)
                self.udp_src = field.udp_src

            elif field.type == METADATA:
                # log.info('*** field.type == METADATA', value=field.table_metadata)
                self.inner_vid = field.table_metadata

            else:
                log.warn('unsupported-selection-field', type=field.type)
                self._status_message = 'Unsupported field.type={}'.format(field.type)
                return False

        return True
    def is_eap_enabled(self, intf_id, onu_id, uni_id):
        flows = self.logical_flows_proxy.get('/').items

        for flow in flows:
            eap_flow = False
            eap_intf_id = None
            eap_onu_id = None
            eap_uni_id = None
            for field in fd.get_ofb_fields(flow):
                if field.type == fd.ETH_TYPE:
                    if field.eth_type == EAP_ETH_TYPE:
                        eap_flow = True
                if field.type == fd.IN_PORT:
                    eap_intf_id = self.platform.intf_id_from_uni_port_num(
                        field.port)
                    eap_onu_id = self.platform.onu_id_from_port_num(field.port)
                    eap_uni_id = self.platform.uni_id_from_port_num(field.port)

            if eap_flow:
                self.log.debug('eap flow detected', onu_id=onu_id,
                               uni_id=uni_id, intf_id=intf_id,
                               eap_intf_id=eap_intf_id, eap_onu_id=eap_onu_id,
                               eap_uni_id=eap_uni_id)
            if eap_flow and intf_id == eap_intf_id \
                    and onu_id == eap_onu_id and uni_id == eap_uni_id:
                return True, flow

        return False, None
Exemple #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')
Exemple #5
0
    def get_classifier_info(self, flow):
        classifier_info = {}
        for field in fd.get_ofb_fields(flow):
            if field.type == fd.ETH_TYPE:
                classifier_info[ETH_TYPE] = field.eth_type
            elif field.type == fd.IP_PROTO:
                classifier_info[IP_PROTO] = field.ip_proto
            elif field.type == fd.IN_PORT:
                classifier_info[IN_PORT] = field.port
            elif field.type == fd.VLAN_VID:
                classifier_info[VLAN_VID] = field.vlan_vid & 0xfff
            elif field.type == fd.VLAN_PCP:
                classifier_info[VLAN_PCP] = field.vlan_pcp
            elif field.type == fd.UDP_DST:
                classifier_info[UDP_DST] = field.udp_dst
            elif field.type == fd.UDP_SRC:
                classifier_info[UDP_SRC] = field.udp_src
            elif field.type == fd.IPV4_DST:
                classifier_info[IPV4_DST] = field.ipv4_dst
            elif field.type == fd.IPV4_SRC:
                classifier_info[IPV4_SRC] = field.ipv4_src
            elif field.type == fd.METADATA:
                classifier_info[METADATA] = field.table_metadata
            else:
                self.log.debug('field-type-unhandled field.type={}'.format(
                    field.type))

        return classifier_info
Exemple #6
0
    def find_next_flow(self, flow):
        table_id = fd.get_goto_table_id(flow)
        metadata = 0
        for field in fd.get_ofb_fields(flow):
            if field.type == fd.METADATA:
                metadata = field.table_metadata
        if table_id is None:
            return None
        flows = self.logical_flows_proxy.get('/').items
        next_flows = []
        for f in flows:
            if f.table_id == table_id:
                #FIXME:
                if fd.get_in_port(f) == fd.get_in_port(flow) and \
                        fd.get_out_port(f) == metadata:

                    next_flows.append(f)

        if len(next_flows) == 0:
            self.log.warning('no next flow found, it may be a timing issue',
                             flow=flow,
                             number_of_flows=len(flows))
            reactor.callLater(5, self.add_flow, flow)
            return None

        next_flows.sort(key=lambda f: f.priority, reverse=True)

        return next_flows[0]
    def find_next_flow(self, flow):
        table_id = fd.get_goto_table_id(flow)
        metadata = 0
        # Prior to ONOS 1.13.5, Metadata contained the UNI output port number. In
        # 1.13.5 and later, the lower 32-bits is the output port number and the
        # upper 32-bits is the inner-vid we are looking for. Use just the lower 32
        # bits.  Allows this code to work with pre- and post-1.13.5 ONOS OltPipeline

        for field in fd.get_ofb_fields(flow):
            if field.type == fd.METADATA:
                metadata = field.table_metadata & 0xFFFFFFFF
        if table_id is None:
            return None
        flows = self.logical_flows_proxy.get('/').items
        next_flows = []
        for f in flows:
            if f.table_id == table_id:
                # FIXME
                if fd.get_in_port(f) == fd.get_in_port(flow) and \
                        fd.get_out_port(f) == metadata:

                    next_flows.append(f)

        if len(next_flows) == 0:
            self.log.warning('no next flow found, it may be a timing issue',
                             flow=flow, number_of_flows=len(flows))
            reactor.callLater(5, self.add_flow, flow)
            return None

        next_flows.sort(key=lambda f: f.priority, reverse=True)

        return next_flows[0]
Exemple #8
0
    def _decode_traffic_selector(self):
        """
        Extract EVC related traffic selection settings
        """
        self.in_port = fd.get_in_port(self._flow)

        if self.in_port > OFPP_MAX:
            log.warn('Logical-input-ports-not-supported')
            return False

        for field in fd.get_ofb_fields(self._flow):
            if field.type == IN_PORT:
                pass  # Handled earlier

            elif field.type == VLAN_VID:
                # log.info('*** field.type == VLAN_VID', value=field.vlan_vid & 0xfff)
                self.vlan_id = field.vlan_vid & 0xfff

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

            elif field.type == ETH_TYPE:
                # log.info('*** field.type == ETH_TYPE', value=field.eth_type)
                self.eth_type = field.eth_type

            elif field.type == IP_PROTO:
                # log.info('*** field.type == IP_PROTO', value=field.ip_proto)
                self.ip_protocol = field.ip_proto

                if self.ip_protocol not in _supported_ip_protocols:
                    # log.error('Unsupported IP Protocol')
                    return False

            elif field.type == IPV4_DST:
                # log.info('*** field.type == IPV4_DST', value=field.ipv4_dst)
                self.ipv4_dst = field.ipv4_dst

            elif field.type == UDP_DST:
                # log.info('*** field.type == UDP_DST', value=field.udp_dst)
                self.udp_dst = field.udp_dst

            elif field.type == UDP_SRC:
                # log.info('*** field.type == UDP_SRC', value=field.udp_src)
                self.udp_src = field.udp_src

            elif field.type == METADATA:
                # log.info('*** field.type == METADATA', value=field.table_metadata)
                self.inner_vid = field.table_metadata

            else:
                log.warn('unsupported-selection-field', type=field.type)
                self._status_message = 'Unsupported field.type={}'.format(
                    field.type)
                return False

        return True
Exemple #9
0
    def _decode_traffic_treatment(self):
        out_port = fd.get_out_port(self._flow)

        log.debug('OutPort: {}', out_port)

        for field in fd.get_ofb_fields(self._flow):
            log.debug('Found-OFB-field', field=field)

        for action in fd.get_actions(self._flow):
            log.debug('Found-Action', action=action)

        return True
Exemple #10
0
    def _decode_traffic_treatment(self):
        out_port = fd.get_out_port(self._flow)

        log.debug('OutPort: {}', out_port)

        for field in fd.get_ofb_fields(self._flow):
            log.debug('Found-OFB-field', field=field)

        for action in fd.get_actions(self._flow):
            log.debug('Found-Action', action=action)

        return True
Exemple #11
0
    def _decode_traffic_selector(self):
        """
        Extract EVC related traffic selection settings
        """
        in_port = fd.get_in_port(self._flow)
        assert in_port is not None

        log.debug('InPort: {}', in_port)

        for field in fd.get_ofb_fields(self._flow):
            log.debug('Found-OFB-field', field=field)

        for action in fd.get_actions(self._flow):
            log.debug('Found-Action', action=action)

        return True
Exemple #12
0
    def _decode_traffic_selector(self):
        """
        Extract EVC related traffic selection settings
        """
        in_port = fd.get_in_port(self._flow)
        assert in_port is not None

        log.debug('InPort: {}', in_port)

        for field in fd.get_ofb_fields(self._flow):
            log.debug('Found-OFB-field', field=field)

        for action in fd.get_actions(self._flow):
            log.debug('Found-Action', action=action)

        return True
    def get_subscriber_vlan(self, port):
        self.log.debug('looking from subscriber flow for port', port=port)

        flows = self.logical_flows_proxy.get('/').items
        for flow in flows:
            in_port = fd.get_in_port(flow)
            out_port = fd.get_out_port(flow)
            if in_port == port and \
                self.platform.intf_id_to_port_type_name(out_port) \
                    == Port.ETHERNET_NNI:
                fields = fd.get_ofb_fields(flow)
                self.log.debug('subscriber flow found', fields=fields)
                for field in fields:
                    if field.type == OFPXMT_OFB_VLAN_VID:
                        self.log.debug('subscriber vlan found',
                                       vlan_id=field.vlan_vid)
                        return field.vlan_vid & 0x0fff
        self.log.debug('No subscriber flow found', port=port)
        return None
Exemple #14
0
    def update_flow_table(self, device, flows):
        import voltha.core.flow_decomposer as fd
        from voltha.protos.openflow_13_pb2 import OFPP_IN_PORT, OFPP_TABLE, OFPP_NORMAL, OFPP_FLOOD, OFPP_ALL
        from voltha.protos.openflow_13_pb2 import OFPP_CONTROLLER, OFPP_LOCAL, OFPP_ANY, OFPP_MAX
        #
        # We need to proxy through the OLT to get to the ONU
        # Configuration from here should be using OMCI
        #
        log.info('update_flow_table', device_id=device.id, flows=flows)

        for flow in flows:
            # TODO: Do we get duplicates here (ie all flows re-pushed on each individual flow add?)

            in_port = fd.get_in_port(flow)
            out_port = fd.get_out_port(flow)
            self.log.debug('InPort: {}, OutPort: {}'.format(in_port, out_port))

            for field in fd.get_ofb_fields(flow):
                self.log.debug('Found OFB field', field=field)

            for action in fd.get_actions(flow):
                log.debug('Found Action', action=action)

        raise NotImplementedError()
    def update_flow_table(self, device, flows):
        self.log.debug('function-entry', device=device, flows=flows)
        #
        # We need to proxy through the OLT to get to the ONU
        # Configuration from here should be using OMCI
        #
        #self.log.info('bulk-flow-update', device_id=device.id, flows=flows)

        def is_downstream(port):
            return port == self._pon_port_number

        def is_upstream(port):
            return not is_downstream(port)

        for flow in flows:
            _type = None
            _port = None
            _vlan_vid = None
            _udp_dst = None
            _udp_src = None
            _ipv4_dst = None
            _ipv4_src = None
            _metadata = None
            _output = None
            _push_tpid = None
            _field = None
            _set_vlan_vid = None
            self.log.debug('bulk-flow-update', device_id=device.id, flow=flow)
            try:
                _in_port = fd.get_in_port(flow)
                assert _in_port is not None

                if is_downstream(_in_port):
                    self.log.debug('downstream-flow')
                elif is_upstream(_in_port):
                    self.log.debug('upstream-flow')
                else:
                    raise Exception('port should be 1 or 2 by our convention')

                _out_port = fd.get_out_port(flow)  # may be None
                self.log.debug('out-port', out_port=_out_port)

                for field in fd.get_ofb_fields(flow):
                    if field.type == fd.ETH_TYPE:
                        _type = field.eth_type
                        self.log.debug('field-type-eth-type',
                                      eth_type=_type)

                    elif field.type == fd.IP_PROTO:
                        _proto = field.ip_proto
                        self.log.debug('field-type-ip-proto',
                                      ip_proto=_proto)

                    elif field.type == fd.IN_PORT:
                        _port = field.port
                        self.log.debug('field-type-in-port',
                                      in_port=_port)

                    elif field.type == fd.VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        self.log.debug('field-type-vlan-vid',
                                      vlan=_vlan_vid)

                    elif field.type == fd.VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        self.log.debug('field-type-vlan-pcp',
                                      pcp=_vlan_pcp)

                    elif field.type == fd.UDP_DST:
                        _udp_dst = field.udp_dst
                        self.log.debug('field-type-udp-dst',
                                      udp_dst=_udp_dst)

                    elif field.type == fd.UDP_SRC:
                        _udp_src = field.udp_src
                        self.log.debug('field-type-udp-src',
                                      udp_src=_udp_src)

                    elif field.type == fd.IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        self.log.debug('field-type-ipv4-dst',
                                      ipv4_dst=_ipv4_dst)

                    elif field.type == fd.IPV4_SRC:
                        _ipv4_src = field.ipv4_src
                        self.log.debug('field-type-ipv4-src',
                                      ipv4_dst=_ipv4_src)

                    elif field.type == fd.METADATA:
                        _metadata = field.table_metadata
                        self.log.debug('field-type-metadata',
                                      metadata=_metadata)

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

                for action in fd.get_actions(flow):

                    if action.type == fd.OUTPUT:
                        _output = action.output.port
                        self.log.debug('action-type-output',
                                      output=_output, in_port=_in_port)

                    elif action.type == fd.POP_VLAN:
                        self.log.debug('action-type-pop-vlan',
                                      in_port=_in_port)

                    elif action.type == fd.PUSH_VLAN:
                        _push_tpid = action.push.ethertype
                        self.log.debug('action-type-push-vlan',
                                 push_tpid=_push_tpid, in_port=_in_port)
                        if action.push.ethertype != 0x8100:
                            self.log.error('unhandled-tpid',
                                           ethertype=action.push.ethertype)

                    elif action.type == fd.SET_FIELD:
                        _field = action.set_field.field.ofb_field
                        assert (action.set_field.field.oxm_class ==
                                OFPXMC_OPENFLOW_BASIC)
                        self.log.debug('action-type-set-field',
                                      field=_field, in_port=_in_port)
                        if _field.type == fd.VLAN_VID:
                            _set_vlan_vid = _field.vlan_vid & 0xfff
                            self.log.debug('set-field-type-valn-vid', _set_vlan_vid)
                        else:
                            self.log.error('unsupported-action-set-field-type',
                                           field_type=_field.type)
                    else:
                        self.log.error('unsupported-action-type',
                                  action_type=action.type, in_port=_in_port)

                #
                # All flows created from ONU adapter should be OMCI based
                #
                if _vlan_vid == 0 and _set_vlan_vid != None and _set_vlan_vid != 0:

                    # TODO: find a better place for all of this
                    # TODO: make this a member of the onu gem port or the uni port
                    _mac_bridge_service_profile_entity_id = 0x201
                    _mac_bridge_port_ani_entity_id = 0x2102   # TODO: can we just use the entity id from the anis list?

                    # Delete bridge ani side vlan filter
                    msg = VlanTaggingFilterDataFrame(_mac_bridge_port_ani_entity_id)
                    frame = msg.delete()
                    self.log.debug('openomci-msg', msg=msg)
                    results = yield self.omci_cc.send(frame)
                    self.check_status_and_state(results, 'flow-delete-vlan-tagging-filter-data')

                    # Re-Create bridge ani side vlan filter
                    msg = VlanTaggingFilterDataFrame(
                        _mac_bridge_port_ani_entity_id,  # Entity ID
                        vlan_tcis=[_set_vlan_vid],        # VLAN IDs
                        forward_operation=0x10
                    )
                    frame = msg.create()
                    self.log.debug('openomci-msg', msg=msg)
                    results = yield self.omci_cc.send(frame)
                    self.check_status_and_state(results, 'flow-create-vlan-tagging-filter-data')

                    # Update uni side extended vlan filter
                    # filter for untagged
                    # probably for eapol
                    # TODO: magic 0x1000 / 4096?
                    # TODO: lots of magic
                    attributes = dict(
                        received_frame_vlan_tagging_operation_table=
                        VlanTaggingOperation(
                            filter_outer_priority=15,
                            filter_outer_vid=4096,
                            filter_outer_tpid_de=0,

                            filter_inner_priority=15,
                            filter_inner_vid=4096,
                            filter_inner_tpid_de=0,
                            filter_ether_type=0,

                            treatment_tags_to_remove=0,
                            treatment_outer_priority=15,
                            treatment_outer_vid=0,
                            treatment_outer_tpid_de=0,

                            treatment_inner_priority=0,
                            treatment_inner_vid=_set_vlan_vid,
                            treatment_inner_tpid_de=4
                        )
                    )
                    msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
                        _mac_bridge_service_profile_entity_id,  # Bridge Entity ID
                        attributes=attributes  # See above
                    )
                    frame = msg.set()
                    self.log.debug('openomci-msg', msg=msg)
                    results = yield self.omci_cc.send(frame)
                    self.check_status_and_state(results,
                                                'flow-set-ext-vlan-tagging-op-config-data-untagged')

                    # Update uni side extended vlan filter
                    # filter for vlan 0
                    # TODO: lots of magic
                    attributes = dict(
                        received_frame_vlan_tagging_operation_table=
                        VlanTaggingOperation(
                            filter_outer_priority=15,  # This entry is not a double-tag rule
                            filter_outer_vid=4096,  # Do not filter on the outer VID value
                            filter_outer_tpid_de=0,  # Do not filter on the outer TPID field

                            filter_inner_priority=8,  # Filter on inner vlan
                            filter_inner_vid=0x0,  # Look for vlan 0
                            filter_inner_tpid_de=0,  # Do not filter on inner TPID field
                            filter_ether_type=0,  # Do not filter on EtherType

                            treatment_tags_to_remove=1,
                            treatment_outer_priority=15,
                            treatment_outer_vid=0,
                            treatment_outer_tpid_de=0,

                            treatment_inner_priority=8,  # Add an inner tag and insert this value as the priority
                            treatment_inner_vid=_set_vlan_vid,  # use this value as the VID in the inner VLAN tag
                            treatment_inner_tpid_de=4,  # set TPID
                        )
                    )
                    msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
                        _mac_bridge_service_profile_entity_id,  # Bridge Entity ID
                        attributes=attributes  # See above
                    )
                    frame = msg.set()
                    self.log.debug('openomci-msg', msg=msg)
                    results = yield self.omci_cc.send(frame)
                    self.check_status_and_state(results,
                                                'flow-set-ext-vlan-tagging-op-config-data-zero-tagged')

            except Exception as e:
                self.log.exception('failed-to-install-flow', e=e, flow=flow)
Exemple #16
0
    def _clear_flow_id_from_rm(self, flow, flow_id, flow_direction):
        uni_port_no = None
        flow_category = HSIA_FLOW  # default
        child_device_id = None
        if flow_direction == UPSTREAM:
            for field in fd.get_ofb_fields(flow):
                if field.type == fd.IN_PORT:
                    is_uni, child_device_id = self._is_uni_port(field.port)
                    if is_uni:
                        uni_port_no = field.port
                elif field.type == fd.IP_PROTO:
                    if field.ip_proto == IGMP_PROTO:
                        flow_category = IGMP_FLOW
                elif field.type == fd.ETH_TYPE:
                    if field.eth_type == EAP_ETH_TYPE:
                        flow_category = EAPOL_PRIMARY_FLOW
                    elif field.eth_type == LLDP_ETH_TYPE:
                        flow_category = LLDP_FLOW

        elif flow_direction == DOWNSTREAM:
            for field in fd.get_ofb_fields(flow):
                if field.type == fd.METADATA:
                    uni_port = field.table_metadata & 0xFFFFFFFF
                    is_uni, child_device_id = self._is_uni_port(uni_port)
                    if is_uni:
                        uni_port_no = field.port

            if uni_port_no is None:
                for action in fd.get_actions(flow):
                    if action.type == fd.OUTPUT:
                        is_uni, child_device_id = \
                            self._is_uni_port(action.output.port)
                        if is_uni:
                            uni_port_no = action.output.port

        if flow_category and child_device_id:
            child_device = self.adapter_agent.get_device(child_device_id)
            pon_intf = child_device.proxy_address.channel_id
            onu_id = child_device.proxy_address.onu_id
            flows = self.resource_mgr.get_flow_id_info(pon_intf, onu_id,
                                                       flow_id)
            assert (isinstance(flows, list))
            self.log.debug("retrieved-flows", flows=flows)
            for idx in range(len(flows)):
                if flow_direction == flows[idx]['flow_type']:
                    flows.pop(idx)
                    self.update_flow_info_to_kv_store(pon_intf, onu_id,
                                                      flow_id, flows)
                    if len(flows) > 0:
                        # There are still flows referencing the same flow_id.
                        # So the flow should not be freed yet.
                        # For ex: Case of HSIA where same flow is shared
                        # between DS and US.
                        return

            self.resource_mgr.free_flow_id(pon_intf, onu_id, flow_id)
        else:
            self.log.error("invalid-info",
                           uni_port_no=uni_port_no,
                           flow_category=flow_category,
                           child_device_id=child_device_id)
Exemple #17
0
    def update_flow_table(self, device, flows):
        #
        # We need to proxy through the OLT to get to the ONU
        # Configuration from here should be using OMCI
        #
        # self.log.info('bulk-flow-update', device_id=device.id, flows=flows)

        import voltha.core.flow_decomposer as fd
        from voltha.protos.openflow_13_pb2 import OFPXMC_OPENFLOW_BASIC, ofp_port

        def is_downstream(port):
            return port == 100  # Need a better way

        def is_upstream(port):
            return not is_downstream(port)

        omci = self._omci

        for flow in flows:
            _type = None
            _port = None
            _vlan_vid = None
            _udp_dst = None
            _udp_src = None
            _ipv4_dst = None
            _ipv4_src = None
            _metadata = None
            _output = None
            _push_tpid = None
            _field = None
            _set_vlan_vid = None
            self.log.info('bulk-flow-update', device_id=device.id, flow=flow)
            try:
                _in_port = fd.get_in_port(flow)
                assert _in_port is not None

                if is_downstream(_in_port):
                    self.log.info('downstream-flow')
                elif is_upstream(_in_port):
                    self.log.info('upstream-flow')
                else:
                    raise Exception('port should be 1 or 2 by our convention')

                _out_port = fd.get_out_port(flow)  # may be None
                self.log.info('out-port', out_port=_out_port)

                for field in fd.get_ofb_fields(flow):
                    if field.type == fd.ETH_TYPE:
                        _type = field.eth_type
                        self.log.info('field-type-eth-type', eth_type=_type)

                    elif field.type == fd.IP_PROTO:
                        _proto = field.ip_proto
                        self.log.info('field-type-ip-proto', ip_proto=_proto)

                    elif field.type == fd.IN_PORT:
                        _port = field.port
                        self.log.info('field-type-in-port', in_port=_port)

                    elif field.type == fd.VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        self.log.info('field-type-vlan-vid', vlan=_vlan_vid)

                    elif field.type == fd.VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        self.log.info('field-type-vlan-pcp', pcp=_vlan_pcp)

                    elif field.type == fd.UDP_DST:
                        _udp_dst = field.udp_dst
                        self.log.info('field-type-udp-dst', udp_dst=_udp_dst)

                    elif field.type == fd.UDP_SRC:
                        _udp_src = field.udp_src
                        self.log.info('field-type-udp-src', udp_src=_udp_src)

                    elif field.type == fd.IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        self.log.info('field-type-ipv4-dst',
                                      ipv4_dst=_ipv4_dst)

                    elif field.type == fd.IPV4_SRC:
                        _ipv4_src = field.ipv4_src
                        self.log.info('field-type-ipv4-src',
                                      ipv4_dst=_ipv4_src)

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

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

                for action in fd.get_actions(flow):

                    if action.type == fd.OUTPUT:
                        _output = action.output.port
                        self.log.info('action-type-output',
                                      output=_output,
                                      in_port=_in_port)

                    elif action.type == fd.POP_VLAN:
                        self.log.info('action-type-pop-vlan', in_port=_in_port)

                    elif action.type == fd.PUSH_VLAN:
                        _push_tpid = action.push.ethertype
                        log.info('action-type-push-vlan',
                                 push_tpid=_push_tpid,
                                 in_port=_in_port)
                        if action.push.ethertype != 0x8100:
                            self.log.error('unhandled-tpid',
                                           ethertype=action.push.ethertype)

                    elif action.type == fd.SET_FIELD:
                        _field = action.set_field.field.ofb_field
                        assert (action.set_field.field.oxm_class ==
                                OFPXMC_OPENFLOW_BASIC)
                        self.log.info('action-type-set-field',
                                      field=_field,
                                      in_port=_in_port)
                        if _field.type == fd.VLAN_VID:
                            _set_vlan_vid = _field.vlan_vid & 0xfff
                            self.log.info('set-field-type-valn-vid',
                                          _set_vlan_vid)
                        else:
                            self.log.error('unsupported-action-set-field-type',
                                           field_type=_field.type)
                    else:
                        log.error('unsupported-action-type',
                                  action_type=action.type,
                                  in_port=_in_port)

                #
                # All flows created from ONU adapter should be OMCI based
                #
                if _vlan_vid == 0 and _set_vlan_vid != None and _set_vlan_vid != 0:
                    # allow priority tagged packets
                    # Set AR - ExtendedVlanTaggingOperationConfigData
                    #          514 - RxVlanTaggingOperationTable - add VLAN <cvid> to priority tagged pkts - c-vid

                    results = yield omci.send_delete_vlan_tagging_filter_data(
                        0x2102)

                    # self.send_set_vlan_tagging_filter_data(0x2102, _set_vlan_vid)
                    results = yield omci.send_create_vlan_tagging_filter_data(
                        0x2102, _set_vlan_vid)

                    results = yield omci.send_set_extended_vlan_tagging_operation_vlan_configuration_data_untagged(
                        0x202, 0x1000, _set_vlan_vid)

                    results = yield omci.send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(
                        0x202, 8, 0, 0, 1, 8, _set_vlan_vid)

                    # Set AR - ExtendedVlanTaggingOperationConfigData
                    #          514 - RxVlanTaggingOperationTable - add VLAN <cvid> to priority tagged pkts - c-vid
                    '''
                    results = yield omci.send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(0x205, 8, 0, 0,
                                                   
                    '''

            except Exception as e:
                log.exception('failed-to-install-flow', e=e, flow=flow)
Exemple #18
0
    def add_flow(self, flow):
        self.log.debug('add flow', flow=flow)
        classifier_info = dict()
        action_info = dict()

        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])
            elif field.type == fd.IN_PORT:
                classifier_info[IN_PORT] = field.port
                self.log.debug('field-type-in-port',
                               in_port=classifier_info[IN_PORT])
            elif field.type == fd.VLAN_VID:
                classifier_info[VLAN_VID] = field.vlan_vid & 0xfff
                self.log.debug('field-type-vlan-vid',
                               vlan=classifier_info[VLAN_VID])
            elif field.type == fd.VLAN_PCP:
                classifier_info[VLAN_PCP] = field.vlan_pcp
                self.log.debug('field-type-vlan-pcp',
                               pcp=classifier_info[VLAN_PCP])
            elif field.type == fd.UDP_DST:
                classifier_info[UDP_DST] = field.udp_dst
                self.log.debug('field-type-udp-dst',
                               udp_dst=classifier_info[UDP_DST])
            elif field.type == fd.UDP_SRC:
                classifier_info[UDP_SRC] = field.udp_src
                self.log.debug('field-type-udp-src',
                               udp_src=classifier_info[UDP_SRC])
            elif field.type == fd.IPV4_DST:
                classifier_info[IPV4_DST] = field.ipv4_dst
                self.log.debug('field-type-ipv4-dst',
                               ipv4_dst=classifier_info[IPV4_DST])
            elif field.type == fd.IPV4_SRC:
                classifier_info[IPV4_SRC] = field.ipv4_src
                self.log.debug('field-type-ipv4-src',
                               ipv4_dst=classifier_info[IPV4_SRC])
            elif field.type == fd.METADATA:
                classifier_info[METADATA] = field.table_metadata
                self.log.debug('field-type-metadata',
                               metadata=classifier_info[METADATA])
            else:
                raise NotImplementedError('field.type={}'.format(
                    field.type))

        for action in fd.get_actions(flow):
            if action.type == fd.OUTPUT:
                action_info[OUTPUT] = action.output.port
                self.log.debug('action-type-output',
                               output=action_info[OUTPUT],
                               in_port=classifier_info[IN_PORT])
            elif action.type == fd.POP_VLAN:
                if fd.get_goto_table_id(flow) is None:
                    self.log.debug('being taken care of by ONU', flow=flow)
                    return
                action_info[POP_VLAN] = True
                self.log.debug('action-type-pop-vlan',
                               in_port=classifier_info[IN_PORT])
            elif action.type == fd.PUSH_VLAN:
                action_info[PUSH_VLAN] = True
                action_info[TPID] = action.push.ethertype
                self.log.debug('action-type-push-vlan',
                               push_tpid=action_info[TPID],
                               in_port=classifier_info[IN_PORT])
                if action.push.ethertype != 0x8100:
                    self.log.error('unhandled-tpid',
                                   ethertype=action.push.ethertype)
            elif action.type == fd.SET_FIELD:
                # action_info['action_type'] = 'set_field'
                _field = action.set_field.field.ofb_field
                assert (action.set_field.field.oxm_class ==
                        OFPXMC_OPENFLOW_BASIC)
                self.log.debug('action-type-set-field',
                               field=_field, in_port=classifier_info[IN_PORT])
                if _field.type == fd.VLAN_VID:
                    self.log.debug('set-field-type-vlan-vid',
                                   vlan_vid=_field.vlan_vid & 0xfff)
                    action_info[VLAN_VID] = (_field.vlan_vid & 0xfff)
                else:
                    self.log.error('unsupported-action-set-field-type',
                                   field_type=_field.type)
            else:
                self.log.error('unsupported-action-type',
                               action_type=action.type,
                               in_port=classifier_info[IN_PORT])

        if fd.get_goto_table_id(flow) is not None \
                and POP_VLAN not in action_info:
            self.log.debug('being taken care of by ONU', flow=flow)
            return

        if OUTPUT not in action_info and METADATA in classifier_info:
            # find flow in the next table
            next_flow = self.find_next_flow(flow)
            if next_flow is None:
                return
            action_info[OUTPUT] = fd.get_out_port(next_flow)
            for field in fd.get_ofb_fields(next_flow):
                if field.type == fd.VLAN_VID:
                    classifier_info[METADATA] = field.vlan_vid & 0xfff

        self.log.debug('flow-ports',
                       classifier_inport=classifier_info[IN_PORT],
                       action_output=action_info[OUTPUT])
        (port_no, intf_id, onu_id, uni_id) \
            = self.platform.extract_access_from_flow(
            classifier_info[IN_PORT], action_info[OUTPUT])

        # LLDP flow has nothing to do with any particular subscriber.
        # So, lets not care about the Tech-profile, meters etc.
        # Just add the flow and return.
        if ETH_TYPE in classifier_info and \
                classifier_info[ETH_TYPE] == LLDP_ETH_TYPE:
            self.log.debug('lldp flow add')
            self.add_lldp_flow(flow, port_no)
            return

        if ETH_TYPE in classifier_info and \
                classifier_info[ETH_TYPE] == IPV4_ETH_TYPE and \
                IP_PROTO in classifier_info and \
                classifier_info[IP_PROTO] == 2:
            self.log.debug('igmp flow add ignored, not implemented yet')
            return

        if IP_PROTO in classifier_info and \
                classifier_info[IP_PROTO] == 17 and \
                UDP_SRC in classifier_info and \
                classifier_info[UDP_SRC] == 67:
            self.log.debug('ignore trap-dhcp-from-nni-flow')
            # self.add_dhcp_trap_nni(flow, classifier_info, port_no,
            #                       network_intf_id=0)
            return

        self.divide_and_add_flow(intf_id, onu_id, uni_id, port_no,
                                 classifier_info, action_info, flow)
Exemple #19
0
    def add_flow(self, flow, is_down_stream):
        self.log.debug('add flow', flow=flow, is_down_stream=is_down_stream)
        classifier_info = dict()
        action_info = dict()

        in_port = fd.get_in_port(flow)
        assert in_port is not None

        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'])
            elif field.type == fd.IN_PORT:
                classifier_info['in_port'] = field.port
                self.log.debug('field-type-in-port',
                               in_port=classifier_info['in_port'])
            elif field.type == fd.VLAN_VID:
                classifier_info['vlan_vid'] = field.vlan_vid & 0xfff
                self.log.debug('field-type-vlan-vid',
                               vlan=classifier_info['vlan_vid'])
            elif field.type == fd.VLAN_PCP:
                classifier_info['vlan_pcp'] = field.vlan_pcp
                self.log.debug('field-type-vlan-pcp',
                               pcp=classifier_info['vlan_pcp'])
            elif field.type == fd.UDP_DST:
                classifier_info['udp_dst'] = field.udp_dst
                self.log.debug('field-type-udp-dst',
                               udp_dst=classifier_info['udp_dst'])
            elif field.type == fd.UDP_SRC:
                classifier_info['udp_src'] = field.udp_src
                self.log.debug('field-type-udp-src',
                               udp_src=classifier_info['udp_src'])
            elif field.type == fd.IPV4_DST:
                classifier_info['ipv4_dst'] = field.ipv4_dst
                self.log.debug('field-type-ipv4-dst',
                               ipv4_dst=classifier_info['ipv4_dst'])
            elif field.type == fd.IPV4_SRC:
                classifier_info['ipv4_src'] = field.ipv4_src
                self.log.debug('field-type-ipv4-src',
                               ipv4_dst=classifier_info['ipv4_src'])
            elif field.type == fd.METADATA:
                classifier_info['metadata'] = field.table_metadata
                self.log.debug('field-type-metadata',
                               metadata=classifier_info['metadata'])
            else:
                raise NotImplementedError('field.type={}'.format(field.type))

        for action in fd.get_actions(flow):
            if action.type == fd.OUTPUT:
                action_info['output'] = action.output.port
                self.log.debug('action-type-output',
                               output=action_info['output'],
                               in_port=classifier_info['in_port'])
            elif action.type == fd.POP_VLAN:
                action_info['pop_vlan'] = True
                self.log.debug('action-type-pop-vlan', in_port=in_port)
            elif action.type == fd.PUSH_VLAN:
                action_info['push_vlan'] = True
                action_info['tpid'] = action.push.ethertype
                self.log.debug('action-type-push-vlan',
                               push_tpid=action_info['tpid'],
                               in_port=in_port)
                if action.push.ethertype != 0x8100:
                    self.log.error('unhandled-tpid',
                                   ethertype=action.push.ethertype)
            elif action.type == fd.SET_FIELD:
                # action_info['action_type'] = 'set_field'
                _field = action.set_field.field.ofb_field
                assert (
                    action.set_field.field.oxm_class == OFPXMC_OPENFLOW_BASIC)
                self.log.debug('action-type-set-field',
                               field=_field,
                               in_port=in_port)
                if _field.type == fd.VLAN_VID:
                    self.log.debug('set-field-type-vlan-vid',
                                   vlan_vid=_field.vlan_vid & 0xfff)
                    action_info['vlan_vid'] = (_field.vlan_vid & 0xfff)
                else:
                    self.log.error('unsupported-action-set-field-type',
                                   field_type=_field.type)
            else:
                self.log.error('unsupported-action-type',
                               action_type=action.type,
                               in_port=in_port)

        # FIXME - Why ignore downstream flows?
        if is_down_stream is False:
            intf_id = platform.intf_id_from_uni_port_num(
                classifier_info['in_port'])
            onu_id = platform.onu_id_from_port_num(classifier_info['in_port'])
            self.divide_and_add_flow(intf_id, onu_id, classifier_info,
                                     action_info)
Exemple #20
0
 def get_vlan(self, flow):
     for field in fd.get_ofb_fields(flow):
         if field.type == fd.VLAN_VID:
             return field.vlan_vid
     return None
Exemple #21
0
    def update_flow_table(self, flows):
        device = self.adapter_agent.get_device(self.device_id)
        self.log.info('update flow table', flows=flows)

        for flow in flows:
            self.log.info('flow-details', device_id=self.device_id, flow=flow)
            classifier_info = dict()
            action_info = dict()
            is_down_stream = None
            _in_port = None
            try:
                _in_port = fd.get_in_port(flow)
                assert _in_port is not None
                # Right now there is only one NNI port. Get the NNI PORT and compare
                # with IN_PUT port number. Need to find better way.
                ports = self.adapter_agent.get_ports(device.id, Port.ETHERNET_NNI)

                for port in ports:
                    if (port.port_no == _in_port):
                        self.log.info('downstream-flow')
                        is_down_stream = True
                        break
                if is_down_stream is None:
                    is_down_stream = False
                    self.log.info('upstream-flow')

                for field in fd.get_ofb_fields(flow):

                    if field.type == fd.ETH_TYPE:
                        classifier_info['eth_type'] = field.eth_type
                        self.log.info('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.info('field-type-ip-proto',
                                ip_proto=classifier_info['ip_proto'])

                    elif field.type == fd.IN_PORT:
                        classifier_info['in_port'] = field.port
                        self.log.info('field-type-in-port',
                                in_port=classifier_info['in_port'])

                    elif field.type == fd.VLAN_VID:
                        classifier_info['vlan_vid'] = field.vlan_vid & 0xfff
                        self.log.info('field-type-vlan-vid',
                                vlan=classifier_info['vlan_vid'])

                    elif field.type == fd.VLAN_PCP:
                        classifier_info['vlan_pcp'] = field.vlan_pcp
                        self.log.info('field-type-vlan-pcp',
                                pcp=classifier_info['vlan_pcp'])

                    elif field.type == fd.UDP_DST:
                        classifier_info['udp_dst'] = field.udp_dst
                        self.log.info('field-type-udp-dst',
                                udp_dst=classifier_info['udp_dst'])

                    elif field.type == fd.UDP_SRC:
                        classifier_info['udp_src'] = field.udp_src
                        self.log.info('field-type-udp-src',
                                udp_src=classifier_info['udp_src'])

                    elif field.type == fd.IPV4_DST:
                        classifier_info['ipv4_dst'] = field.ipv4_dst
                        self.log.info('field-type-ipv4-dst',
                                ipv4_dst=classifier_info['ipv4_dst'])

                    elif field.type == fd.IPV4_SRC:
                        classifier_info['ipv4_src'] = field.ipv4_src
                        self.log.info('field-type-ipv4-src',
                                ipv4_dst=classifier_info['ipv4_src'])

                    elif field.type == fd.METADATA:
                        classifier_info['metadata'] = field.table_metadata
                        self.log.info('field-type-metadata',
                                metadata=classifier_info['metadata'])

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

                for action in fd.get_actions(flow):

                    if action.type == fd.OUTPUT:
                        action_info['output'] = action.output.port
                        self.log.info('action-type-output',
                                output=action_info['output'],
                                in_port=classifier_info['in_port'])

                    elif action.type == fd.POP_VLAN:
                        action_info['pop_vlan'] = True
                        self.log.info('action-type-pop-vlan', in_port=_in_port)

                    elif action.type == fd.PUSH_VLAN:
                        action_info['push_vlan'] = True
                        action_info['tpid'] = action.push.ethertype
                        self.log.info('action-type-push-vlan',
                                push_tpid=action_info['tpid'], in_port=_in_port)
                        if action.push.ethertype != 0x8100:
                            self.log.error('unhandled-tpid',
                                   ethertype=action.push.ethertype)

                    elif action.type == fd.SET_FIELD:
                        # action_info['action_type'] = 'set_field'
                        _field = action.set_field.field.ofb_field
                        assert (action.set_field.field.oxm_class ==
                                OFPXMC_OPENFLOW_BASIC)
                        self.log.info('action-type-set-field',
                                field=_field, in_port=_in_port)
                        if _field.type == fd.VLAN_VID:
                            self.log.info('set-field-type-vlan-vid',
                                    vlan_vid=_field.vlan_vid & 0xfff)
                            action_info['vlan_vid'] = (_field.vlan_vid & 0xfff)
                        else:
                            self.log.error('unsupported-action-set-field-type',
                                    field_type=_field.type)
                    else:
                        self.log.error('unsupported-action-type',
                                action_type=action.type, in_port=_in_port)

                # FIXME - Why ignore downstream flows?
                if is_down_stream is False:
                    intf_id = self.intf_id_from_port_num(classifier_info['in_port'])
                    onu_id = self.onu_id_from_port_num(classifier_info['in_port'])
                    self.divide_and_add_flow(intf_id, onu_id, classifier_info, action_info)
            except Exception as e:
                self.log.exception('failed-to-install-flow', e=e, flow=flow)
    def update_flow_table(self, device, flows):
        #
        # We need to proxy through the OLT to get to the ONU
        # Configuration from here should be using OMCI
        #
        # self.log.info('bulk-flow-update', device_id=device.id, flows=flows)

        import voltha.core.flow_decomposer as fd
        from voltha.protos.openflow_13_pb2 import OFPXMC_OPENFLOW_BASIC, ofp_port

        def is_downstream(port):
            return port == 100  # Need a better way

        def is_upstream(port):
            return not is_downstream(port)

        omci = self._omci

        for flow in flows:
            _type = None
            _port = None
            _vlan_vid = None
            _udp_dst = None
            _udp_src = None
            _ipv4_dst = None
            _ipv4_src = None
            _metadata = None
            _output = None
            _push_tpid = None
            _field = None
            _set_vlan_vid = None
            self.log.info('bulk-flow-update', device_id=device.id, flow=flow)
            try:
                _in_port = fd.get_in_port(flow)
                assert _in_port is not None

                if is_downstream(_in_port):
                    self.log.info('downstream-flow')
                elif is_upstream(_in_port):
                    self.log.info('upstream-flow')
                else:
                    raise Exception('port should be 1 or 2 by our convention')

                _out_port = fd.get_out_port(flow)  # may be None
                self.log.info('out-port', out_port=_out_port)

                for field in fd.get_ofb_fields(flow):
                    if field.type == fd.ETH_TYPE:
                        _type = field.eth_type
                        self.log.info('field-type-eth-type',
                                      eth_type=_type)

                    elif field.type == fd.IP_PROTO:
                        _proto = field.ip_proto
                        self.log.info('field-type-ip-proto',
                                      ip_proto=_proto)

                    elif field.type == fd.IN_PORT:
                        _port = field.port
                        self.log.info('field-type-in-port',
                                      in_port=_port)

                    elif field.type == fd.VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        self.log.info('field-type-vlan-vid',
                                      vlan=_vlan_vid)

                    elif field.type == fd.VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        self.log.info('field-type-vlan-pcp',
                                      pcp=_vlan_pcp)

                    elif field.type == fd.UDP_DST:
                        _udp_dst = field.udp_dst
                        self.log.info('field-type-udp-dst',
                                      udp_dst=_udp_dst)

                    elif field.type == fd.UDP_SRC:
                        _udp_src = field.udp_src
                        self.log.info('field-type-udp-src',
                                      udp_src=_udp_src)

                    elif field.type == fd.IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        self.log.info('field-type-ipv4-dst',
                                      ipv4_dst=_ipv4_dst)

                    elif field.type == fd.IPV4_SRC:
                        _ipv4_src = field.ipv4_src
                        self.log.info('field-type-ipv4-src',
                                      ipv4_dst=_ipv4_src)

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

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

                for action in fd.get_actions(flow):

                    if action.type == fd.OUTPUT:
                        _output = action.output.port
                        self.log.info('action-type-output',
                                      output=_output, in_port=_in_port)

                    elif action.type == fd.POP_VLAN:
                        self.log.info('action-type-pop-vlan',
                                      in_port=_in_port)

                    elif action.type == fd.PUSH_VLAN:
                        _push_tpid = action.push.ethertype
                        log.info('action-type-push-vlan',
                                 push_tpid=_push_tpid, in_port=_in_port)
                        if action.push.ethertype != 0x8100:
                            self.log.error('unhandled-tpid',
                                           ethertype=action.push.ethertype)

                    elif action.type == fd.SET_FIELD:
                        _field = action.set_field.field.ofb_field
                        assert (action.set_field.field.oxm_class ==
                                OFPXMC_OPENFLOW_BASIC)
                        self.log.info('action-type-set-field',
                                      field=_field, in_port=_in_port)
                        if _field.type == fd.VLAN_VID:
                            _set_vlan_vid = _field.vlan_vid & 0xfff
                            self.log.info('set-field-type-valn-vid', _set_vlan_vid)
                        else:
                            self.log.error('unsupported-action-set-field-type',
                                           field_type=_field.type)
                    else:
                        log.error('unsupported-action-type',
                                  action_type=action.type, in_port=_in_port)

                #
                # All flows created from ONU adapter should be OMCI based
                #
                if _vlan_vid == 0 and _set_vlan_vid != None and _set_vlan_vid != 0:
                    # allow priority tagged packets
                    # Set AR - ExtendedVlanTaggingOperationConfigData
                    #          514 - RxVlanTaggingOperationTable - add VLAN <cvid> to priority tagged pkts - c-vid

                    results = yield omci.send_delete_vlan_tagging_filter_data(0x2102)

                    # self.send_set_vlan_tagging_filter_data(0x2102, _set_vlan_vid)
                    results = yield omci.send_create_vlan_tagging_filter_data(
                                        0x2102,
                                        _set_vlan_vid)

                    results = yield omci.send_set_extended_vlan_tagging_operation_vlan_configuration_data_untagged(
                                        0x202,
                                        0x1000,
                                        _set_vlan_vid)

                    results = yield omci.send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(
                                        0x202,
                                        8,
                                        0,
                                        0,
                                        1,
                                        8,
                                        _set_vlan_vid)

                    # Set AR - ExtendedVlanTaggingOperationConfigData
                    #          514 - RxVlanTaggingOperationTable - add VLAN <cvid> to priority tagged pkts - c-vid
                    '''
                    results = yield omci.send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(0x205, 8, 0, 0,
                                                   
                    '''

            except Exception as e:
                log.exception('failed-to-install-flow', e=e, flow=flow)
Exemple #23
0
    def update_flow_table(self, device, flows):
        #
        # We need to proxy through the OLT to get to the ONU
        # Configuration from here should be using OMCI
        #
        self.log.info('bulk-flow-update', device_id=device.id, flows=flows)

        def is_downstream(port):
            return port == 2  # Need a better way

        def is_upstream(port):
            return not is_downstream(port)

        for flow in flows:
            try:
                _in_port = fd.get_in_port(flow)
                assert _in_port is not None

                if is_downstream(_in_port):
                    self.log.info('downstream-flow')
                elif is_upstream(_in_port):
                    self.log.info('upstream-flow')
                else:
                    raise Exception('port should be 1 or 2 by our convention')

                _out_port = fd.get_out_port(flow)  # may be None
                self.log.info('out-port', out_port=_out_port)

                for field in fd.get_ofb_fields(flow):
                    if field.type == fd.ETH_TYPE:
                        _type = field.eth_type
                        self.log.info('field-type-eth-type', eth_type=_type)

                    elif field.type == fd.IP_PROTO:
                        _proto = field.ip_proto
                        self.log.info('field-type-ip-proto', ip_proto=_proto)

                    elif field.type == fd.IN_PORT:
                        _port = field.port
                        self.log.info('field-type-in-port', in_port=_port)

                    elif field.type == fd.VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        self.log.info('field-type-vlan-vid', vlan=_vlan_vid)

                    elif field.type == fd.VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        self.log.info('field-type-vlan-pcp', pcp=_vlan_pcp)

                    elif field.type == fd.UDP_DST:
                        _udp_dst = field.udp_dst
                        self.log.info('field-type-udp-dst', udp_dst=_udp_dst)

                    elif field.type == fd.UDP_SRC:
                        _udp_src = field.udp_src
                        self.log.info('field-type-udp-src', udp_src=_udp_src)

                    elif field.type == fd.IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        self.log.info('field-type-ipv4-dst',
                                      ipv4_dst=_ipv4_dst)

                    elif field.type == fd.IPV4_SRC:
                        _ipv4_src = field.ipv4_src
                        self.log.info('field-type-ipv4-src',
                                      ipv4_dst=_ipv4_src)

                    elif field.type == fd.METADATA:
                        _metadata = field.metadata
                        self.log.info('field-type-metadata',
                                      metadata=_metadata)

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

                for action in fd.get_actions(flow):

                    if action.type == fd.OUTPUT:
                        _output = action.output.port
                        self.log.info('action-type-output',
                                      output=_output,
                                      in_port=_in_port)

                    elif action.type == fd.POP_VLAN:
                        self.log.info('action-type-pop-vlan', in_port=_in_port)

                    elif action.type == fd.PUSH_VLAN:
                        _push_tpid = action.push.ethertype
                        log.info('action-type-push-vlan',
                                 push_tpid=_push_tpid,
                                 in_port=_in_port)
                        if action.push.ethertype != 0x8100:
                            self.log.error('unhandled-tpid',
                                           ethertype=action.push.ethertype)

                    elif action.type == fd.SET_FIELD:
                        _field = action.set_field.field.ofb_field
                        assert (action.set_field.field.oxm_class ==
                                OFPXMC_OPENFLOW_BASIC)
                        self.log.info('action-type-set-field',
                                      field=_field,
                                      in_port=_in_port)
                        if _field.type == fd.VLAN_VID:
                            self.log.info('set-field-type-valn-vid',
                                          vlan_vid=_field.vlan_vid & 0xfff)
                        else:
                            self.log.error('unsupported-action-set-field-type',
                                           field_type=_field.type)
                    else:
                        log.error('unsupported-action-type',
                                  action_type=action.type,
                                  in_port=_in_port)

                #
                # All flows created from ONU adapter should be OMCI based
                #

            except Exception as e:
                log.exception('failed-to-install-flow', e=e, flow=flow)
    def add_flow(self, flow):
        self.log.debug('add flow', flow=flow)
        classifier_info = dict()
        action_info = dict()

        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])
            elif field.type == fd.IN_PORT:
                classifier_info[IN_PORT] = field.port
                self.log.debug('field-type-in-port',
                               in_port=classifier_info[IN_PORT])
            elif field.type == fd.VLAN_VID:
                classifier_info[VLAN_VID] = field.vlan_vid & 0xfff
                self.log.debug('field-type-vlan-vid',
                               vlan=classifier_info[VLAN_VID])
            elif field.type == fd.VLAN_PCP:
                classifier_info[VLAN_PCP] = field.vlan_pcp
                self.log.debug('field-type-vlan-pcp',
                               pcp=classifier_info[VLAN_PCP])
            elif field.type == fd.UDP_DST:
                classifier_info[UDP_DST] = field.udp_dst
                self.log.debug('field-type-udp-dst',
                               udp_dst=classifier_info[UDP_DST])
            elif field.type == fd.UDP_SRC:
                classifier_info[UDP_SRC] = field.udp_src
                self.log.debug('field-type-udp-src',
                               udp_src=classifier_info[UDP_SRC])
            elif field.type == fd.IPV4_DST:
                classifier_info[IPV4_DST] = field.ipv4_dst
                self.log.debug('field-type-ipv4-dst',
                               ipv4_dst=classifier_info[IPV4_DST])
            elif field.type == fd.IPV4_SRC:
                classifier_info[IPV4_SRC] = field.ipv4_src
                self.log.debug('field-type-ipv4-src',
                               ipv4_dst=classifier_info[IPV4_SRC])
            elif field.type == fd.METADATA:
                classifier_info[METADATA] = field.table_metadata
                self.log.debug('field-type-metadata',
                               metadata=classifier_info[METADATA])
            else:
                raise NotImplementedError('field.type={}'.format(
                    field.type))

        for action in fd.get_actions(flow):
            if action.type == fd.OUTPUT:
                action_info[OUTPUT] = action.output.port
                self.log.debug('action-type-output',
                               output=action_info[OUTPUT],
                               in_port=classifier_info[IN_PORT])
            elif action.type == fd.POP_VLAN:
                if fd.get_goto_table_id(flow) is None:
                    self.log.debug('being taken care of by ONU', flow=flow)
                    return
                action_info[POP_VLAN] = True
                self.log.debug('action-type-pop-vlan',
                               in_port=classifier_info[IN_PORT])
            elif action.type == fd.PUSH_VLAN:
                action_info[PUSH_VLAN] = True
                action_info[TPID] = action.push.ethertype
                self.log.debug('action-type-push-vlan',
                               push_tpid=action_info[TPID], in_port=classifier_info[IN_PORT])
                if action.push.ethertype != 0x8100:
                    self.log.error('unhandled-tpid',
                                   ethertype=action.push.ethertype)
            elif action.type == fd.SET_FIELD:
                # action_info['action_type'] = 'set_field'
                _field = action.set_field.field.ofb_field
                assert (action.set_field.field.oxm_class ==
                        OFPXMC_OPENFLOW_BASIC)
                self.log.debug('action-type-set-field',
                               field=_field, in_port=classifier_info[IN_PORT])
                if _field.type == fd.VLAN_VID:
                    self.log.debug('set-field-type-vlan-vid',
                                   vlan_vid=_field.vlan_vid & 0xfff)
                    action_info[VLAN_VID] = (_field.vlan_vid & 0xfff)
                else:
                    self.log.error('unsupported-action-set-field-type',
                                   field_type=_field.type)
            else:
                self.log.error('unsupported-action-type',
                               action_type=action.type, in_port=classifier_info[IN_PORT])

        if fd.get_goto_table_id(flow) is not None and not POP_VLAN in \
                action_info:
            self.log.debug('being taken care of by ONU', flow=flow)
            return

        if not OUTPUT in action_info and METADATA in classifier_info:
            #find flow in the next table
            next_flow = self.find_next_flow(flow)
            if next_flow is None:
                return
            action_info[OUTPUT] = fd.get_out_port(next_flow)
            for field in fd.get_ofb_fields(next_flow):
                if field.type == fd.VLAN_VID:
                    classifier_info[METADATA] = field.vlan_vid & 0xfff


        (intf_id, onu_id) = self.platform.extract_access_from_flow(
            classifier_info[IN_PORT], action_info[OUTPUT])


        self.divide_and_add_flow(intf_id, onu_id, classifier_info,
                                 action_info, flow)
Exemple #25
0
    def _decode_traffic_selector(self, flow):
        """
        Extract traffic selection settings
        """
        self.in_port = fd.get_in_port(flow)

        if self.in_port > OFPP_MAX:
            log.warn('logical-input-ports-not-supported')
            return False

        for field in fd.get_ofb_fields(flow):
            if field.type == IN_PORT:
                assert self.in_port == field.port, 'Multiple Input Ports found in flow rule'

            elif field.type == VLAN_VID:
                self.vlan_vid = field.vlan_vid & 0xfff
                log.debug('*** field.type == VLAN_VID',
                          value=field.vlan_vid,
                          vlan_id=self.vlan_vid)
                self._is_multicast = False  # TODO: self.vlan_id in self._handler.multicast_vlans

            elif field.type == VLAN_PCP:
                log.debug('*** field.type == VLAN_PCP', value=field.vlan_pcp)
                self.vlan_pcp = field.vlan_pcp

            elif field.type == ETH_TYPE:
                log.debug('*** field.type == ETH_TYPE', value=field.eth_type)
                self.etype = field.eth_type

            elif field.type == IP_PROTO:
                log.debug('*** field.type == IP_PROTO', value=field.ip_proto)
                self.proto = field.ip_proto

                if self.proto not in _supported_ip_protocols:
                    log.error('Unsupported IP Protocol', ip_proto=self.proto)
                    return False

            elif field.type == IPV4_DST:
                log.debug('*** field.type == IPV4_DST', value=field.ipv4_dst)
                self.ipv4_dst = field.ipv4_dst

            elif field.type == UDP_DST:
                log.debug('*** field.type == UDP_DST', value=field.udp_dst)
                self.udp_dst = field.udp_dst

            elif field.type == UDP_SRC:
                log.debug('*** field.type == UDP_SRC', value=field.udp_src)
                self.udp_src = field.udp_src

            elif field.type == METADATA:
                log.debug('*** field.type == METADATA',
                          value=field.table_metadata)
                self.inner_vid = field.table_metadata
                log.debug('*** field.type == METADATA',
                          value=field.table_metadata,
                          inner_vid=self.inner_vid)
            else:
                log.warn('unsupported-selection-field', type=field.type)
                self._status_message = 'Unsupported field.type={}'.format(
                    field.type)
                return False

        return True
Exemple #26
0
    def _decode_traffic_selector(self, flow):
        """
        Extract EVC related traffic selection settings
        """
        self.in_port = fd.get_in_port(flow)

        if self.in_port > OFPP_MAX:
            log.warn('logical-input-ports-not-supported', in_port=self.in_port)
            return False

        for field in fd.get_ofb_fields(flow):
            if field.type == IN_PORT:
                if self._handler.is_nni_port(self.in_port) or self._handler.is_uni_port(self.in_port):
                    self._logical_port = self.in_port

            elif field.type == VLAN_VID:
                if field.vlan_vid >= OFPVID_PRESENT + 4095:
                    self.vlan_id = None             # pre-ONOS v1.13.5 or old EAPOL Rule
                else:
                    self.vlan_id = field.vlan_vid & 0xfff

                log.debug('*** field.type == VLAN_VID', value=field.vlan_vid, vlan_id=self.vlan_id)

            elif field.type == VLAN_PCP:
                log.debug('*** field.type == VLAN_PCP', value=field.vlan_pcp)
                self.pcp = field.vlan_pcp

            elif field.type == ETH_TYPE:
                log.debug('*** field.type == ETH_TYPE', value=field.eth_type)
                self.eth_type = field.eth_type

            elif field.type == IP_PROTO:
                log.debug('*** field.type == IP_PROTO', value=field.ip_proto)
                self.ip_protocol = field.ip_proto

                if self.ip_protocol not in _supported_ip_protocols:
                    log.error('Unsupported IP Protocol', protocol=self.ip_protocol)
                    return False

            elif field.type == IPV4_DST:
                log.debug('*** field.type == IPV4_DST', value=field.ipv4_dst)
                self.ipv4_dst = field.ipv4_dst

            elif field.type == UDP_DST:
                log.debug('*** field.type == UDP_DST', value=field.udp_dst)
                self.udp_dst = field.udp_dst

            elif field.type == UDP_SRC:
                log.debug('*** field.type == UDP_SRC', value=field.udp_src)
                self.udp_src = field.udp_src

            elif field.type == METADATA:
                if self._handler.is_nni_port(self.in_port):
                    # Downstream flow
                    log.debug('*** field.type == METADATA', value=field.table_metadata)

                    if field.table_metadata > 4095:
                        # ONOS v1.13.5 or later. c-vid in upper 32-bits
                        vid = field.table_metadata & 0x0FFF
                        if vid > 0:
                            self.inner_vid = vid        # CTag is never '0'

                    elif field.table_metadata > 0:
                        # Pre-ONOS v1.13.5 (vid without the 4096 offset)
                        self.inner_vid = field.table_metadata

                else:
                    # Upstream flow
                    pass   # Not used upstream at this time

                log.debug('*** field.type == METADATA', value=field.table_metadata,
                          inner_vid=self.inner_vid)
            else:
                log.warn('unsupported-selection-field', type=field.type)
                self._status_message = 'Unsupported field.type={}'.format(field.type)
                return False

        return True
Exemple #27
0
    def update_flow_table(self, device, flows):
        self.log.debug('function-entry', device=device, flows=flows)

        #
        # We need to proxy through the OLT to get to the ONU
        # Configuration from here should be using OMCI
        #
        # self.log.info('bulk-flow-update', device_id=device.id, flows=flows)

        # no point in pushing omci flows if the device isnt reachable
        if device.connect_status != ConnectStatus.REACHABLE or \
           device.admin_state != AdminState.ENABLED:
            self.log.warn("device-disabled-or-offline-skipping-flow-update",
                          admin=device.admin_state,
                          connect=device.connect_status)
            return

        def is_downstream(port):
            return port == self._pon_port_number

        def is_upstream(port):
            return not is_downstream(port)

        for flow in flows:
            _type = None
            _port = None
            _vlan_vid = None
            _udp_dst = None
            _udp_src = None
            _ipv4_dst = None
            _ipv4_src = None
            _metadata = None
            _output = None
            _push_tpid = None
            _field = None
            _set_vlan_vid = None
            self.log.debug('bulk-flow-update', device_id=device.id, flow=flow)
            try:
                _in_port = fd.get_in_port(flow)
                assert _in_port is not None

                _out_port = fd.get_out_port(flow)  # may be None

                if is_downstream(_in_port):
                    self.log.debug('downstream-flow',
                                   in_port=_in_port,
                                   out_port=_out_port)
                    uni_port = self.uni_port(_out_port)
                elif is_upstream(_in_port):
                    self.log.debug('upstream-flow',
                                   in_port=_in_port,
                                   out_port=_out_port)
                    uni_port = self.uni_port(_in_port)
                else:
                    raise Exception('port should be 1 or 2 by our convention')

                self.log.debug('flow-ports',
                               in_port=_in_port,
                               out_port=_out_port,
                               uni_port=str(uni_port))

                for field in fd.get_ofb_fields(flow):
                    if field.type == fd.ETH_TYPE:
                        _type = field.eth_type
                        self.log.debug('field-type-eth-type', eth_type=_type)

                    elif field.type == fd.IP_PROTO:
                        _proto = field.ip_proto
                        self.log.debug('field-type-ip-proto', ip_proto=_proto)

                    elif field.type == fd.IN_PORT:
                        _port = field.port
                        self.log.debug('field-type-in-port', in_port=_port)

                    elif field.type == fd.VLAN_VID:
                        _vlan_vid = field.vlan_vid & 0xfff
                        self.log.debug('field-type-vlan-vid', vlan=_vlan_vid)

                    elif field.type == fd.VLAN_PCP:
                        _vlan_pcp = field.vlan_pcp
                        self.log.debug('field-type-vlan-pcp', pcp=_vlan_pcp)

                    elif field.type == fd.UDP_DST:
                        _udp_dst = field.udp_dst
                        self.log.debug('field-type-udp-dst', udp_dst=_udp_dst)

                    elif field.type == fd.UDP_SRC:
                        _udp_src = field.udp_src
                        self.log.debug('field-type-udp-src', udp_src=_udp_src)

                    elif field.type == fd.IPV4_DST:
                        _ipv4_dst = field.ipv4_dst
                        self.log.debug('field-type-ipv4-dst',
                                       ipv4_dst=_ipv4_dst)

                    elif field.type == fd.IPV4_SRC:
                        _ipv4_src = field.ipv4_src
                        self.log.debug('field-type-ipv4-src',
                                       ipv4_dst=_ipv4_src)

                    elif field.type == fd.METADATA:
                        _metadata = field.table_metadata
                        self.log.debug('field-type-metadata',
                                       metadata=_metadata)

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

                for action in fd.get_actions(flow):

                    if action.type == fd.OUTPUT:
                        _output = action.output.port
                        self.log.debug('action-type-output',
                                       output=_output,
                                       in_port=_in_port)

                    elif action.type == fd.POP_VLAN:
                        self.log.debug('action-type-pop-vlan',
                                       in_port=_in_port)

                    elif action.type == fd.PUSH_VLAN:
                        _push_tpid = action.push.ethertype
                        self.log.debug('action-type-push-vlan',
                                       push_tpid=_push_tpid,
                                       in_port=_in_port)
                        if action.push.ethertype != 0x8100:
                            self.log.error('unhandled-tpid',
                                           ethertype=action.push.ethertype)

                    elif action.type == fd.SET_FIELD:
                        _field = action.set_field.field.ofb_field
                        assert (action.set_field.field.oxm_class ==
                                OFPXMC_OPENFLOW_BASIC)
                        self.log.debug('action-type-set-field',
                                       field=_field,
                                       in_port=_in_port)
                        if _field.type == fd.VLAN_VID:
                            _set_vlan_vid = _field.vlan_vid & 0xfff
                            self.log.debug('set-field-type-vlan-vid',
                                           vlan_vid=_set_vlan_vid)
                        else:
                            self.log.error('unsupported-action-set-field-type',
                                           field_type=_field.type)
                    else:
                        self.log.error('unsupported-action-type',
                                       action_type=action.type,
                                       in_port=_in_port)

                # TODO: We only set vlan omci flows.  Handle omci matching ethertypes at some point in another task
                if _type is not None:
                    self.log.warn('ignoring-flow-with-ethType', ethType=_type)
                elif _set_vlan_vid is None or _set_vlan_vid == 0:
                    self.log.warn('ignorning-flow-that-does-not-set-vlanid')
                else:
                    self.log.warn('set-vlanid',
                                  uni_id=uni_port.port_number,
                                  set_vlan_vid=_set_vlan_vid)
                    self._add_vlan_filter_task(device, uni_port, _set_vlan_vid)

            except Exception as e:
                self.log.exception('failed-to-install-flow', e=e, flow=flow)
Exemple #28
0
    def _decode_traffic_selector(self, flow):
        """
        Extract EVC related traffic selection settings
        """
        self.in_port = fd.get_in_port(flow)

        if self.in_port > OFPP_MAX:
            log.warn('logical-input-ports-not-supported', in_port=self.in_port)
            return False

        for field in fd.get_ofb_fields(flow):
            if field.type == IN_PORT:
                if self._handler.is_nni_port(
                        self.in_port) or self._handler.is_uni_port(
                            self.in_port):
                    self._logical_port = self.in_port

            elif field.type == VLAN_VID:
                if field.vlan_vid >= ofp.OFPVID_PRESENT + 4095:
                    self.vlan_id = None  # pre-ONOS v1.13.5 or old EAPOL Rule
                else:
                    self.vlan_id = field.vlan_vid & 0xfff

                log.debug('*** field.type == VLAN_VID',
                          value=field.vlan_vid,
                          vlan_id=self.vlan_id)

            elif field.type == VLAN_PCP:
                log.debug('*** field.type == VLAN_PCP', value=field.vlan_pcp)
                self.pcp = field.vlan_pcp

            elif field.type == ETH_TYPE:
                log.debug('*** field.type == ETH_TYPE', value=field.eth_type)
                self.eth_type = field.eth_type

            elif field.type == IP_PROTO:
                log.debug('*** field.type == IP_PROTO', value=field.ip_proto)
                self.ip_protocol = field.ip_proto

                if self.ip_protocol not in _supported_ip_protocols:
                    log.error('Unsupported IP Protocol',
                              protocol=self.ip_protocol)
                    return False

            elif field.type == IPV4_DST:
                log.debug('*** field.type == IPV4_DST', value=field.ipv4_dst)
                self.ipv4_dst = field.ipv4_dst

            elif field.type == UDP_DST:
                log.debug('*** field.type == UDP_DST', value=field.udp_dst)
                self.udp_dst = field.udp_dst

            elif field.type == UDP_SRC:
                log.debug('*** field.type == UDP_SRC', value=field.udp_src)
                self.udp_src = field.udp_src

            elif field.type == METADATA:
                log.debug('*** field.type == METADATA',
                          value=field.table_metadata)

                if 0xFFFFFFFF >= field.table_metadata > ofp.OFPVID_PRESENT + 4095:
                    # Default flows for old-style controller flows
                    self.inner_vid = None

                elif field.table_metadata > 0xFFFFFFFF:
                    # ONOS v1.13.5 or later. c-vid in upper 32-bits
                    self.inner_vid = field.table_metadata >> 32

                else:
                    # Pre- ONOS v1.13.5
                    self.inner_vid = field.table_metadata

                log.debug('*** field.type == METADATA',
                          value=field.table_metadata,
                          inner_vid=self.inner_vid)
            else:
                log.warn('unsupported-selection-field', type=field.type)
                self._status_message = 'Unsupported field.type={}'.format(
                    field.type)
                return False

        return True