예제 #1
0
    def add_hsia_flow(self, intf_id, onu_id, uplink_classifier, uplink_action,
                downlink_classifier, downlink_action, hsia_id):

        gemport_id = platform.mk_gemport_id(onu_id)
        flow_id = platform.mk_flow_id(intf_id, onu_id, hsia_id)

        self.log.debug('add upstream flow', onu_id=onu_id, classifier=uplink_classifier,
                action=uplink_action, gemport_id=gemport_id, flow_id=flow_id)

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


        self.stub.FlowAdd(flow)

        self.log.debug('add downstream flow', classifier=downlink_classifier,
                action=downlink_action, gemport_id=gemport_id, flow_id=flow_id)

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

        self.stub.FlowAdd(flow)
예제 #2
0
    def add_dhcp_trap(self, intf_id, onu_id, priority, classifier, action):

        self.log.debug('add dhcp upstream trap',
                       classifier=classifier,
                       action=action)

        action.clear()
        action['trap_to_host'] = True
        classifier['pkt_tag_type'] = 'single_tag'
        classifier.pop('vlan_vid', None)

        gemport_id = platform.mk_gemport_id(onu_id)
        flow_id = platform.mk_flow_id(intf_id, onu_id, DHCP_FLOW_INDEX)

        upstream_flow = openolt_pb2.Flow(
            onu_id=onu_id,
            flow_id=flow_id,
            flow_type="upstream",
            access_intf_id=intf_id,
            network_intf_id=0,
            gemport_id=gemport_id,
            priority=priority,
            classifier=self.mk_classifier(classifier),
            action=self.mk_action(action))

        self.stub.FlowAdd(upstream_flow)

        # FIXME - Fix OpenOLT handling of downstream flows instead
        #         of duplicating the downstream flow from the upstream
        #         flow.
        # FIXME - ONOS should send explicit upstream and downstream
        #         exact dhcp trap flow.
        classifier['udp_src'] = 67
        classifier['udp_dst'] = 68
        classifier['pkt_tag_type'] = 'double_tag'
        action.pop('push_vlan', None)

        flow_id = platform.mk_flow_id(intf_id, onu_id,
                                      DHCP_DOWNLINK_FLOW_INDEX)

        downstream_flow = openolt_pb2.Flow(
            onu_id=onu_id,
            flow_id=flow_id,
            flow_type="downstream",
            access_intf_id=intf_id,
            network_intf_id=0,
            gemport_id=gemport_id,
            priority=priority,
            classifier=self.mk_classifier(classifier),
            action=self.mk_action(action))

        self.log.debug('add dhcp downstream trap',
                       access_intf_id=intf_id,
                       onu_id=onu_id,
                       flow_id=flow_id)
        self.stub.FlowAdd(downstream_flow)
예제 #3
0
    def add_dhcp_trap(self, intf_id, onu_id, classifier, action, logical_flow):

        self.log.debug('add dhcp upstream trap',
                       classifier=classifier,
                       action=action)

        action.clear()
        action['trap_to_host'] = True
        classifier['pkt_tag_type'] = 'single_tag'
        classifier.pop('vlan_vid', None)

        gemport_id = platform.mk_gemport_id(intf_id, onu_id)
        flow_id = platform.mk_flow_id(intf_id, onu_id, DHCP_FLOW_INDEX)

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

        self.add_flow_to_device(upstream_flow, logical_flow)

        # FIXME - ONOS should send explicit upstream and downstream
        #         exact dhcp trap flow.

        downstream_logical_flow = copy.deepcopy(logical_flow)
        for oxm_field in downstream_logical_flow.match.oxm_fields:
            if oxm_field.ofb_field.type == OFPXMT_OFB_IN_PORT:
                oxm_field.ofb_field.port = 128

        classifier['udp_src'] = 67
        classifier['udp_dst'] = 68
        classifier['pkt_tag_type'] = 'double_tag'
        action.pop('push_vlan', None)

        flow_id = platform.mk_flow_id(intf_id, onu_id,
                                      DHCP_DOWNLINK_FLOW_INDEX)

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

        self.add_flow_to_device(downstream_flow, downstream_logical_flow)
예제 #4
0
    def add_hsia_flow(self, intf_id, onu_id, classifier, action, direction,
                      hsia_id, logical_flow):

        gemport_id = platform.mk_gemport_id(intf_id, onu_id)
        flow_id = platform.mk_flow_id(intf_id, onu_id, hsia_id)

        flow = openolt_pb2.Flow(onu_id=onu_id,
                                flow_id=flow_id,
                                flow_type=direction,
                                access_intf_id=intf_id,
                                gemport_id=gemport_id,
                                priority=logical_flow.priority,
                                classifier=self.mk_classifier(classifier),
                                action=self.mk_action(action))

        self.add_flow_to_device(flow, logical_flow)
예제 #5
0
    def add_dhcp_trap(self, intf_id, onu_id, classifier, action):

        self.log.debug('add dhcp trap', classifier=classifier, action=action)

        action.clear()
        action['trap_to_host'] = True
        classifier['pkt_tag_type'] = 'single_tag'
        classifier.pop('vlan_vid', None)

        gemport_id = platform.mk_gemport_id(onu_id)
        flow_id = platform.mk_flow_id(intf_id, onu_id, DHCP_FLOW_INDEX)

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

        self.stub.FlowAdd(upstream_flow)
예제 #6
0
    def add_eapol_flow(self, intf_id, onu_id, uplink_classifier, uplink_action,
            uplink_eapol_id=EAPOL_FLOW_INDEX,
            downlink_eapol_id=EAPOL_DOWNLINK_FLOW_INDEX,
            vlan_id=DEFAULT_MGMT_VLAN):

        self.log.debug('add eapol flow', classifier=uplink_classifier, action=uplink_action)

        downlink_classifier = dict(uplink_classifier)
        downlink_action = dict(uplink_action)

        gemport_id = platform.mk_gemport_id(onu_id)
        uplink_flow_id = platform.mk_flow_id(intf_id, onu_id, uplink_eapol_id)

        # Add Upstream EAPOL Flow.
        uplink_classifier['pkt_tag_type'] = 'single_tag'
        uplink_classifier['vlan_vid'] = vlan_id
        uplink_action.clear()
        uplink_action['trap_to_host'] = True

        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,
                classifier=self.mk_classifier(uplink_classifier), action=self.mk_action(uplink_action))

        self.stub.FlowAdd(upstream_flow)

        # Add Downstream EAPOL Flow.
        downlink_flow_id = platform.mk_flow_id(intf_id, onu_id, downlink_eapol_id)
        downlink_classifier['pkt_tag_type'] = 'single_tag'
        downlink_classifier['vlan_vid'] = vlan_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,
                classifier=self.mk_classifier(downlink_classifier), action=self.mk_action(downlink_action))


        self.stub.FlowAdd(downstream_flow)
예제 #7
0
    def onu_indication(self, onu_indication):
        self.log.debug("onu-indication",
                       intf_id=onu_indication.intf_id,
                       onu_id=onu_indication.onu_id,
                       serial_number=onu_indication.serial_number,
                       oper_state=onu_indication.oper_state,
                       admin_state=onu_indication.admin_state)

        serial_number_str = self.stringify_serial_number(
            onu_indication.serial_number)

        if serial_number_str == '000000000000':
            self.log.debug(
                'serial-number-was-not-provided-or-default-serial-number-provided-identifying-onu-by-onu_id'
            )
            #FIXME: if multiple PON ports onu_id is not a sufficient key
            onu_device = self.adapter_agent.get_child_device(
                self.device_id, onu_id=onu_indication.onu_id)
        else:
            onu_device = self.adapter_agent.get_child_device(
                self.device_id, serial_number=serial_number_str)

        self.log.debug('onu-device',
                       olt_device_id=self.device_id,
                       device=onu_device)

        # FIXME - handle serial_number mismatch
        # assert key is not None
        # assert onu_device is not None
        if onu_device is None:
            self.log.warn('onu-device-is-none-invalid-message')
            return

        if onu_device.connect_status != ConnectStatus.REACHABLE:
            onu_device.connect_status = ConnectStatus.REACHABLE
            self.adapter_agent.update_device(onu_device)

        if platform.intf_id_from_pon_port_no(
                onu_device.parent_port_no) != onu_indication.intf_id:
            self.log.warn('ONU-is-on-a-different-intf-id-now',
                          previous_intf_id=platform.intf_id_from_pon_port_no(
                              onu_device.parent_port_no),
                          current_intf_id=onu_indication.intf_id)
            # FIXME - handle intf_id mismatch (ONU move?)

        if onu_device.proxy_address.onu_id != onu_indication.onu_id:
            # FIXME - handle onu id mismatch
            self.log.warn('ONU-id-mismatch',
                          expected_onu_id=onu_device.proxy_address.onu_id,
                          received_onu_id=onu_indication.onu_id)

        uni_no = platform.mk_uni_port_num(onu_indication.intf_id,
                                          onu_indication.onu_id)
        uni_name = self.port_name(uni_no,
                                  Port.ETHERNET_UNI,
                                  serial_number=serial_number_str)

        self.log.debug('port-number-ready', uni_no=uni_no, uni_name=uni_name)

        #Admin state
        if onu_indication.admin_state == 'down':
            if onu_indication.oper_state != 'down':
                self.log.error('ONU-admin-state-down-and-oper-status-not-down',
                               oper_state=onu_indication.oper_state)
                onu_indication.oper_state = 'down'  # Forcing the oper state change code to execute

            if onu_device.admin_state != AdminState.DISABLED:
                onu_device.admin_state = AdminState.DISABLED
                self.adapter_agent.update(onu_device)
                self.log.debug('putting-onu-in-disabled-state',
                               onu_serial_number=onu_device.serial_number)

            #Port and logical port update is taken care of by oper state block

        elif onu_indication.admin_state == 'up':
            if onu_device.admin_state != AdminState.ENABLED:
                onu_device.admin_state = AdminState.ENABLED
                self.adapter_agent.update(onu_device)
                self.log.debug('putting-onu-in-enabled-state',
                               onu_serial_number=onu_device.serial_number)

        else:
            self.log.warn('Invalid-or-not-implemented-admin-state',
                          received_admin_state=onu_indication.admin_state)

        self.log.debug('admin-state-dealt-with')

        #Operating state
        if onu_indication.oper_state == 'down':
            #Move to discovered state
            self.log.debug('onu-oper-state-is-down')

            if onu_device.oper_status != OperStatus.DISCOVERED:
                onu_device.oper_status = OperStatus.DISCOVERED
                self.adapter_agent.update_device(onu_device)
            #Set port oper state to Discovered

            self.onu_ports_down(onu_device, uni_no, uni_name,
                                OperStatus.DISCOVERED)

        elif onu_indication.oper_state == 'up':

            if onu_device.oper_status != OperStatus.DISCOVERED:
                self.log.debug("ignore onu indication",
                               intf_id=onu_indication.intf_id,
                               onu_id=onu_indication.onu_id,
                               state=onu_device.oper_status,
                               msg_oper_state=onu_indication.oper_state)
                return

            #Device was in Discovered state, setting it to active

            onu_adapter_agent = registry('adapter_loader').get_agent(
                onu_device.adapter)
            if onu_adapter_agent is None:
                self.log.error('onu_adapter_agent-could-not-be-retrieved',
                               onu_device=onu_device)
                return

            #Prepare onu configuration

            # onu initialization, base configuration (bridge setup ...)
            def onu_initialization():

                #FIXME: that's definitely cheating
                if onu_device.adapter == 'broadcom_onu':
                    onu_adapter_agent.adapter.devices_handlers[
                        onu_device.id].message_exchange()
                    self.log.debug('broadcom-message-exchange-started')

            # tcont creation (onu)
            tcont = TcontsConfigData()
            tcont.alloc_id = platform.mk_alloc_id(onu_indication.onu_id)

            # gem port creation
            gem_port = GemportsConfigData()
            gem_port.gemport_id = platform.mk_gemport_id(onu_indication.onu_id)

            #ports creation/update
            def port_config():

                # "v_enet" creation (olt)

                #add_port update port when it exists
                self.adapter_agent.add_port(
                    self.device_id,
                    Port(port_no=uni_no,
                         label=uni_name,
                         type=Port.ETHERNET_UNI,
                         admin_state=AdminState.ENABLED,
                         oper_status=OperStatus.ACTIVE))

                # v_enet creation (onu)

                venet = VEnetConfig(name=uni_name)
                venet.interface.name = uni_name
                onu_adapter_agent.create_interface(onu_device, venet)

            # ONU device status update in the datastore
            def onu_update_oper_status():
                onu_device.oper_status = OperStatus.ACTIVE
                onu_device.connect_status = ConnectStatus.REACHABLE
                self.adapter_agent.update_device(onu_device)

            # FIXME : the asynchronicity has to be taken care of properly
            onu_initialization()
            reactor.callLater(10,
                              onu_adapter_agent.create_tcont,
                              device=onu_device,
                              tcont_data=tcont,
                              traffic_descriptor_data=None)
            reactor.callLater(11, onu_adapter_agent.create_gemport, onu_device,
                              gem_port)
            reactor.callLater(12, port_config)
            reactor.callLater(12, onu_update_oper_status)

        else:
            self.log.warn('Not-implemented-or-invalid-value-of-oper-state',
                          oper_state=onu_indication.oper_state)
예제 #8
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):

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

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

        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 = platform.mk_gemport_id(intf_id, onu_id)

        # Add Upstream EAPOL Flow.

        uplink_flow_id = 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)

        # Add Downstream EAPOL Flow.
        downlink_flow_id = 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.eth_type(EAP_ETH_TYPE),
                fd.vlan_vid(vlan_id | 0x1000)
            ]))
        downstream_logical_flow.match.type = OFPMT_OXM

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

        self.add_flow_to_device(downstream_flow, downstream_logical_flow)
예제 #9
0
    def add_eapol_flow(self,
                       intf_id,
                       onu_id,
                       uplink_eapol_id=EAPOL_FLOW_INDEX,
                       downlink_eapol_id=EAPOL_DOWNLINK_FLOW_INDEX,
                       vlan_id=DEFAULT_MGMT_VLAN):

        # self.log.debug('add eapol flow pre-process',
        #                classifier=uplink_classifier)
        #                #action=uplink_action)

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

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

        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 = platform.mk_gemport_id(onu_id)

        self.log.debug('add eapol flow',
                       uplink_classifier=uplink_classifier,
                       uplink_action=uplink_action,
                       downlink_classifier=downlink_classifier,
                       downlink_action=downlink_action)
        # Add Upstream EAPOL Flow.

        uplink_flow_id = 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,
            classifier=self.mk_classifier(uplink_classifier),
            action=self.mk_action(uplink_action))

        self.stub.FlowAdd(upstream_flow)

        # Add Downstream EAPOL Flow.
        downlink_flow_id = 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,
            classifier=self.mk_classifier(downlink_classifier),
            action=self.mk_action(downlink_action))

        self.stub.FlowAdd(downstream_flow)

        self.log.debug('eap flows',
                       upstream_flow=upstream_flow,
                       downstream_flow=downstream_flow)