class TestAttachServiceWithMultiPdnsAndBearers(unittest.TestCase):
    def setUp(self):
        self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
        self._sessionManager_util = SessionManagerUtil()

    def tearDown(self):
        self._s1ap_wrapper.cleanup()

    def test_attach_service_with_multi_pdns_and_bearers(self):
        """
        Test with a single UE attach + add secondary PDN
        + add 2 dedicated bearers + UE context release + service request
        + detach"""
        self._s1ap_wrapper.configUEDevice(1)
        req = self._s1ap_wrapper.ue_req
        ue_id = req.ue_id
        # APN of the secondary PDN
        ims = {
            "apn_name": "ims",  # APN-name
            "qci": 5,  # qci
            "priority": 15,  # priority
            "pre_cap": 0,  # preemption-capability
            "pre_vul": 0,  # preemption-vulnerability
            "mbr_ul": 200000000,  # MBR UL
            "mbr_dl": 100000000,  # MBR DL
        }

        # APN list to be configured
        apn_list = [ims]

        self._s1ap_wrapper.configAPN(
            "IMSI" + "".join([str(i) for i in req.imsi]), apn_list)
        print(
            "************************* Running End to End attach for UE id ",
            ue_id,
        )

        # UL Flow description #1
        ulFlow1 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5002,  # TCP dest port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "UL",  # Direction
        }

        # UL Flow description #2
        ulFlow2 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5001,  # TCP dest port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "UL",  # Direction
        }

        # UL Flow description #3
        ulFlow3 = {
            "ipv4_dst": "192.168.129.64",  # IPv4 destination address
            "tcp_dst_port": 5003,  # TCP dest port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "UL",  # Direction
        }

        # UL Flow description #4
        ulFlow4 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5001,  # TCP dest port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "UL",  # Direction
        }
        # DL Flow description #1
        dlFlow1 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5001,  # TCP source port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "DL",  # Direction
        }

        # DL Flow description #2
        dlFlow2 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5002,  # TCP source port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "DL",  # Direction
        }

        # DL Flow description #3
        dlFlow3 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5003,  # TCP source port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "DL",  # Direction
        }

        # DL Flow description #4
        dlFlow4 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5001,  # TCP source port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "DL",  # Direction
        }

        # Flow lists to be configured
        flow_list1 = [
            ulFlow1,
            ulFlow2,
            ulFlow3,
            dlFlow1,
            dlFlow2,
            dlFlow3,
        ]

        flow_list2 = [
            ulFlow4,
            dlFlow4,
        ]

        # QoS
        qos1 = {
            "qci": 1,  # qci value [1 to 9]
            "priority": 1,  # Range [0-255]
            "max_req_bw_ul": 10000000,  # MAX bw Uplink
            "max_req_bw_dl": 15000000,  # MAX bw Downlink
            "gbr_ul": 1000000,  # GBR Uplink
            "gbr_dl": 2000000,  # GBR Downlink
            "arp_prio": 1,  # ARP priority
            "pre_cap": 1,  # pre-emption capability
            "pre_vul": 1,  # pre-emption vulnerability
        }

        qos2 = {
            "qci": 2,  # qci value [1 to 9]
            "priority": 5,  # Range [0-255]
            "max_req_bw_ul": 10000000,  # MAX bw Uplink
            "max_req_bw_dl": 15000000,  # MAX bw Downlink
            "gbr_ul": 1000000,  # GBR Uplink
            "gbr_dl": 2000000,  # GBR Downlink
            "arp_prio": 1,  # ARP priority
            "pre_cap": 1,  # pre-emption capability
            "pre_vul": 1,  # pre-emption vulnerability
        }

        policy_id1 = "internet"
        policy_id2 = "ims"

        # Now actually complete the attach
        attach = self._s1ap_wrapper._s1_util.attach(
            ue_id,
            s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
            s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
            s1ap_types.ueAttachAccept_t,
        )
        addr = attach.esmInfo.pAddr.addrInfo
        default_ip = ipaddress.ip_address(bytes(addr[:4]))

        # Wait on EMM Information from MME
        self._s1ap_wrapper._s1_util.receive_emm_info()

        # Delay to ensure S1APTester sends attach complete before sending UE
        # context release
        print("Sleeping for 5 seconds")
        time.sleep(5)

        # Add dedicated bearer for default bearer 5
        print("********************** Adding dedicated bearer to magma.ipv4"
              " PDN")
        print(
            "********************** Sending RAR for IMSI",
            "".join([str(i) for i in req.imsi]),
        )
        self._sessionManager_util.create_ReAuthRequest(
            "IMSI" + "".join([str(i) for i in req.imsi]),
            policy_id1,
            flow_list1,
            qos1,
        )

        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(response.msg_type,
                         s1ap_types.tfwCmd.UE_ACT_DED_BER_REQ.value)
        act_ded_ber_req_oai_apn = response.cast(
            s1ap_types.UeActDedBearCtxtReq_t)
        self._s1ap_wrapper.sendActDedicatedBearerAccept(
            req.ue_id, act_ded_ber_req_oai_apn.bearerId)

        print("Sleeping for 5 seconds")
        time.sleep(5)
        # Send PDN Connectivity Request
        apn = "ims"
        self._s1ap_wrapper.sendPdnConnectivityReq(ue_id, apn)
        # Receive PDN CONN RSP/Activate default EPS bearer context request
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(response.msg_type,
                         s1ap_types.tfwCmd.UE_PDN_CONN_RSP_IND.value)
        act_def_bearer_req = response.cast(s1ap_types.uePdnConRsp_t)
        addr = act_def_bearer_req.m.pdnInfo.pAddr.addrInfo
        sec_ip = ipaddress.ip_address(bytes(addr[:4]))

        print(
            "********************** Sending Activate default EPS bearer "
            "context accept for UE id ",
            ue_id,
        )

        print("Sleeping for 5 seconds")
        time.sleep(5)
        # Add dedicated bearer to 2nd PDN
        print("********************** Adding dedicated bearer to ims PDN")
        print(
            "********************** Sending RAR for IMSI",
            "".join([str(i) for i in req.imsi]),
        )
        self._sessionManager_util.create_ReAuthRequest(
            "IMSI" + "".join([str(i) for i in req.imsi]),
            policy_id2,
            flow_list2,
            qos2,
        )

        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(response.msg_type,
                         s1ap_types.tfwCmd.UE_ACT_DED_BER_REQ.value)
        act_ded_ber_req_ims_apn = response.cast(
            s1ap_types.UeActDedBearCtxtReq_t)
        self._s1ap_wrapper.sendActDedicatedBearerAccept(
            req.ue_id, act_ded_ber_req_ims_apn.bearerId)
        print(
            "************* Added dedicated bearer",
            act_ded_ber_req_ims_apn.bearerId,
        )

        print("Sleeping for 5 seconds")
        time.sleep(5)

        dl_flow_rules = {
            default_ip: [flow_list1],
            sec_ip: [flow_list2],
        }
        # 1 UL flow is created per bearer
        num_ul_flows = 4
        # Verify if flow rules are created
        self._s1ap_wrapper.s1_util.verify_flow_rules(num_ul_flows,
                                                     dl_flow_rules)
        print("*********** Moving UE to idle mode")
        print(
            "************* Sending UE context release request ",
            "for UE id ",
            ue_id,
        )
        # Send UE context release request to move UE to idle mode
        req = s1ap_types.ueCntxtRelReq_t()
        req.ue_Id = ue_id
        req.cause.causeVal = gpp_types.CauseRadioNetwork.USER_INACTIVITY.value
        self._s1ap_wrapper.s1_util.issue_cmd(
            s1ap_types.tfwCmd.UE_CNTXT_REL_REQUEST, req)
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(response.msg_type,
                         s1ap_types.tfwCmd.UE_CTX_REL_IND.value)

        print("Sleeping for 5 seconds")
        time.sleep(5)

        # Verify if paging flow rules are created
        ip_list = [default_ip, sec_ip]
        self._s1ap_wrapper.s1_util.verify_paging_flow_rules(ip_list)

        print(
            "************************* Sending Service request for UE id ",
            ue_id,
        )
        # Send service request to reconnect UE
        req = s1ap_types.ueserviceReq_t()
        req.ue_Id = ue_id
        req.ueMtmsi = s1ap_types.ueMtmsi_t()
        req.ueMtmsi.pres = False
        req.rrcCause = s1ap_types.Rrc_Cause.TFW_MO_SIGNALLING.value
        self._s1ap_wrapper.s1_util.issue_cmd(
            s1ap_types.tfwCmd.UE_SERVICE_REQUEST, req)
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(response.msg_type,
                         s1ap_types.tfwCmd.INT_CTX_SETUP_IND.value)

        print("Sleeping for 5 seconds")
        time.sleep(5)

        # Verify if flow rules are created
        self._s1ap_wrapper.s1_util.verify_flow_rules(num_ul_flows,
                                                     dl_flow_rules)

        print("Sleeping for 5 seconds")
        time.sleep(5)
        print("************************* Running UE detach for UE id ", ue_id)
        # Now detach the UE
        self._s1ap_wrapper.s1_util.detach(
            ue_id, s1ap_types.ueDetachType_t.UE_SWITCHOFF_DETACH.value, True)
Ejemplo n.º 2
0
class TestDedicatedBearerActivationIdleModePagingTmrExpiry(unittest.TestCase):
    def setUp(self):
        self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
        self._sessionManager_util = SessionManagerUtil()

    def tearDown(self):
        self._s1ap_wrapper.cleanup()

    def test_dedicated_bearer_activation_idle_mode_pag_tmr_exp(self):
        """
        Test with a single UE attach + UE context release
        + dedicated bearer activation + page the UE + Paging timer expires
        + send dedicated bearer activation reject to SPGW"""
        self._s1ap_wrapper.configUEDevice(1)
        req = self._s1ap_wrapper.ue_req
        ue_id = req.ue_id
        imsi = req.imsi

        # Add dedicated bearer for default bearer 5
        # UL Flow description #1
        ulFlow1 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5002,  # TCP dest port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "UL",  # Direction
        }

        # UL Flow description #2
        ulFlow2 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5001,  # TCP dest port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "UL",  # Direction
        }

        # UL Flow description #3
        ulFlow3 = {
            "ipv4_dst": "192.168.129.64",  # IPv4 destination address
            "tcp_dst_port": 5003,  # TCP dest port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "UL",  # Direction
        }

        # UL Flow description #4
        ulFlow4 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5004,  # TCP dest port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "UL",  # Direction
        }

        # DL Flow description #1
        dlFlow1 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5001,  # TCP source port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "DL",  # Direction
        }

        # DL Flow description #2
        dlFlow2 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5002,  # TCP source port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "DL",  # Direction
        }
        # DL Flow description #3
        dlFlow3 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5003,  # TCP source port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "DL",  # Direction
        }

        # DL Flow description #4
        dlFlow4 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5004,  # TCP source port
            "ip_proto": "TCP",  # Protocol Type
            "direction": "DL",  # Direction
        }

        # Flow list to be configured
        flow_list = [
            ulFlow1,
            ulFlow2,
            ulFlow3,
            ulFlow4,
            dlFlow1,
            dlFlow2,
            dlFlow3,
            dlFlow4,
        ]

        # QoS
        qos = {
            "qci": 1,  # qci value [1 to 9]
            "priority": 1,  # Range [0-255]
            "max_req_bw_ul": 10000000,  # MAX bw Uplink
            "max_req_bw_dl": 15000000,  # MAX bw Downlink
            "gbr_ul": 1000000,  # GBR Uplink
            "gbr_dl": 2000000,  # GBR Downlink
            "arp_prio": 1,  # ARP priority
            "pre_cap": 1,  # pre-emption capability
            "pre_vul": 1,  # pre-emption vulnerability
        }

        policy_id = "internet"

        print("*********** Running End to End attach for UE id ", ue_id)
        attach = self._s1ap_wrapper._s1_util.attach(
            ue_id,
            s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
            s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
            s1ap_types.ueAttachAccept_t,
        )
        addr = attach.esmInfo.pAddr.addrInfo
        default_ip = ipaddress.ip_address(bytes(addr[:4]))

        # Wait on EMM Information from MME
        self._s1ap_wrapper._s1_util.receive_emm_info()

        # Delay to ensure S1APTester sends attach complete before sending UE
        # context release
        print("*********** Sleeping for 5 seconds")
        time.sleep(5)

        print("*********** Moving UE to idle mode")
        print(
            "*********** Sending UE context release request ",
            "for UE id ",
            ue_id,
        )
        # Send UE context release request to move UE to idle mode
        req = s1ap_types.ueCntxtRelReq_t()
        req.ue_Id = ue_id
        req.cause.causeVal = gpp_types.CauseRadioNetwork.USER_INACTIVITY.value
        self._s1ap_wrapper.s1_util.issue_cmd(
            s1ap_types.tfwCmd.UE_CNTXT_REL_REQUEST, req
        )
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.UE_CTX_REL_IND.value
        )

        # Verify if paging flow rules are created
        ip_list = [default_ip]
        self._s1ap_wrapper.s1_util.verify_paging_flow_rules(ip_list)

        print("Sleeping for 5 seconds")
        time.sleep(5)
        print(
            "************* Adding dedicated bearer to magma.ipv4"
            " PDN in idle mode"
        )
        print(
            "************* Sending RAR for IMSI",
            "".join([str(i) for i in imsi]),
        )
        self._sessionManager_util.create_ReAuthRequest(
            "IMSI" + "".join([str(i) for i in imsi]),
            policy_id,
            flow_list,
            qos,
        )

        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.UE_PAGING_IND.value
        )

        print("*********** Received Paging for UE id ", ue_id)

        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.UE_PAGING_IND.value
        )

        print("*********** Received second Paging for UE id ", ue_id)

        print("*********** Sleeping for 5 seconds")
        time.sleep(5)
        print("*********** Running UE detach for UE id ", ue_id)

        # Now detach the UE
        detach_req = s1ap_types.uedetachReq_t()
        detach_req.ue_Id = ue_id
        detach_req.ueDetType = (
            s1ap_types.ueDetachType_t.UE_SWITCHOFF_DETACH.value
        )
        self._s1ap_wrapper._s1_util.issue_cmd(
            s1ap_types.tfwCmd.UE_DETACH_REQUEST, detach_req
        )
Ejemplo n.º 3
0
class TestAttachDetachRarTcpData(unittest.TestCase):
    SPGW_TABLE = 0
    LOCAL_PORT = "LOCAL"

    def setUp(self):
        self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
        self._sessionManager_util = SessionManagerUtil()
        self._spgw_util = SpgwUtil()

    def tearDown(self):
        self._s1ap_wrapper.cleanup()

    def test_attach_detach_rar_tcp_data(self):
        """ attach/detach + send ReAuth Req to session manager with a"""
        """ single UE """
        num_ues = 1
        detach_type = [
            s1ap_types.ueDetachType_t.UE_NORMAL_DETACH.value,
            s1ap_types.ueDetachType_t.UE_SWITCHOFF_DETACH.value,
        ]
        wait_for_s1 = [True, False]
        self._s1ap_wrapper.configUEDevice(num_ues)
        datapath = get_datapath()
        MAX_NUM_RETRIES = 5
        gtp_br_util = GTPBridgeUtils()
        GTP_PORT = gtp_br_util.get_gtp_port_no()

        for i in range(num_ues):
            req = self._s1ap_wrapper.ue_req
            print(
                "********************** Running End to End attach for ",
                "UE id ",
                req.ue_id,
            )
            # Now actually complete the attach
            self._s1ap_wrapper._s1_util.attach(
                req.ue_id,
                s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
                s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
                s1ap_types.ueAttachAccept_t,
            )

            # Wait on EMM Information from MME
            self._s1ap_wrapper._s1_util.receive_emm_info()

            # UL Flow description #1
            ulFlow1 = {
                "ipv4_dst": "192.168.129.42",  # IPv4 destination address
                "tcp_dst_port": 5002,  # TCP dest port
                "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
                "direction": FlowMatch.UPLINK,  # Direction
            }

            # UL Flow description #2
            ulFlow2 = {
                "ipv4_dst": "192.168.129.42",  # IPv4 destination address
                "tcp_dst_port": 5001,  # TCP dest port
                "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
                "direction": FlowMatch.UPLINK,  # Direction
            }

            # UL Flow description #3
            ulFlow3 = {
                "ipv4_dst": "192.168.129.64",  # IPv4 destination address
                "tcp_dst_port": 5003,  # TCP dest port
                "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
                "direction": FlowMatch.UPLINK,  # Direction
            }

            # UL Flow description #4
            ulFlow4 = {
                "ipv4_dst": "192.168.129.42",  # IPv4 destination address
                "tcp_dst_port": 5004,  # TCP dest port
                "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
                "direction": FlowMatch.UPLINK,  # Direction
            }

            # DL Flow description #1
            dlFlow1 = {
                "ipv4_src": "192.168.129.42",  # IPv4 source address
                "tcp_src_port": 5001,  # TCP source port
                "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
                "direction": FlowMatch.DOWNLINK,  # Direction
            }

            # DL Flow description #2
            dlFlow2 = {
                "ipv4_src": "192.168.129.64",  # IPv4 source address
                "tcp_src_port": 5002,  # TCP source port
                "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
                "direction": FlowMatch.DOWNLINK,  # Direction
            }

            # DL Flow description #3
            dlFlow3 = {
                "ipv4_src": "192.168.129.64",  # IPv4 source address
                "tcp_src_port": 5003,  # TCP source port
                "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
                "direction": FlowMatch.DOWNLINK,  # Direction
            }

            # DL Flow description #4
            dlFlow4 = {
                "ipv4_src": "192.168.129.42",  # IPv4 source address
                "tcp_src_port": 5004,  # TCP source port
                "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
                "direction": FlowMatch.DOWNLINK,  # Direction
            }

            # Flow list to be configured
            flow_list = [
                ulFlow1,
                ulFlow2,
                ulFlow3,
                ulFlow4,
                dlFlow1,
                dlFlow2,
                dlFlow3,
                dlFlow4,
            ]

            # QoS
            qos = {
                "qci": 5,  # qci value [1 to 9]
                "priority": 15,  # Range [0-255]
                "max_req_bw_ul": 10000000,  # MAX bw Uplink
                "max_req_bw_dl": 15000000,  # MAX bw Downlink
                "gbr_ul": 1000000,  # GBR Uplink
                "gbr_dl": 2000000,  # GBR Downlink
                "arp_prio": 15,  # ARP priority
                "pre_cap": 1,  # pre-emption capability
                "pre_vul": 1,  # pre-emption vulnerability
            }

            policy_id = "ims-voice"

            print("Sleeping for 5 seconds")
            time.sleep(5)
            print(
                "********************** Sending RAR for IMSI",
                "".join([str(i) for i in req.imsi]),
            )
            self._sessionManager_util.create_ReAuthRequest(
                "IMSI" + "".join([str(i) for i in req.imsi]),
                policy_id,
                flow_list,
                qos,
            )

            # Receive Activate dedicated bearer request
            response = self._s1ap_wrapper.s1_util.get_response()
            self.assertEqual(response.msg_type,
                             s1ap_types.tfwCmd.UE_ACT_DED_BER_REQ.value)
            act_ded_ber_ctxt_req = response.cast(
                s1ap_types.UeActDedBearCtxtReq_t)

            print("Sleeping for 5 seconds")
            time.sleep(5)
            # Send Activate dedicated bearer accept
            self._s1ap_wrapper.sendActDedicatedBearerAccept(
                req.ue_id, act_ded_ber_ctxt_req.bearerId)

            # Check if UL and DL OVS flows are created
            # UPLINK
            print("Checking for uplink flow")
            # try at least 5 times before failing as gateway
            # might take some time to install the flows in ovs
            for i in range(MAX_NUM_RETRIES):
                print("Get uplink flows: attempt ", i)
                uplink_flows = get_flows(
                    datapath,
                    {
                        "table_id": self.SPGW_TABLE,
                        "match": {
                            "in_port": GTP_PORT
                        },
                    },
                )
                if len(uplink_flows) > 1:
                    break
                time.sleep(5)  # sleep for 5 seconds before retrying

            assert len(uplink_flows) > 1, "Uplink flow missing for UE"
            self.assertIsNotNone(
                uplink_flows[0]["match"]["tunnel_id"],
                "Uplink flow missing tunnel id match",
            )

            # DOWNLINK
            print("Checking for downlink flow")
            ue_ip = str(self._s1ap_wrapper._s1_util.get_ip(req.ue_id))
            # try at least 5 times before failing as gateway
            # might take some time to install the flows in ovs
            for i in range(MAX_NUM_RETRIES):
                print("Get downlink flows: attempt ", i)
                downlink_flows = get_flows(
                    datapath,
                    {
                        "table_id": self.SPGW_TABLE,
                        "match": {
                            "nw_dst": ue_ip,
                            "eth_type": 2048,
                            "in_port": self.LOCAL_PORT,
                        },
                    },
                )
                if len(downlink_flows) > 1:
                    break
                time.sleep(5)  # sleep for 5 seconds before retrying

            assert len(downlink_flows) > 1, "Downlink flow missing for UE"
            self.assertEqual(
                downlink_flows[0]["match"]["ipv4_dst"],
                ue_ip,
                "UE IP match missing from downlink flow",
            )

            actions = downlink_flows[0]["instructions"][0]["actions"]
            has_tunnel_action = any(action for action in actions
                                    if action["field"] == "tunnel_id"
                                    and action["type"] == "SET_FIELD")
            self.assertTrue(has_tunnel_action,
                            "Downlink flow missing set tunnel action")

            print("Sleeping for 5 seconds")
            time.sleep(5)
            with self._s1ap_wrapper.configUplinkTest(req, duration=1) as test:
                test.verify()

            print(
                "********************** Deleting dedicated bearer for IMSI",
                "".join([str(i) for i in req.imsi]),
            )
            self._spgw_util.delete_bearer(
                "IMSI" + "".join([str(i) for i in req.imsi]), 5, 6)

            response = self._s1ap_wrapper.s1_util.get_response()
            self.assertEqual(
                response.msg_type,
                s1ap_types.tfwCmd.UE_DEACTIVATE_BER_REQ.value,
            )

            print("******************* Received deactivate eps bearer context")

            deactv_bearer_req = response.cast(s1ap_types.UeDeActvBearCtxtReq_t)
            self._s1ap_wrapper.sendDeactDedicatedBearerAccept(
                req.ue_id, deactv_bearer_req.bearerId)

            print("Sleeping for 5 seconds")
            time.sleep(5)

            print(
                "********************** Running UE detach for UE id ",
                req.ue_id,
            )
            # Now detach the UE
            self._s1ap_wrapper.s1_util.detach(req.ue_id, detach_type[i],
                                              wait_for_s1[i])

            print("Checking that uplink/downlink flows were deleted")
            flows = get_flows(datapath, {
                "table_id": self.SPGW_TABLE,
                "priority": 0
            })
            self.assertEqual(len(flows), 2,
                             "There should only be 2 default table 0 flows")
class TestOutOfOrderErabSetupRspDedicatedBearer(unittest.TestCase):
    def setUp(self):
        self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
        self._sessionManager_util = SessionManagerUtil()

    def tearDown(self):
        self._s1ap_wrapper.cleanup()

    def test_outoforder_erab_setup_rsp_dedicated_bearer(self):
        """ Attach a single UE + add dedicated bearer + send erab setup rsp
        message out of order for the dedicated bearer"""
        num_ue = 1

        self._s1ap_wrapper.configUEDevice(num_ue)
        req = self._s1ap_wrapper.ue_req
        ue_id = req.ue_id

        # UL Flow description #1
        ulFlow1 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5002,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #2
        ulFlow2 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5001,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #3
        ulFlow3 = {
            "ipv4_dst": "192.168.129.64",  # IPv4 destination address
            "tcp_dst_port": 5003,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #4
        ulFlow4 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5004,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # DL Flow description #1
        dlFlow1 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5001,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #2
        dlFlow2 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5002,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #3
        dlFlow3 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5003,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #4
        dlFlow4 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5004,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # Flow list to be configured
        flow_list = [
            ulFlow1,
            ulFlow2,
            ulFlow3,
            ulFlow4,
            dlFlow1,
            dlFlow2,
            dlFlow3,
            dlFlow4,
        ]

        # QoS
        qos = {
            "qci": 1,  # qci value [1 to 9]
            "priority": 15,  # Range [0-255]
            "max_req_bw_ul": 10000000,  # MAX bw Uplink
            "max_req_bw_dl": 15000000,  # MAX bw Downlink
            "gbr_ul": 1000000,  # GBR Uplink
            "gbr_dl": 2000000,  # GBR Downlink
            "arp_prio": 15,  # ARP priority
            "pre_cap": 1,  # pre-emption capability
            "pre_vul": 1,  # pre-emption vulnerability
        }

        policy_id = "internet"

        print(
            "************************* Running End to End attach for UE id ",
            ue_id,
        )
        # Attach
        attach = self._s1ap_wrapper.s1_util.attach(
            ue_id,
            s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
            s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
            s1ap_types.ueAttachAccept_t,
        )

        # Wait on EMM Information from MME
        self._s1ap_wrapper._s1_util.receive_emm_info()

        addr = attach.esmInfo.pAddr.addrInfo
        default_ip = ipaddress.ip_address(bytes(addr[:4]))

        # Send indication to delay sending of erab setup rsp
        delay_erab_setup_resp = s1ap_types.UeDelayErabSetupRsp()
        delay_erab_setup_resp.ue_Id = ue_id
        delay_erab_setup_resp.flag = 1
        # Timer value in secs to delay erab setup rsp
        delay_erab_setup_resp.tmrVal = 6000
        self._s1ap_wrapper._s1_util.issue_cmd(
            s1ap_types.tfwCmd.UE_SET_DELAY_ERAB_SETUP_RSP,
            delay_erab_setup_resp,
        )
        print(
            "Sent UE_SET_DELAY_ERAB_SETUP_RSP with delay value of %d secs"
            % (delay_erab_setup_resp.tmrVal)
        )

        print("Sleeping for 5 seconds")
        time.sleep(5)
        print(
            "********************** Sending RAR for IMSI",
            "".join([str(i) for i in req.imsi]),
        )
        self._sessionManager_util.create_ReAuthRequest(
            "IMSI" + "".join([str(i) for i in req.imsi]),
            policy_id,
            flow_list,
            qos,
        )

        # Receive Activate dedicated bearer request
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.UE_ACT_DED_BER_REQ.value
        )
        act_ded_ber_ctxt_req = response.cast(s1ap_types.UeActDedBearCtxtReq_t)

        print("Sleeping for 5 seconds")
        time.sleep(5)
        # Send Activate dedicated bearer accept
        self._s1ap_wrapper.sendActDedicatedBearerAccept(
            ue_id, act_ded_ber_ctxt_req.bearerId
        )
        # Delay to ensure erab setup rsp is sent out of order
        print("Sleeping for 10 seconds")
        time.sleep(10)

        dl_flow_rules = {
            default_ip: [flow_list],
        }
        # ipv4 default bearer + dedicated bearer
        num_ul_flows = 2
        # Verify if flow rules are created
        self._s1ap_wrapper.s1_util.verify_flow_rules(
            num_ul_flows, dl_flow_rules
        )

        print(
            "************************* Running UE detach (switch-off) for ",
            "UE id ",
            ue_id,
        )

        # Now detach the UE
        self._s1ap_wrapper.s1_util.detach(
            ue_id, s1ap_types.ueDetachType_t.UE_SWITCHOFF_DETACH.value, False
        )
class TestAttachStandaloneActvDfltBearCtxtRejDedBerActivation(
        unittest.TestCase):
    def setUp(self):
        self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
        self._sessionManager_util = SessionManagerUtil()

    def tearDown(self):
        self._s1ap_wrapper.cleanup()

    def test_attach_standalone_act_dflt_ber_ctxt_rej_ded_bearer_activation(
        self, ):
        """ Attach + PDN connectivity req + activate default
        EPS bearer reject for secondary PDN
        + initiate RAR for the secondary PDN + detach"""

        self._s1ap_wrapper.configUEDevice(1)
        req = self._s1ap_wrapper.ue_req

        # APN of the secondary PDN
        ims = {
            "apn_name": "ims",  # APN-name
            "qci": 5,  # qci
            "priority": 15,  # priority
            "pre_cap": 0,  # preemption-capability
            "pre_vul": 0,  # preemption-vulnerability
            "mbr_ul": 200000000,  # MBR UL
            "mbr_dl": 100000000,  # MBR DL
        }
        # UL Flow description #1
        ulFlow1 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5002,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #2
        ulFlow2 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5001,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #3
        ulFlow3 = {
            "ipv4_dst": "192.168.129.64",  # IPv4 destination address
            "tcp_dst_port": 5003,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #4
        ulFlow4 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5004,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # DL Flow description #1
        dlFlow1 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5001,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #2
        dlFlow2 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5002,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #3
        dlFlow3 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5003,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }
        # DL Flow description #4
        dlFlow4 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5004,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # Flow list to be configured
        flow_list = [
            ulFlow1,
            ulFlow2,
            ulFlow3,
            ulFlow4,
            dlFlow1,
            dlFlow2,
            dlFlow3,
            dlFlow4,
        ]

        # QoS
        qos = {
            "qci": 1,  # qci value [1 to 9]
            "priority": 15,  # Range [0-255]
            "max_req_bw_ul": 10000000,  # MAX bw Uplink
            "max_req_bw_dl": 15000000,  # MAX bw Downlink
            "gbr_ul": 1000000,  # GBR Uplink
            "gbr_dl": 2000000,  # GBR Downlink
            "arp_prio": 15,  # ARP priority
            "pre_cap": 1,  # pre-emption capability
            "pre_vul": 1,  # pre-emption vulnerability
        }

        policy_id = "ims-voice"

        # APN list to be configured
        apn_list = [ims]

        self._s1ap_wrapper.configAPN(
            "IMSI" + "".join([str(i) for i in req.imsi]), apn_list)
        print(
            "************************* Running End to End attach for UE id ",
            req.ue_id,
        )
        # Attach
        attach = self._s1ap_wrapper.s1_util.attach(
            req.ue_id,
            s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
            s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
            s1ap_types.ueAttachAccept_t,
        )

        addr = attach.esmInfo.pAddr.addrInfo
        default_ip = ipaddress.ip_address(bytes(addr[:4]))

        # Wait on EMM Information from MME
        self._s1ap_wrapper._s1_util.receive_emm_info()
        print("Sleeping for 5 seconds")
        time.sleep(5)
        # Verify if flow rules are created
        # No dedicated bearers, so flow list will be empty
        dl_flow_rules = {
            default_ip: [],
        }
        # 1 UL flow for the default bearer
        num_ul_flows = 1
        self._s1ap_wrapper.s1_util.verify_flow_rules(num_ul_flows,
                                                     dl_flow_rules)

        print("Sleeping for 5 seconds")
        time.sleep(5)
        # Trigger Activate Default EPS Bearer Context Reject indication
        # so that s1ap tester sends Activate default EPS bearer context reject
        # instead of Activate default EPS bearer context accept
        def_ber_rej = s1ap_types.ueActvDfltEpsBearerCtxtRej_t()
        def_ber_rej.ue_Id = req.ue_id
        def_ber_rej.bearerId = attach.esmInfo.epsBearerId
        def_ber_rej.cause = s1ap_types.TFW_EMM_CAUSE_PROT_ERR_UNSP

        self._s1ap_wrapper._s1_util.issue_cmd(
            s1ap_types.tfwCmd.
            UE_STANDALONE_ACTV_DEFAULT_EPS_BEARER_CNTXT_REJECT,
            def_ber_rej,
        )
        print(
            "Sent STANDALONE_ACTV_DEFAULT_EPS_BEARER_CNTXT_REJECT indication")
        print("Sleeping for 5 seconds")
        time.sleep(5)
        # Send PDN Connectivity Request
        apn = "ims"
        self._s1ap_wrapper.sendPdnConnectivityReq(req.ue_id, apn)
        # Receive PDN CONN RSP/Activate default EPS bearer context request
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(response.msg_type,
                         s1ap_types.tfwCmd.UE_PDN_CONN_RSP_IND.value)
        act_def_bearer_req = response.cast(s1ap_types.uePdnConRsp_t)

        print("************************* Sending Activate default EPS bearer "
              "context reject for UE id %d and bearer %d" %
              (req.ue_id, act_def_bearer_req.m.pdnInfo.epsBearerId))

        print("Sleeping for 5 seconds")
        time.sleep(5)

        # Dedicated bearer will not be established as the seconday PDN
        # establishment failed
        print(
            "********************** Sending RAR for IMSI",
            "".join([str(i) for i in req.imsi]),
        )
        self._sessionManager_util.create_ReAuthRequest(
            "IMSI" + "".join([str(i) for i in req.imsi]),
            policy_id,
            flow_list,
            qos,
        )

        print("Sleeping for 5 seconds")
        time.sleep(5)
        # Verify that ovs rules are not created for the seconday pdn and
        # dedicated bearer as UE rejected the establishment of secondary pdn

        self._s1ap_wrapper.s1_util.verify_flow_rules(num_ul_flows,
                                                     dl_flow_rules)

        print("Sleeping for 5 seconds")
        time.sleep(5)
        # Now detach the UE
        print(
            "************************* Running UE detach (switch-off) for ",
            "UE id ",
            req.ue_id,
        )
        self._s1ap_wrapper.s1_util.detach(
            req.ue_id,
            s1ap_types.ueDetachType_t.UE_SWITCHOFF_DETACH.value,
            False,
        )
Ejemplo n.º 6
0
class TestDedicatedBearerActivationIdleMode(unittest.TestCase):
    def setUp(self):
        self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
        self._sessionManager_util = SessionManagerUtil()

    def tearDown(self):
        self._s1ap_wrapper.cleanup()

    def test_dedicated_bearer_activation_idle_mode(self):
        """
        Test with a single UE attach + UE context release +
        trigger dedicated bearer activation
        + Page the UE + detach"""

        # UL Flow description #1
        ulFlow1 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5002,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #2
        ulFlow2 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5001,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #3
        ulFlow3 = {
            "ipv4_dst": "192.168.129.64",  # IPv4 destination address
            "tcp_dst_port": 5003,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #4
        ulFlow4 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5001,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # DL Flow description #1
        dlFlow1 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5001,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #2
        dlFlow2 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5002,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }
        # DL Flow description #3
        dlFlow3 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5003,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #4
        dlFlow4 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5001,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # Flow list to be configured
        flow_list1 = [
            ulFlow1,
            ulFlow2,
            ulFlow3,
            dlFlow1,
            dlFlow2,
            dlFlow3,
        ]

        flow_list2 = [
            ulFlow4,
            dlFlow4,
        ]

        # QoS
        qos1 = {
            "qci": 5,  # qci value [1 to 9]
            "priority": 5,  # Range [0-255]
            "max_req_bw_ul": 10000000,  # MAX bw Uplink
            "max_req_bw_dl": 15000000,  # MAX bw Downlink
            "gbr_ul": 1000000,  # GBR Uplink
            "gbr_dl": 2000000,  # GBR Downlink
            "arp_prio": 15,  # ARP priority
            "pre_cap": 1,  # pre-emption capability
            "pre_vul": 1,  # pre-emption vulnerability
        }
        qos2 = {
            "qci": 1,  # qci value [1 to 9]
            "priority": 1,  # Range [0-255]
            "max_req_bw_ul": 10000000,  # MAX bw Uplink
            "max_req_bw_dl": 15000000,  # MAX bw Downlink
            "gbr_ul": 1000000,  # GBR Uplink
            "gbr_dl": 2000000,  # GBR Downlink
            "arp_prio": 1,  # ARP priority
            "pre_cap": 1,  # pre-emption capability
            "pre_vul": 1,  # pre-emption vulnerability
        }

        policy_id1 = "ims-voice"
        policy_id2 = "internet"

        self._s1ap_wrapper.configUEDevice(1)
        req = self._s1ap_wrapper.ue_req
        ue_id = req.ue_id
        imsi = req.imsi
        print("*********** Running End to End attach for UE id ", ue_id)
        # Now actually complete the attach
        attach = self._s1ap_wrapper._s1_util.attach(
            ue_id,
            s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
            s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
            s1ap_types.ueAttachAccept_t,
        )
        addr = attach.esmInfo.pAddr.addrInfo
        default_ip = ipaddress.ip_address(bytes(addr[:4]))

        # Wait on EMM Information from MME
        self._s1ap_wrapper._s1_util.receive_emm_info()

        # Delay to ensure S1APTester sends attach complete before sending UE
        # context release
        print("*********** Sleeping for 5 seconds")
        time.sleep(5)

        # Move UE to idle mode
        print("*********** Moving UE to idle mode")
        print(
            "*********** Sending UE context release request ",
            "for UE id ",
            ue_id,
        )
        # Send UE context release request to move UE to idle mode
        rel_req = s1ap_types.ueCntxtRelReq_t()
        rel_req.ue_Id = ue_id
        rel_req.cause.causeVal = (
            gpp_types.CauseRadioNetwork.USER_INACTIVITY.value
        )
        self._s1ap_wrapper.s1_util.issue_cmd(
            s1ap_types.tfwCmd.UE_CNTXT_REL_REQUEST, rel_req
        )
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.UE_CTX_REL_IND.value
        )

        # Verify if paging flow rules are created
        ip_list = [default_ip]
        self._s1ap_wrapper.s1_util.verify_paging_flow_rules(ip_list)

        print("*********** Sleeping for 5 seconds")
        time.sleep(5)
        # Add dedicated bearers for default bearer 5

        print(
            "************* Adding dedicated bearers to magma.ipv4"
            " PDN in idle mode for UE",
            ue_id,
        )
        print(
            "********************** Sending 1st RAR for IMSI",
            "".join([str(i) for i in imsi]),
        )
        self._sessionManager_util.create_ReAuthRequest(
            "IMSI" + "".join([str(i) for i in imsi]),
            policy_id1,
            flow_list1,
            qos1,
        )

        # Add 2nd dedicated bearer for default bearer 5
        print(
            "********************** Sending 2nd RAR for IMSI",
            "".join([str(i) for i in imsi]),
        )
        self._sessionManager_util.create_ReAuthRequest(
            "IMSI" + "".join([str(i) for i in imsi]),
            policy_id2,
            flow_list2,
            qos2,
        )

        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.UE_PAGING_IND.value
        )

        print("*********** Received Paging for UE id ", ue_id)
        print("*********** Sending Service request for UE id ", ue_id)
        # Send service request to reconnect UE
        ser_req = s1ap_types.ueserviceReq_t()
        ser_req.ue_Id = ue_id
        ser_req.ueMtmsi = s1ap_types.ueMtmsi_t()
        ser_req.ueMtmsi.pres = False
        ser_req.rrcCause = s1ap_types.Rrc_Cause.TFW_MO_SIGNALLING.value
        self._s1ap_wrapper.s1_util.issue_cmd(
            s1ap_types.tfwCmd.UE_SERVICE_REQUEST, ser_req
        )
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.INT_CTX_SETUP_IND.value
        )

        print("*********** Received ICS Request for UE id ", ue_id)
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.UE_ACT_DED_BER_REQ.value
        )
        act_ded_ber_req_oai_apn1 = response.cast(
            s1ap_types.UeActDedBearCtxtReq_t
        )
        print(
            "*********** Received Activate dedicated EPS bearer"
            " req for bearer ",
            act_ded_ber_req_oai_apn1.bearerId,
        )
        self._s1ap_wrapper.sendActDedicatedBearerAccept(
            ue_id, act_ded_ber_req_oai_apn1.bearerId
        )
        response = self._s1ap_wrapper.s1_util.get_response()
        self.assertEqual(
            response.msg_type, s1ap_types.tfwCmd.UE_ACT_DED_BER_REQ.value
        )
        act_ded_ber_req_oai_apn2 = response.cast(
            s1ap_types.UeActDedBearCtxtReq_t
        )
        print(
            "*********** Received Activate dedicated EPS bearer"
            " req for bearer ",
            act_ded_ber_req_oai_apn2.bearerId,
        )

        self._s1ap_wrapper.sendActDedicatedBearerAccept(
            ue_id, act_ded_ber_req_oai_apn2.bearerId
        )

        # Verify if flow rules are created
        dl_flow_rules = {default_ip: [flow_list1, flow_list2]}
        # 1 UL flow is created per bearer
        num_ul_flows = 3
        self._s1ap_wrapper.s1_util.verify_flow_rules(
            num_ul_flows, dl_flow_rules
        )

        print("*********** Sleeping for 5 seconds")
        time.sleep(5)
        print("*********** Running UE detach for UE id ", ue_id)

        # Now detach the UE
        self._s1ap_wrapper.s1_util.detach(
            ue_id, s1ap_types.ueDetachType_t.UE_SWITCHOFF_DETACH.value, True
        )
class TestIPv4v6SecondaryPdnWithDedBearerMultiUe(unittest.TestCase):
    def setUp(self):
        self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
        self._sessionManager_util = SessionManagerUtil()

    def tearDown(self):
        self._s1ap_wrapper.cleanup()

    def test_ipv4v6_secondary_pdn_with_ded_bearer_multi_ue(self):
        """ Attach a single UE + add a secondary pdn with
        IPv4v6 + add dedicated bearer + detach
        Repeat for 4 UEs"""
        num_ues = 4
        ue_ids = []
        default_ip = []
        sec_ip_ipv4 = []
        sec_ip_ipv6 = []

        # APN of the secondary PDN
        ims_apn = {
            "apn_name": "ims",  # APN-name
            "qci": 5,  # qci
            "priority": 15,  # priority
            "pre_cap": 0,  # preemption-capability
            "pre_vul": 0,  # preemption-vulnerability
            "mbr_ul": 200000000,  # MBR UL
            "mbr_dl": 100000000,  # MBR DL
            "pdn_type": 2,  # PDN Type 0-IPv4,1-IPv6,2-IPv4v6
        }
        # UL Flow description #1
        ulFlow1 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5002,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #2
        ulFlow2 = {
            "ipv4_dst": "192.168.129.42",  # IPv4 destination address
            "tcp_dst_port": 5001,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # UL Flow description #3
        ulFlow3 = {
            "ipv6_dst": "5e90:db7b:b18e::1556",  # IPv6 destination address
            "tcp_dst_port": 5003,  # TCP dest port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.UPLINK,  # Direction
        }

        # DL Flow description #1
        dlFlow1 = {
            "ipv4_src": "192.168.129.42",  # IPv4 source address
            "tcp_src_port": 5001,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #2
        dlFlow2 = {
            "ipv4_src": "192.168.129.64",  # IPv4 source address
            "tcp_src_port": 5002,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # DL Flow description #3
        dlFlow3 = {
            "ipv6_src": "6e31:1a95:1e7c::df1",  # IPv6 source address
            "tcp_src_port": 5003,  # TCP source port
            "ip_proto": FlowMatch.IPPROTO_TCP,  # Protocol Type
            "direction": FlowMatch.DOWNLINK,  # Direction
        }

        # Flow lists to be configured
        flow_list = [
            ulFlow1,
            ulFlow2,
            ulFlow3,
            dlFlow1,
            dlFlow2,
            dlFlow3,
        ]

        # QoS
        qos = {
            "qci": 1,  # qci value [1 to 9]
            "priority": 1,  # Range [0-255]
            "max_req_bw_ul": 10000000,  # MAX bw Uplink
            "max_req_bw_dl": 15000000,  # MAX bw Downlink
            "gbr_ul": 1000000,  # GBR Uplink
            "gbr_dl": 2000000,  # GBR Downlink
            "arp_prio": 1,  # ARP priority
            "pre_cap": 1,  # pre-emption capability
            "pre_vul": 1,  # pre-emption vulnerability
        }

        policy_id = "ims"

        self._s1ap_wrapper.configUEDevice(num_ues)
        for i in range(num_ues):
            req = self._s1ap_wrapper.ue_req
            ue_id = req.ue_id

            apn_list = [ims_apn]
            self._s1ap_wrapper.configAPN(
                "IMSI" + "".join([str(i) for i in req.imsi]), apn_list)
            print(
                "*********************** Running End to End attach for UE id ",
                ue_id,
            )

            print("***** Sleeping for 5 seconds")
            time.sleep(5)
            # Attach
            attach = self._s1ap_wrapper.s1_util.attach(
                ue_id,
                s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
                s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
                s1ap_types.ueAttachAccept_t,
            )
            addr = attach.esmInfo.pAddr.addrInfo
            default_ip.append(ipaddress.ip_address(bytes(addr[:4])))
            ue_ids.append(ue_id)

            # Wait on EMM Information from MME
            self._s1ap_wrapper._s1_util.receive_emm_info()

        print("***** Sleeping for 5 seconds")
        time.sleep(5)
        self._s1ap_wrapper._ue_idx = 0
        for i in range(num_ues):
            req = self._s1ap_wrapper.ue_req
            ue_id = req.ue_id

            apn = "ims"
            # PDN Type 2 = IPv6, 3 = IPv4v6
            pdn_type = 3
            # Send PDN Connectivity Request
            self._s1ap_wrapper.sendPdnConnectivityReq(ue_id,
                                                      apn,
                                                      pdn_type=pdn_type)
            # Receive PDN CONN RSP/Activate default EPS bearer context request
            response = self._s1ap_wrapper.s1_util.get_response()
            self.assertEqual(response.msg_type,
                             s1ap_types.tfwCmd.UE_PDN_CONN_RSP_IND.value)
            act_def_bearer_req = response.cast(s1ap_types.uePdnConRsp_t)

            addr = act_def_bearer_req.m.pdnInfo.pAddr.addrInfo
            sec_ip_ipv4.append(ipaddress.ip_address(bytes(addr[8:12])))

            print(
                "********************** Sending Activate default EPS bearer "
                "context accept for APN-%s, UE id-%d" % (apn, ue_id), )
            print("********************** Added default bearer for apn-%s,"
                  " bearer id-%d, pdn type-%d" % (
                      apn,
                      act_def_bearer_req.m.pdnInfo.epsBearerId,
                      pdn_type,
                  ))

            # Receive Router Advertisement message
            response = self._s1ap_wrapper.s1_util.get_response()
            self.assertEqual(response.msg_type,
                             s1ap_types.tfwCmd.UE_ROUTER_ADV_IND.value)
            routerAdv = response.cast(s1ap_types.ueRouterAdv_t)
            print(
                "******************* Received Router Advertisement for APN-%s"
                " ,bearer id-%d" % (apn, routerAdv.bearerId))

            ipv6_addr = "".join([chr(i)
                                 for i in routerAdv.ipv6Addr]).rstrip("\x00")
            print("******* UE IPv6 address: ", ipv6_addr)
            sec_ip_ipv6.append(ipaddress.ip_address(ipv6_addr))

            print("***** Sleeping for 5 seconds")
            time.sleep(5)

            # Add dedicated bearer
            print("********************** Adding dedicated bearer to ims PDN")
            print(
                "********************** Sending RAR for IMSI",
                "".join([str(i) for i in req.imsi]),
            )
            self._sessionManager_util.create_ReAuthRequest(
                "IMSI" + "".join([str(i) for i in req.imsi]),
                policy_id,
                flow_list,
                qos,
            )
            response = self._s1ap_wrapper.s1_util.get_response()
            self.assertEqual(response.msg_type,
                             s1ap_types.tfwCmd.UE_ACT_DED_BER_REQ.value)
            act_ded_ber_req_ims_apn = response.cast(
                s1ap_types.UeActDedBearCtxtReq_t)
            self._s1ap_wrapper.sendActDedicatedBearerAccept(
                req.ue_id, act_ded_ber_req_ims_apn.bearerId)
            print(
                "************* Added dedicated bearer",
                act_ded_ber_req_ims_apn.bearerId,
            )

        print("***** Sleeping for 10 seconds")
        time.sleep(10)
        # ipv4 default pdn + ipv4v6(ims) pdn +
        # dedicated bearer for ims pdn for 4 UEs
        num_ul_flows = 12
        for i in range(num_ues):
            dl_flow_rules = {
                default_ip[i]: [],
                sec_ip_ipv4[i]: [flow_list],
                sec_ip_ipv6[i]: [flow_list],
            }
            # Verify if flow rules are created
            self._s1ap_wrapper.s1_util.verify_flow_rules(
                num_ul_flows, dl_flow_rules)

        print("***** Sleeping for 5 seconds")
        time.sleep(5)
        for ue in ue_ids:
            print(
                "******************* Running UE detach (switch-off) for ",
                "UE id ",
                ue,
            )
            # Now detach the UE
            self._s1ap_wrapper.s1_util.detach(
                ue, s1ap_types.ueDetachType_t.UE_SWITCHOFF_DETACH.value, False)