Exemplo n.º 1
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')
Exemplo n.º 2
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]
Exemplo n.º 3
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]
Exemplo n.º 4
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
Exemplo n.º 5
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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    def _decode_traffic_treatment(self):
        self.output = fd.get_out_port(self._flow)

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

        for act in fd.get_actions(self._flow):
            if act.type == fd.OUTPUT:
                assert self.output == act.output.port, 'Multiple Output Ports found in flow rule'
                pass  # Handled earlier

            elif act.type == POP_VLAN:
                # log.info('*** action.type == POP_VLAN')
                self.pop_vlan += 1

            elif act.type == PUSH_VLAN:
                # log.info('*** action.type == PUSH_VLAN', value=act.push)
                # TODO: Do we want to test the ethertype for support?
                tpid = act.push.ethertype
                self.push_vlan_tpid.append(tpid)

            elif act.type == SET_FIELD:
                # log.info('*** action.type == SET_FIELD', value=act.set_field.field)
                assert (
                    act.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC)
                field = act.set_field.field.ofb_field
                if field.type == VLAN_VID:
                    self.push_vlan_id.append(field.vlan_vid & 0xfff)

            else:
                # TODO: May need to modify ce-preservation
                log.warn('unsupported-action', action=act)
                self._status_message = 'Unsupported action.type={}'.format(
                    act.type)
                return False

        return True
Exemplo n.º 8
0
    def _decode_traffic_treatment(self, flow):
        self.out_port = fd.get_out_port(flow)

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

        for act in fd.get_actions(flow):
            if act.type == fd.OUTPUT:
                assert self.out_port == act.output.port, 'Multiple Output Ports found in flow rule'
                pass  # Handled earlier

            elif act.type == POP_VLAN:
                log.debug('*** action.type == POP_VLAN')
                self.pop_vlan = True

            elif act.type == PUSH_VLAN:
                log.debug('*** action.type == PUSH_VLAN', value=act.push)
                tpid = act.push.ethertype
                self.push_tpid = tpid
                assert tpid == 0x8100, 'Only TPID 0x8100 is currently supported'

            elif act.type == SET_FIELD:
                log.debug('*** action.type == SET_FIELD',
                          value=act.set_field.field)
                assert (
                    act.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC)
                field = act.set_field.field.ofb_field
                if field.type == VLAN_VID:
                    self.set_vlan_vid = field.vlan_vid & 0xfff

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

        return True
Exemplo n.º 9
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()
Exemplo n.º 10
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)

        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)
Exemplo n.º 11
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 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)
Exemplo n.º 12
0
    def add_eapol_flow(self,
                       intf_id,
                       onu_id,
                       logical_flow,
                       alloc_id,
                       gemport_id,
                       eapol_flow_category=EAPOL_PRIMARY_FLOW,
                       vlan_id=DEFAULT_MGMT_VLAN):

        uplink_classifier = dict()
        uplink_classifier[ETH_TYPE] = EAP_ETH_TYPE
        uplink_classifier[PACKET_TAG_TYPE] = SINGLE_TAG
        uplink_classifier[VLAN_VID] = vlan_id

        uplink_action = dict()
        uplink_action[TRAP_TO_HOST] = True

        pon_intf_onu_id = (intf_id, onu_id)
        # Add Upstream EAPOL Flow.
        if eapol_flow_category == EAPOL_PRIMARY_FLOW:
            uplink_flow_id = self.resource_mgr.get_flow_id(pon_intf_onu_id)
        else:
            uplink_flow_id = self.resource_mgr.get_flow_id(pon_intf_onu_id)

        upstream_flow = openolt_pb2.Flow(
            access_intf_id=intf_id,
            onu_id=onu_id,
            flow_id=uplink_flow_id,
            flow_type=UPSTREAM,
            alloc_id=alloc_id,
            network_intf_id=0,
            gemport_id=gemport_id,
            classifier=self.mk_classifier(uplink_classifier),
            action=self.mk_action(uplink_action),
            priority=logical_flow.priority)

        logical_flow = copy.deepcopy(logical_flow)
        logical_flow.match.oxm_fields.extend(
            fd.mk_oxm_fields([fd.vlan_vid(vlan_id | 0x1000)]))
        logical_flow.match.type = OFPMT_OXM

        if self.add_flow_to_device(upstream_flow, logical_flow):
            if eapol_flow_category == EAPOL_PRIMARY_FLOW:
                flow_info = self._get_flow_info_as_json_blob(
                    upstream_flow, EAPOL_PRIMARY_FLOW)
                self.update_flow_info_to_kv_store(upstream_flow.access_intf_id,
                                                  upstream_flow.onu_id,
                                                  upstream_flow.flow_id,
                                                  flow_info)
            else:
                flow_info = self._get_flow_info_as_json_blob(
                    upstream_flow, EAPOL_SECONDARY_FLOW)
                self.update_flow_info_to_kv_store(upstream_flow.access_intf_id,
                                                  upstream_flow.onu_id,
                                                  upstream_flow.flow_id,
                                                  flow_info)

        if vlan_id == DEFAULT_MGMT_VLAN:
            # Add Downstream EAPOL Flow, Only for first EAP flow (BAL
            # requirement)
            special_vlan_downstream_flow = 4000 - onu_id

            downlink_classifier = dict()
            downlink_classifier[PACKET_TAG_TYPE] = SINGLE_TAG
            downlink_classifier[VLAN_VID] = special_vlan_downstream_flow

            downlink_action = dict()
            downlink_action[PUSH_VLAN] = True
            downlink_action[VLAN_VID] = vlan_id

            pon_intf_onu_id = (intf_id, onu_id)
            downlink_flow_id = self.resource_mgr.get_flow_id(pon_intf_onu_id)

            downstream_flow = openolt_pb2.Flow(
                access_intf_id=intf_id,
                onu_id=onu_id,
                flow_id=downlink_flow_id,
                flow_type=DOWNSTREAM,
                alloc_id=alloc_id,
                network_intf_id=0,
                gemport_id=gemport_id,
                classifier=self.mk_classifier(downlink_classifier),
                action=self.mk_action(downlink_action),
                priority=logical_flow.priority)

            downstream_logical_flow = ofp_flow_stats(
                id=logical_flow.id,
                cookie=logical_flow.cookie,
                table_id=logical_flow.table_id,
                priority=logical_flow.priority,
                flags=logical_flow.flags)

            downstream_logical_flow.match.oxm_fields.extend(
                fd.mk_oxm_fields([
                    fd.in_port(fd.get_out_port(logical_flow)),
                    fd.vlan_vid(special_vlan_downstream_flow | 0x1000)
                ]))
            downstream_logical_flow.match.type = OFPMT_OXM

            downstream_logical_flow.instructions.extend(
                fd.mk_instructions_from_actions([
                    fd.output(self.platform.mk_uni_port_num(intf_id, onu_id))
                ]))

            if self.add_flow_to_device(downstream_flow,
                                       downstream_logical_flow):
                flow_info = self._get_flow_info_as_json_blob(
                    downstream_flow, EAPOL_PRIMARY_FLOW)
                self.update_flow_info_to_kv_store(
                    downstream_flow.access_intf_id, downstream_flow.onu_id,
                    downstream_flow.flow_id, flow_info)
Exemplo n.º 13
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')

                _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:
                        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)

                if is_down_stream is False:
                    intf_id, onu_id = self.parse_port_no(
                        classifier_info['in_port'])
                    self.divide_and_add_flow(onu_id, intf_id, classifier_info,
                                             action_info)
            except Exception as e:
                self.log.exception('failed-to-install-flow', e=e, flow=flow)
Exemplo n.º 14
0
    def add_eapol_flow(self, intf_id, onu_id, logical_flow,
                       eapol_id=EAPOL_FLOW_INDEX,
                       vlan_id=DEFAULT_MGMT_VLAN):

        uplink_classifier = {}
        uplink_classifier[ETH_TYPE] = EAP_ETH_TYPE
        uplink_classifier[PACKET_TAG_TYPE] = SINGLE_TAG
        uplink_classifier[VLAN_VID] = vlan_id

        uplink_action = {}
        uplink_action[TRAP_TO_HOST] = True

        # Add Upstream EAPOL Flow.

        pon_intf_onu_id = (intf_id, onu_id)
        gemport_id = self.resource_mgr.get_gemport_id(
                          pon_intf_onu_id=pon_intf_onu_id
                     )
        alloc_id = self.resource_mgr.get_alloc_id(
                          pon_intf_onu_id=pon_intf_onu_id
                     )

        uplink_flow_id = self.platform.mk_flow_id(intf_id, onu_id, eapol_id)

        upstream_flow = openolt_pb2.Flow(
            onu_id=onu_id, flow_id=uplink_flow_id, flow_type=UPSTREAM,
            access_intf_id=intf_id, gemport_id=gemport_id,
            alloc_id=alloc_id,
            priority=logical_flow.priority,
            classifier=self.mk_classifier(uplink_classifier),
            action=self.mk_action(uplink_action))

        logical_flow = copy.deepcopy(logical_flow)
        logical_flow.match.oxm_fields.extend(fd.mk_oxm_fields([fd.vlan_vid(
            vlan_id | 0x1000)]))
        logical_flow.match.type = OFPMT_OXM

        self.add_flow_to_device(upstream_flow, logical_flow)

        if vlan_id == DEFAULT_MGMT_VLAN:

            # Add Downstream EAPOL Flow, Only for first EAP flow (BAL
            # requirement)
            special_vlan_downstream_flow = 4000 - onu_id

            downlink_classifier = {}
            downlink_classifier[PACKET_TAG_TYPE] = SINGLE_TAG
            downlink_classifier[VLAN_VID] = special_vlan_downstream_flow

            downlink_action = {}
            downlink_action[PUSH_VLAN] = True
            downlink_action[VLAN_VID] = vlan_id

            downlink_flow_id = self.platform.mk_flow_id(
                intf_id, onu_id, DOWNSTREAM_FLOW_FOR_PACKET_OUT)

            downstream_flow = openolt_pb2.Flow(
                onu_id=onu_id, flow_id=downlink_flow_id, flow_type=DOWNSTREAM,
                access_intf_id=intf_id, gemport_id=gemport_id,
                priority=logical_flow.priority,
                classifier=self.mk_classifier(downlink_classifier),
                action=self.mk_action(downlink_action))

            downstream_logical_flow = ofp_flow_stats(
                id=logical_flow.id, cookie=logical_flow.cookie,
                table_id=logical_flow.table_id, priority=logical_flow.priority,
                flags=logical_flow.flags)

            downstream_logical_flow.match.oxm_fields.extend(fd.mk_oxm_fields([
                fd.in_port(fd.get_out_port(logical_flow)),
                fd.vlan_vid((special_vlan_downstream_flow) | 0x1000)]))
            downstream_logical_flow.match.type = OFPMT_OXM

            downstream_logical_flow.instructions.extend(
                fd.mk_instructions_from_actions([fd.output(
                    self.platform.mk_uni_port_num(intf_id, onu_id))]))

            self.add_flow_to_device(downstream_flow, downstream_logical_flow)
Exemplo n.º 15
0
    def add_eapol_flow(self, intf_id, onu_id, uni_id, port_no, logical_flow,
                       alloc_id, gemport_id, vlan_id=DEFAULT_MGMT_VLAN):

        uplink_classifier = dict()
        uplink_classifier[ETH_TYPE] = EAP_ETH_TYPE
        uplink_classifier[PACKET_TAG_TYPE] = SINGLE_TAG
        uplink_classifier[VLAN_VID] = vlan_id

        uplink_action = dict()
        uplink_action[TRAP_TO_HOST] = True

        flow_store_cookie = self._get_flow_store_cookie(uplink_classifier,
                                                        gemport_id)

        if self.resource_mgr.is_flow_cookie_on_kv_store(intf_id, onu_id,
                                                        uni_id,
                                                        flow_store_cookie):
            self.log.debug('flow-exists--not-re-adding')
        else:
            # Add Upstream EAPOL Flow.
            uplink_flow_id = self.resource_mgr.get_flow_id(
                intf_id, onu_id, uni_id, flow_store_cookie
            )

            upstream_flow = openolt_pb2.Flow(
                access_intf_id=intf_id, onu_id=onu_id, uni_id=uni_id,
                flow_id=uplink_flow_id, flow_type=UPSTREAM, alloc_id=alloc_id,
                network_intf_id=self.data_model.olt_nni_intf_id(),
                gemport_id=gemport_id,
                classifier=self.mk_classifier(uplink_classifier),
                action=self.mk_action(uplink_action),
                priority=logical_flow.priority,
                port_no=port_no,
                cookie=logical_flow.cookie)

            logical_flow = copy.deepcopy(logical_flow)
            logical_flow.match.oxm_fields.extend(fd.mk_oxm_fields([fd.vlan_vid(
                vlan_id | 0x1000)]))
            logical_flow.match.type = OFPMT_OXM

            if self.add_flow_to_device(upstream_flow, logical_flow):
                flow_info = self._get_flow_info_as_json_blob(upstream_flow,
                                                             flow_store_cookie)
                self.update_flow_info_to_kv_store(upstream_flow.access_intf_id,
                                                  upstream_flow.onu_id,
                                                  upstream_flow.uni_id,
                                                  upstream_flow.flow_id,
                                                  flow_info)

        if vlan_id == DEFAULT_MGMT_VLAN:
            # Add Downstream EAPOL Flow, Only for first EAP flow (BAL
            # requirement)
            # On one of the platforms (Broadcom BAL), when same DL classifier
            # vlan was used across multiple ONUs, eapol flow re-adds after
            # flow delete (cases of onu reboot/disable) fails.
            # In order to generate unique vlan, a combination of intf_id
            # onu_id and uni_id is used.
            # uni_id defaults to 0, so add 1 to it.
            special_vlan_downstream_flow = 4090 - intf_id * onu_id * (uni_id+1)
            # Assert that we do not generate invalid vlans under no condition
            assert special_vlan_downstream_flow >= 2

            downlink_classifier = dict()
            downlink_classifier[PACKET_TAG_TYPE] = SINGLE_TAG
            downlink_classifier[VLAN_VID] = special_vlan_downstream_flow

            downlink_action = dict()
            downlink_action[PUSH_VLAN] = True
            downlink_action[VLAN_VID] = vlan_id

            flow_store_cookie = self._get_flow_store_cookie(
                downlink_classifier, gemport_id)
            if self.resource_mgr.is_flow_cookie_on_kv_store(
                    intf_id, onu_id, uni_id, flow_store_cookie):
                self.log.debug('flow-exists--not-re-adding')
            else:

                downlink_flow_id = self.resource_mgr.get_flow_id(
                    intf_id, onu_id, uni_id, flow_store_cookie
                )

                downstream_flow = openolt_pb2.Flow(
                    access_intf_id=intf_id, onu_id=onu_id, uni_id=uni_id,
                    flow_id=downlink_flow_id, flow_type=DOWNSTREAM,
                    alloc_id=alloc_id,
                    network_intf_id=self.data_model.olt_nni_intf_id(),
                    gemport_id=gemport_id,
                    classifier=self.mk_classifier(downlink_classifier),
                    action=self.mk_action(downlink_action),
                    priority=logical_flow.priority,
                    port_no=port_no,
                    cookie=logical_flow.cookie)

                downstream_logical_flow = ofp_flow_stats(
                    id=logical_flow.id, cookie=logical_flow.cookie,
                    table_id=logical_flow.table_id,
                    priority=logical_flow.priority, flags=logical_flow.flags)

                downstream_logical_flow.match.oxm_fields.extend(
                    fd.mk_oxm_fields(
                        [fd.in_port(fd.get_out_port(logical_flow)),
                         fd.vlan_vid(special_vlan_downstream_flow | 0x1000)]))
                downstream_logical_flow.match.type = OFPMT_OXM

                downstream_logical_flow.instructions.extend(
                    fd.mk_instructions_from_actions([fd.output(
                        self.platform.mk_uni_port_num(intf_id, onu_id,
                                                      uni_id))]))

                if self.add_flow_to_device(downstream_flow,
                                           downstream_logical_flow):
                    flow_info = self._get_flow_info_as_json_blob(
                        downstream_flow, flow_store_cookie)
                    self.update_flow_info_to_kv_store(
                        downstream_flow.access_intf_id, downstream_flow.onu_id,
                        downstream_flow.uni_id, downstream_flow.flow_id,
                        flow_info)
Exemplo n.º 16
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)
Exemplo n.º 17
0
    def add_eapol_flow(self, intf_id, onu_id, logical_flow,
                       uplink_eapol_id=EAPOL_FLOW_INDEX,
                       downlink_eapol_id=EAPOL_DOWNLINK_FLOW_INDEX,
                       vlan_id=DEFAULT_MGMT_VLAN):



        uplink_classifier = {}
        uplink_classifier['eth_type'] = EAP_ETH_TYPE
        uplink_classifier['pkt_tag_type'] = 'single_tag'
        uplink_classifier['vlan_vid'] = vlan_id

        uplink_action = {}
        uplink_action['trap_to_host'] = True

        gemport_id = self.platform.mk_gemport_id(intf_id, onu_id)

        # Add Upstream EAPOL Flow.

        uplink_flow_id = self.platform.mk_flow_id(intf_id, onu_id, uplink_eapol_id)

        upstream_flow = openolt_pb2.Flow(
            onu_id=onu_id, flow_id=uplink_flow_id, flow_type="upstream",
            access_intf_id=intf_id, gemport_id=gemport_id,
            priority=logical_flow.priority,
            classifier=self.mk_classifier(uplink_classifier),
            action=self.mk_action(uplink_action))

        logical_flow = copy.deepcopy(logical_flow)
        logical_flow.match.oxm_fields.extend(fd.mk_oxm_fields([fd.vlan_vid(
            vlan_id | 0x1000)]))
        logical_flow.match.type = OFPMT_OXM

        self.add_flow_to_device(upstream_flow, logical_flow)

        if vlan_id == DEFAULT_MGMT_VLAN:

            # Add Downstream EAPOL Flow, Only for first EAP flow

            downlink_classifier = {}
            downlink_classifier['pkt_tag_type'] = 'single_tag'
            downlink_classifier['vlan_vid'] = 4000 - onu_id



            downlink_action = {}
            downlink_action['push_vlan'] = True
            downlink_action['vlan_vid'] = vlan_id

            downlink_flow_id = self.platform.mk_flow_id(intf_id, onu_id,
                                                   downlink_eapol_id)

            downstream_flow = openolt_pb2.Flow(
                onu_id=onu_id, flow_id=downlink_flow_id, flow_type="downstream",
                access_intf_id=intf_id, gemport_id=gemport_id,
                priority=logical_flow.priority,
                classifier=self.mk_classifier(downlink_classifier),
                action=self.mk_action(downlink_action))

            downstream_logical_flow = ofp_flow_stats(id=logical_flow.id,
                 cookie=logical_flow.cookie, table_id=logical_flow.table_id,
                 priority=logical_flow.priority, flags=logical_flow.flags)

            downstream_logical_flow.match.oxm_fields.extend(fd.mk_oxm_fields([
                fd.in_port(fd.get_out_port(logical_flow)),
                fd.vlan_vid((4000 - onu_id) | 0x1000)]))
            downstream_logical_flow.match.type = OFPMT_OXM

            downstream_logical_flow.instructions.extend(
                fd.mk_instructions_from_actions([fd.output(
                self.platform.mk_uni_port_num(intf_id, onu_id))]))

            self.add_flow_to_device(downstream_flow, downstream_logical_flow)
Exemplo n.º 18
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)
Exemplo n.º 19
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)
Exemplo n.º 20
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)
Exemplo n.º 21
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)