Exemple #1
0
        def leaf_device_default_rules(device):
            ports = self.root_proxy.get('/devices/{}/ports'.format(device.id))
            upstream_ports = [
                port for port in ports if port.type == Port.PON_ONU \
                                            or port.type == Port.VENET_ONU
            ]
            assert len(upstream_ports) == 1
            downstream_ports = [
                port for port in ports if port.type == Port.ETHERNET_UNI
            ]

            # it is possible that the downstream ports are not
            # created, but the flow_decomposition has already
            # kicked in. In such scenarios, cut short the processing
            # and return.
            if len(downstream_ports) == 0:
                return None, None
            # assert len(downstream_ports) == 1
            upstream_port  = upstream_ports[0]
            flows = OrderedDict()
            for downstream_port in downstream_ports:
                flows.update(OrderedDict((f.id, f) for f in [
                    mk_flow_stat(
                        priority=500,
                        match_fields=[
                            in_port(downstream_port.port_no),
                            vlan_vid(ofp.OFPVID_PRESENT | 0)
                        ],
                        actions=[
                            set_field(vlan_vid(ofp.OFPVID_PRESENT | device.vlan)),
                            output(upstream_port.port_no)
                        ]
                    ),
                    mk_flow_stat(
                        priority=500,
                        match_fields=[
                            in_port(downstream_port.port_no),
                            vlan_vid(0)
                        ],
                        actions=[
                            push_vlan(0x8100),
                            set_field(vlan_vid(ofp.OFPVID_PRESENT | device.vlan)),
                            output(upstream_port.port_no)
                        ]
                    ),
                    mk_flow_stat(
                        priority=500,
                        match_fields=[
                            in_port(upstream_port.port_no),
                            vlan_vid(ofp.OFPVID_PRESENT | device.vlan)
                        ],
                        actions=[
                            set_field(vlan_vid(ofp.OFPVID_PRESENT | 0)),
                            output(downstream_port.port_no)
                        ]
                    ),
                ]))
            groups = OrderedDict()
            return flows, groups
 def leaf_device_default_rules(device):
     ports = self.root_proxy.get('/devices/{}/ports'.format(device.id))
     upstream_ports = [
         port for port in ports if port.type == Port.PON_ONU \
                                     or port.type == Port.VENET_ONU
     ]
     assert len(upstream_ports) == 1
     downstream_ports = [
         port for port in ports if port.type == Port.ETHERNET_UNI
     ]
     # assert len(downstream_ports) == 1
     flows = OrderedDict((f.id, f) for f in [
         mk_flow_stat(
             priority=500,
             match_fields=[
                 in_port(downstream_ports[0].port_no),
                 vlan_vid(ofp.OFPVID_PRESENT | 0)
             ],
             actions=[
                 set_field(vlan_vid(ofp.OFPVID_PRESENT | device.vlan)),
                 output(upstream_ports[0].port_no)
             ]
         ),
         mk_flow_stat(
             priority=500,
             match_fields=[
                 in_port(downstream_ports[0].port_no),
                 vlan_vid(0)
             ],
             actions=[
                 push_vlan(0x8100),
                 set_field(vlan_vid(ofp.OFPVID_PRESENT | device.vlan)),
                 output(upstream_ports[0].port_no)
             ]
         ),
         mk_flow_stat(
             priority=500,
             match_fields=[
                 in_port(upstream_ports[0].port_no),
                 vlan_vid(ofp.OFPVID_PRESENT | device.vlan)
             ],
             actions=[
                 set_field(vlan_vid(ofp.OFPVID_PRESENT | 0)),
                 output(downstream_ports[0].port_no)
             ]
         ),
     ])
     groups = OrderedDict()
     return flows, groups
 def leaf_device_default_rules(device):
     ports = self.root_proxy.get('/devices/{}/ports'.format(device.id))
     upstream_ports = [
         port for port in ports if port.type == Port.PON_ONU \
                                     or port.type == Port.VENET_ONU
     ]
     assert len(upstream_ports) == 1
     downstream_ports = [
         port for port in ports if port.type == Port.ETHERNET_UNI
     ]
     # assert len(downstream_ports) == 1
     flows = OrderedDict((f.id, f) for f in [
         mk_flow_stat(
             priority=500,
             match_fields=[
                 in_port(downstream_ports[0].port_no),
                 vlan_vid(ofp.OFPVID_PRESENT | 0)
             ],
             actions=[
                 set_field(vlan_vid(ofp.OFPVID_PRESENT | device.vlan)),
                 output(upstream_ports[0].port_no)
             ]
         ),
         mk_flow_stat(
             priority=500,
             match_fields=[
                 in_port(downstream_ports[0].port_no),
                 vlan_vid(0)
             ],
             actions=[
                 push_vlan(0x8100),
                 set_field(vlan_vid(ofp.OFPVID_PRESENT | device.vlan)),
                 output(upstream_ports[0].port_no)
             ]
         ),
         mk_flow_stat(
             priority=500,
             match_fields=[
                 in_port(upstream_ports[0].port_no),
                 vlan_vid(ofp.OFPVID_PRESENT | device.vlan)
             ],
             actions=[
                 set_field(vlan_vid(ofp.OFPVID_PRESENT | 0)),
                 output(downstream_ports[0].port_no)
             ]
         ),
     ])
     groups = OrderedDict()
     return flows, groups
 def root_device_default_rules(device):
     ports = self.root_proxy.get('/devices/{}/ports'.format(device.id))
     upstream_ports = [
         port for port in ports if port.type == Port.ETHERNET_NNI
     ]
     assert len(upstream_ports) == 1
     downstream_ports = [
         port for port in ports if port.type == Port.PON_OLT \
                                     or port.type == Port.VENET_OLT
     ]
     _is_any_venet_port = any(_port.type == Port.VENET_OLT for _port in
                           downstream_ports)
     if _is_any_venet_port != True:
         assert len(downstream_ports) == 1, \
             'Initially, we only handle one PON port'
     flows = OrderedDict((f.id, f) for f in [
         mk_flow_stat(
             priority=2000,
             match_fields=[
                 in_port(upstream_ports[0].port_no),
                 vlan_vid(ofp.OFPVID_PRESENT | 4000),
                 vlan_pcp(0)
             ],
             actions=[
                 pop_vlan(),
                 output(downstream_ports[0].port_no)
             ]
         )
     ])
     groups = OrderedDict()
     return flows, groups
Exemple #5
0
    def _list_and_update_logical_device_flows(self, id):

        # retrieve flow list
        res = self.get('/api/v1/logical_devices/{}/flows'.format(id))
        len_before = len(res['items'])

        # add some flows
        req = ofp.FlowTableUpdate(
            id=id,
            flow_mod=mk_simple_flow_mod(
                cookie=randint(1, 10000000000),
                priority=len_before,
                match_fields=[
                    in_port(129)
                ],
                actions=[
                    output(1)
                ]
            )
        )
        res = self.post('/api/v1/logical_devices/{}/flows'.format(id),
                        MessageToDict(req, preserving_proto_field_name=True),
                        expected_http_code=200)
        # TODO check some stuff on res

        res = self.get('/api/v1/logical_devices/{}/flows'.format(id))
        len_after = len(res['items'])
        self.assertGreater(len_after, len_before)
Exemple #6
0
    def _list_and_update_local_logical_device_flows(self, id):

        # retrieve flow list
        res = self.get('/api/v1/local/logical_devices/{}/flows'.format(id))
        len_before = len(res['items'])

        t0 = time()
        # add some flows
        for _ in xrange(10):
            req = ofp.FlowTableUpdate(
                id=id,
                flow_mod=mk_simple_flow_mod(
                    cookie=randint(1, 10000000000),
                    priority=randint(1, 10000),  # to make it unique
                    match_fields=[
                        in_port(129)
                    ],
                    actions=[
                        output(1)
                    ]
                )
            )
            self.post('/api/v1/local/logical_devices/{}/flows'.format(id),
                      MessageToDict(req, preserving_proto_field_name=True),
                      expected_http_code=200)
        print time() - t0

        res = self.get('/api/v1/local/logical_devices/{}/flows'.format(id))
        len_after = len(res['items'])
        self.assertGreater(len_after, len_before)
Exemple #7
0
    def handle_packet_in_event(self, logical_port_no, packet):
        self.log.debug('handle-packet-in', logical_port_no=logical_port_no)
        packet_in = ofp.ofp_packet_in(
            # buffer_id=0,
            reason=ofp.OFPR_ACTION,
            # table_id=0,
            # cookie=0,
            match=ofp.ofp_match(
                type=ofp.OFPMT_OXM,
                oxm_fields=[
                    ofp.ofp_oxm_field(
                        oxm_class=ofp.OFPXMC_OPENFLOW_BASIC,
                        ofb_field=in_port(logical_port_no)
                    )
                ]
            ),
            data=packet
        )

        packet_in = ofp.PacketIn(id=self.device.data_model.logical_device_id,
                                 packet_in=packet_in)
        '''
        # FIXME - change this to use kafka
        lh = self.device.data_model.adapter_agent.core.get_local_handler()
        lh.core.packet_in_queue.put(packet_in)
        '''

        kafka_send_pb('voltha.pktin', packet_in)
    def _list_and_update_local_logical_device_flows(self, id):

        # retrieve flow list
        res = self.get('/api/v1/local/logical_devices/{}/flows'.format(id))
        len_before = len(res['items'])

        t0 = time()
        # add some flows
        for _ in xrange(10):
            req = ofp.FlowTableUpdate(
                id=id,
                flow_mod=mk_simple_flow_mod(
                    cookie=randint(1, 10000000000),
                    priority=randint(1, 10000),  # to make it unique
                    match_fields=[
                        in_port(129)
                    ],
                    actions=[
                        output(1)
                    ]
                )
            )
            self.post('/api/v1/local/logical_devices/{}/flows'.format(id),
                      MessageToDict(req, preserving_proto_field_name=True),
                      expected_http_code=200)
        print time() - t0

        res = self.get('/api/v1/local/logical_devices/{}/flows'.format(id))
        len_after = len(res['items'])
        self.assertGreater(len_after, len_before)
    def _list_and_update_logical_device_flows(self, id):

        # retrieve flow list
        res = self.get('/api/v1/logical_devices/{}/flows'.format(id))
        len_before = len(res['items'])

        # add some flows
        req = ofp.FlowTableUpdate(
            id=id,
            flow_mod=mk_simple_flow_mod(
                cookie=randint(1, 10000000000),
                priority=len_before,
                match_fields=[
                    in_port(129)
                ],
                actions=[
                    output(1)
                ]
            )
        )
        res = self.post('/api/v1/logical_devices/{}/flows'.format(id),
                        MessageToDict(req, preserving_proto_field_name=True),
                        expected_http_code=200)
        # TODO check some stuff on res

        res = self.get('/api/v1/logical_devices/{}/flows'.format(id))
        len_after = len(res['items'])
        self.assertGreater(len_after, len_before)
Exemple #10
0
    def update_flow_table(self, flows):
        stub = ponsim_pb2_grpc.PonSimStub(self.get_channel())
        self.log.info('pushing-olt-flow-table')

        eapol_flows = {}
        eapol_flow_without_vlan = False

        for flow in flows:
            classifier_info = self.get_classifier_info(flow)

            self.log.debug('classifier_info', classifier_info=classifier_info)

            if IP_PROTO in classifier_info:
                if classifier_info[IP_PROTO] == 17:
                    if UDP_SRC in classifier_info:
                        if classifier_info[UDP_SRC] == 68:
                            self.log.info('dhcp upstream flow add')
                        elif classifier_info[UDP_SRC] == 67:
                            self.log.info('dhcp downstream flow add')
                    self.to_controller(flow)
                elif classifier_info[IP_PROTO] == 2:
                    self.log.info('igmp flow add')
                    self.to_controller(flow)
                else:
                    self.log.warn("Invalid-Classifier-to-handle",
                                   classifier_info=classifier_info)
            elif ETH_TYPE in classifier_info:
                if classifier_info[ETH_TYPE] == EAP_ETH_TYPE:
                    self.log.info('eapol flow add')
                    self.to_controller(flow)
                    if VLAN_VID in classifier_info:
                        eapol_flows[classifier_info[VLAN_VID]] = flow
                    else:
                        eapol_flow_without_vlan = True

        # The OLT app is now adding EAPOL flows with VLAN_VID=4091 but Ponsim can't
        # properly handle this because it uses VLAN_VID to encode the UNI port ID.
        # Add an EAPOL trap flow with no VLAN_VID match if we see the 4091 match.
        if 4091 in eapol_flows and not eapol_flow_without_vlan:
            new_eapol_flow = [
                fd.mk_flow_stat(
                    priority=10000,
                    match_fields=[fd.in_port(1), fd.eth_type(EAP_ETH_TYPE)],
                    actions=[fd.output(ofp.OFPP_CONTROLLER)]
                )
            ]
            flows.extend(new_eapol_flow)
            self.log.info('add eapol flow with no VLAN_VID match')

        stub.UpdateFlowTable(FlowTable(
            port=0,
            flows=flows
        ))
        self.log.info('success')
Exemple #11
0
 def handle_packet_in_event(self, _, msg):
     self.log.debug('handle-packet-in', msg=msg)
     logical_port_no, packet = msg
     packet_in = ofp.ofp_packet_in(
         # buffer_id=0,
         reason=ofp.OFPR_ACTION,
         # table_id=0,
         # cookie=0,
         match=ofp.ofp_match(type=ofp.OFPMT_OXM,
                             oxm_fields=[
                                 ofp.ofp_oxm_field(
                                     oxm_class=ofp.OFPXMC_OPENFLOW_BASIC,
                                     ofb_field=in_port(logical_port_no))
                             ]),
         data=packet)
     self.packet_in(packet_in)
 def handle_packet_in_event(self, _, msg):
     self.log.debug('handle-packet-in', msg=msg)
     logical_port_no, packet = msg
     packet_in = ofp.ofp_packet_in(
         # buffer_id=0,
         reason=ofp.OFPR_ACTION,
         # table_id=0,
         # cookie=0,
         match=ofp.ofp_match(
             type=ofp.OFPMT_OXM,
             oxm_fields=[
                 ofp.ofp_oxm_field(
                     oxm_class=ofp.OFPXMC_OPENFLOW_BASIC,
                     ofb_field=in_port(logical_port_no)
                 )
             ]
         ),
         data=packet
     )
     self.packet_in(packet_in)
    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)
Exemple #14
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)
Exemple #15
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)
Exemple #16
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)