pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/42501?usp=email )


Change subject: pgw: Test v6 and v4v6 PDU session userplane
......................................................................

pgw: Test v6 and v4v6 PDU session userplane

Change-Id: Idf009b9118db8117c547a1bb0f27afdfa3f03924
---
M library/GTPv2_Templates.ttcn
M pgw/PGW_Tests.cfg
M pgw/PGW_Tests.ttcn
M pgw/expected-results.xml
M pgw/open5gs-smf.yaml
M pgw/open5gs-upf.yaml
M pgw/testenv.sh
7 files changed, 220 insertions(+), 43 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks 
refs/changes/01/42501/1

diff --git a/library/GTPv2_Templates.ttcn b/library/GTPv2_Templates.ttcn
index 539251c..0ac6cf8 100644
--- a/library/GTPv2_Templates.ttcn
+++ b/library/GTPv2_Templates.ttcn
@@ -390,6 +390,20 @@
 tr_GTP2C_PdnAddrAlloc_v4(template (present) OCT4 addr) :=
        ts_GTP2C_PdnAddrAlloc('001'B, {iPv4_Address:=addr});

+template (value) PDN_AddressAllocation
+ts_GTP2C_PdnAddrAlloc_v6(template (value) IPv6 addr) :=
+       ts_GTP2C_PdnAddrAlloc('010'B, {iPv6_Address:=addr});
+template (present) PDN_AddressAllocation
+tr_GTP2C_PdnAddrAlloc_v6(template (present) IPv6 addr) :=
+       ts_GTP2C_PdnAddrAlloc('010'B, {iPv6_Address:=addr});
+
+template (value) PDN_AddressAllocation
+ts_GTP2C_PdnAddrAlloc_v4v6(template (value) IPv4_IPv6 addr) :=
+       ts_GTP2C_PdnAddrAlloc('011'B, {iPv4_IPv6:=addr});
+template (present) PDN_AddressAllocation
+tr_GTP2C_PdnAddrAlloc_v4v6(template (present) IPv4_IPv6 addr) :=
+       ts_GTP2C_PdnAddrAlloc('011'B, {iPv4_IPv6:=addr});
+
 /* 8.15 */
 template (value) Bearer_QoS
 ts_GTP2C_BearerQos(template (value) OCT1 qci,
@@ -903,6 +917,27 @@
 tr_PDU_GTP2C(omit, seq, { echoResponse := ? }, omit);


+private function f_ts_PDN_AddressAllocation_request(template (value) BIT3 
pdn_type)
+return template (value) PDN_AddressAllocation
+{
+       var template (value) PDN_AddressAllocation paa;
+       select (valueof(pdn_type)) {
+       case ('001'B) {
+               paa := ts_GTP2C_PdnAddrAlloc_v4('00000000'O);
+       }
+       case ('010'B) {
+               paa := ts_GTP2C_PdnAddrAlloc_v6({ prefixLength := 64,
+                                                 iPv6_Address := 
'00000000000000000000000000000000'O });
+       }
+       case ('011'B) {
+               paa := ts_GTP2C_PdnAddrAlloc_v4v6({ prefixLength := 64,
+                                                   iPv6_Address := 
'00000000000000000000000000000000'O,
+                                                   iPv4_Address := '00000000'O 
});
+       }
+       }
+
+       return paa;
+}

 template (present) PDU_GTPCv2
 ts_GTP2C_CreateSessionReq(template (value) hexstring imsi, template (omit) 
hexstring msisdn,
@@ -926,7 +961,7 @@
                accessPointName := ts_GTP2C_APN(apn),
                selectionMode := ts_GTP2C_SelectionMode(0),
                pDN_Type := ts_GTP2C_PdnType(pdn_type),
-               pDN_AddressAllocation := ts_GTP2C_PdnAddrAlloc('001'B, 
{iPv4_Address:='00000000'O}),
+               pDN_AddressAllocation := 
f_ts_PDN_AddressAllocation_request(pdn_type),
                maxAPN_Restriction := ts_GTP2C_ApnRestriction(0),
                ambr := ts_GTP2C_Ambr(102400, 102400),
                linkedEPS_Bearer_ID := omit,
diff --git a/pgw/PGW_Tests.cfg b/pgw/PGW_Tests.cfg
index 68688c1..d280a6d 100644
--- a/pgw/PGW_Tests.cfg
+++ b/pgw/PGW_Tests.cfg
@@ -17,6 +17,7 @@
 PGW_Tests.mp_run_prog_log_path := "./run_prog"
 PGW_Tests.mp_run_prog_as_user := "osmocom"  # testenv.sh sets this to $USER
 PGW_Tests.mp_ping_hostname := "10.45.0.1"
+PGW_Tests.mp_ping_hostname6 := "cafe::1"
 PGW_Tests.mp_pcrf_local_ip:= "127.0.0.202"
 PGW_Tests.mp_ocs_local_ip:= "127.0.0.202"
 PGW_Tests.mp_aaa_local_ip:= "127.0.0.202"
diff --git a/pgw/PGW_Tests.ttcn b/pgw/PGW_Tests.ttcn
index a670881..1e02aec 100644
--- a/pgw/PGW_Tests.ttcn
+++ b/pgw/PGW_Tests.ttcn
@@ -35,6 +35,7 @@
        charstring mp_run_prog_log_path := "/tmp";
        charstring mp_run_prog_as_user := "laforge";
        charstring mp_ping_hostname := "10.45.0.1";
+       charstring mp_ping_hostname6 := "cafe::1";

        charstring mp_pcrf_local_ip := "127.0.0.9";
        integer mp_pcrf_local_port := 3868;
@@ -117,8 +118,8 @@

        /* Address allocation */
        var OCT4        g_ip4_addr;
+       var OCT8        g_ip6_interface_id;
        var OCT16       g_ip6_addr;
-       var integer     g_ip6_plen;

        /* Store last received Gy message */
        var PDU_DIAMETER g_rx_gy;
@@ -674,6 +675,58 @@
        return omit;
 }

+private function f_create_sess_tun() runs on PGW_Session_CT
+{
+       var template (value) UECUPS_AddrType user_addr_type;
+       var template (value) OCT4_20n user_addr;
+
+       select (g_pars.pdn_type) {
+       case (GTP2C_PDN_IPv4) {
+               user_addr_type := IPV4;
+               user_addr := g_ip4_addr;
+               }
+       case (GTP2C_PDN_IPv6) {
+               user_addr_type := IPV6;
+               user_addr := g_ip6_addr;
+               }
+       case (GTP2C_PDN_IPv4v6) {
+               user_addr_type := IPV4V6;
+               user_addr := g_ip4_addr & g_ip6_addr;
+               }
+       }
+
+       var template (value) UECUPS_CreateTun uecups_create := 
ts_UECUPS_CreateTun(
+               tx_teid := oct2int(g_pars.bearer.teid_remote),
+               rx_teid := oct2int(g_pars.bearer.teid_local),
+               user_addr_type := user_addr_type,
+               user_addr := user_addr,
+               local_gtp_ep := 
valueof(ts_UECUPS_SockAddr(f_inet_addr(mp_local_hostname_u))),
+               remote_gtp_ep := valueof(ts_UECUPS_SockAddr(g_gtpu4_remote)),
+               tun_dev_name := g_pars.tun_dev_name,
+               tun_netns_name := g_pars.tun_netns_name
+       );
+
+       /* create tunnel in daemon */
+       f_gtp1u_create_tunnel(uecups_create);
+}
+
+private function f_perform_ipv6_slaac() runs on PGW_Session_CT
+{
+       var UECUPS_IPv6SLAACInd ipv6slaac_ind;
+       var template (value) UECUPS_IPv6SLAAC ipv6slaac;
+       ipv6slaac := ts_UECUPS_IPv6SLAAC(
+               local_gtp_ep := 
valueof(ts_UECUPS_SockAddr(f_inet_addr(mp_local_hostname_u))),
+               rx_teid := oct2int(g_pars.bearer.teid_local)
+       );
+       f_gtp1u_ipv6_slaac(ipv6slaac);
+       GTP1U[0].receive(UECUPS_IPv6SLAACInd:?) -> value ipv6slaac_ind;
+       log("5GC assigned IPv6 global prefix: ", ipv6slaac_ind.ipv6_prefix, " 
-> ", f_inet6_ntoa(ipv6slaac_ind.ipv6_prefix & '0000000000000000'O));
+
+       /* Use the first global IPv6 address in the IPv6 prefix picked by 
osmo-uecups: */
+       g_ip6_addr := ipv6slaac_ind.ipv6_user_addr;
+       log("Using IPv6 global address: ", g_ip6_addr);
+}
+
 /* process one to-be-created bearer context */
 private function process_bctx_create(BearerContextGrouped bctx) runs on 
PGW_Session_CT
 {
@@ -702,26 +755,10 @@
                g_gtpu6_remote := rx_fteid.iPv6_Address;
        }

-       var template (value) UECUPS_CreateTun uecups_create := 
ts_UECUPS_CreateTun(
-               tx_teid := oct2int(g_pars.bearer.teid_remote),
-               rx_teid := oct2int(g_pars.bearer.teid_local),
-               user_addr_type := IPV4,
-               user_addr := '00000000'O,
-               local_gtp_ep := 
valueof(ts_UECUPS_SockAddr(f_inet_addr(mp_local_hostname_u))),
-               remote_gtp_ep := valueof(ts_UECUPS_SockAddr(g_gtpu4_remote)),
-               tun_dev_name := g_pars.tun_dev_name,
-               tun_netns_name := g_pars.tun_netns_name
-       );
-
-       /* create tunnel in daemon */
-       if (isbound(g_ip4_addr)) {
-               uecups_create.user_addr := g_ip4_addr;
-               f_gtp1u_create_tunnel(uecups_create);
-       }
-       if (isbound(g_ip6_addr)) {
-               uecups_create.user_addr_type := IPV6;
-               uecups_create.user_addr := g_ip6_addr;
-               f_gtp1u_create_tunnel(uecups_create);
+       f_create_sess_tun();
+       if (g_pars.pdn_type == GTP2C_PDN_IPv6 or
+           g_pars.pdn_type == GTP2C_PDN_IPv4v6) {
+               f_perform_ipv6_slaac();
        }
 }

@@ -780,13 +817,28 @@
                var PDN_Address_and_Prefix paa := 
resp.pDN_AddressAllocation.pDN_Address_and_Prefix;
                if (ischosen(paa.iPv4_Address)) {
                        g_ip4_addr := paa.iPv4_Address;
+                       log("PGW assigned UE IPv4 address: ", 
f_inet_ntoa(g_ip4_addr));
                } else if (ischosen(paa.iPv6_Address)) {
-                       g_ip6_addr := paa.iPv6_Address.iPv6_Address;
-                       g_ip6_plen := paa.iPv6_Address.prefixLength;
+                       if (paa.iPv6_Address.prefixLength != 64) {
+                               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, 
fail,
+                                                       log2str("Got IPv6 
Prefix Length ",
+                                                               
paa.iPv6_Address.prefixLength, " vs exp 64"));
+                       }
+                       g_ip6_interface_id := 
substr(paa.iPv6_Address.iPv6_Address, 8, 8);
+                       log("PGW assigned IPv6 Interface Id: ", 
g_ip6_interface_id);
+                       g_ip6_addr := 'FE80000000000000'O & g_ip6_interface_id;
+                       log("PGW assigned IPv6 link-local Address: ", 
f_inet6_ntoa(g_ip6_addr));
                } else if (ischosen(paa.iPv4_IPv6)) {
+                       if (paa.iPv4_IPv6.prefixLength != 64) {
+                               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, 
fail,
+                                                       log2str("Got IPv6 
Prefix Length ",
+                                                               
paa.iPv6_Address.prefixLength, " vs exp 64"));
+                       }
                        g_ip4_addr := paa.iPv4_IPv6.iPv4_Address;
-                       g_ip6_addr := paa.iPv4_IPv6.iPv6_Address;
-                       g_ip6_plen := paa.iPv4_IPv6.prefixLength;
+                       g_ip6_interface_id := 
substr(paa.iPv4_IPv6.iPv6_Address, 8, 8);
+                       log("PGW assigned IPv6 Interface Id: ", 
g_ip6_interface_id);
+                       g_ip6_addr := 'FE80000000000000'O & g_ip6_interface_id;
+                       log("PGW assigned IPv6 link-local Address: ", 
f_inet6_ntoa(g_ip6_addr));
                }
                var integer i;
                for (i := 0; i < lengthof(resp.bearerContextGrouped); i := i+1) 
{
@@ -920,16 +972,21 @@
 }

 /* execute ping command and wait for result */
-private function f_ping4(charstring host, integer interval := 1, integer count 
:= 10) runs on PGW_Session_CT
+private function f_ping(charstring host, integer interval := 1, integer count 
:= 10) runs on PGW_Session_CT
 {
-       if (not isbound(g_ip4_addr)) {
-               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "f_ping4(): 
g_ip4_addr is unset!");
-       }
-       /* command will be filled in by f_gtp1u_ping() below: */
+       /* command will be filled in by f_gtp1u_ping4() below: */
        var UECUPS_StartProgram sprog := f_run_prog_init("");
-       f_gtp1u_ping(sprog, host, interval, count, f_inet_ntoa(g_ip4_addr),
-                    redirect_output := true,
-                    redirect_output_path_prefix := 
f_run_prog_unique_log_path());
+       var charstring bind_addr;
+
+       if (f_addr_is_ipv6(host)) {
+               bind_addr := f_inet6_ntoa(g_ip6_addr);
+       } else {
+               bind_addr := f_inet_ntoa(g_ip4_addr);
+       }
+
+       f_gtp1u_ping(sprog, host, interval, count, bind_addr,
+                     redirect_output := true,
+                     redirect_output_path_prefix := 
f_run_prog_unique_log_path());
 }

 /* send echo request; expect response */
@@ -957,21 +1014,25 @@
 }
 testcase TC_createSession() runs on PGW_Test_CT {
        var PGW_Session_CT vc_conn;
-       var SessionPars pars := valueof(t_SessionPars('001010123456789'H, 
"tun22"));
+       var SessionPars pars := valueof(t_SessionPars('001010123456789'H,
+                                                     "tun22",
+                                                     pdn_type := 
GTP2C_PDN_IPv4));
        f_init();
        vc_conn := f_start_handler(refers(f_TC_createSession), pars);
        vc_conn.done;
 }

-/* create a session, then execute a ping command on the user plane */
+/* create a IPv4 session, then execute a ping command on the user plane */
 private function f_TC_createSession_ping4() runs on PGW_Session_CT {
        f_s5s8_create_session();
-       f_ping4(mp_ping_hostname);
+       f_ping(mp_ping_hostname);
        setverdict(pass);
 }
 testcase TC_createSession_ping4() runs on PGW_Test_CT {
        var PGW_Session_CT vc_conn;
-       var SessionPars pars := valueof(t_SessionPars('001010123456789'H, 
"tun23"));
+       var SessionPars pars := valueof(t_SessionPars('001010123456789'H,
+                                                     "tun23",
+                                                     pdn_type := 
GTP2C_PDN_IPv4));
        f_init();
        vc_conn := f_start_handler(refers(f_TC_createSession_ping4), pars);
        vc_conn.done;
@@ -993,6 +1054,74 @@
        }
 }

+/* create a IPv6 session, then execute a ping command on the user plane */
+private function f_TC_createSession_ping6() runs on PGW_Session_CT {
+       f_s5s8_create_session();
+       f_ping(mp_ping_hostname6);
+       setverdict(pass);
+}
+testcase TC_createSession_ping6() runs on PGW_Test_CT {
+       var PGW_Session_CT vc_conn;
+       var SessionPars pars := valueof(t_SessionPars('001010123456789'H,
+                                                     "tun23",
+                                                     pdn_type := 
GTP2C_PDN_IPv6));
+       f_init();
+       vc_conn := f_start_handler(refers(f_TC_createSession_ping6), pars);
+       vc_conn.done;
+}
+testcase TC_createSession_ping6_256() runs on PGW_Test_CT {
+       var PGW_Session_CT vc_conn[256];
+       var integer i;
+
+       f_init();
+
+       for (i := 0; i < sizeof(vc_conn); i:=i+1) {
+               var charstring tundev := "ping" & int2str(i);
+               var SessionPars pars := valueof(t_SessionPars(f_gen_imsi(i),
+                                               tundev,
+                                               pdn_type := GTP2C_PDN_IPv6));
+               vc_conn[i] := f_start_handler(refers(f_TC_createSession_ping6), 
pars);
+       }
+
+       for (i := 0; i < lengthof(vc_conn); i:=i+1) {
+               vc_conn[i].done;
+       }
+}
+
+/* create a IPv4v6 session, then execute a ping command on the user plane */
+private function f_TC_createSession_ping46() runs on PGW_Session_CT {
+       f_s5s8_create_session();
+       f_ping(mp_ping_hostname);
+       f_ping(mp_ping_hostname6);
+       setverdict(pass);
+}
+testcase TC_createSession_ping46() runs on PGW_Test_CT {
+       var PGW_Session_CT vc_conn;
+       var SessionPars pars := valueof(t_SessionPars('001010123456789'H,
+                                                     "tun23",
+                                                     pdn_type := 
GTP2C_PDN_IPv4v6));
+       f_init();
+       vc_conn := f_start_handler(refers(f_TC_createSession_ping46), pars);
+       vc_conn.done;
+}
+testcase TC_createSession_ping46_256() runs on PGW_Test_CT {
+       var PGW_Session_CT vc_conn[256];
+       var integer i;
+
+       f_init();
+
+       for (i := 0; i < sizeof(vc_conn); i:=i+1) {
+               var charstring tundev := "ping" & int2str(i);
+               var SessionPars pars := valueof(t_SessionPars(f_gen_imsi(i),
+                                               tundev,
+                                               pdn_type := GTP2C_PDN_IPv4v6));
+               vc_conn[i] := 
f_start_handler(refers(f_TC_createSession_ping46), pars);
+       }
+
+       for (i := 0; i < lengthof(vc_conn); i:=i+1) {
+               vc_conn[i].done;
+       }
+}

 /* create a session, then delete it again */
 private function f_TC_createSession_deleteSession() runs on PGW_Session_CT {
@@ -1033,7 +1162,7 @@
        f_validate_gy_cc_report(g_rx_gy, VALIDITY_TIME, (3..4), 0, 0);

        d := activate(as_DIA_Gy_CCR(UPDATE_REQUEST));
-       f_ping4(mp_ping_hostname);
+       f_ping(mp_ping_hostname);
        /* Let the CCA reach the PGW */
        f_sleep(0.5);
        deactivate(d);
@@ -1126,6 +1255,10 @@
        execute( TC_createSession() );
        execute( TC_createSession_ping4() );
        execute( TC_createSession_ping4_256() );
+       execute( TC_createSession_ping6() );
+       execute( TC_createSession_ping6_256() );
+       execute( TC_createSession_ping46() );
+       execute( TC_createSession_ping46_256() );
        execute( TC_createSession_deleteSession() );
        execute( TC_deleteSession_unknown() );
        execute( TC_gy_charging_cc_time() );
diff --git a/pgw/expected-results.xml b/pgw/expected-results.xml
index 3945b4d..459e59c 100644
--- a/pgw/expected-results.xml
+++ b/pgw/expected-results.xml
@@ -4,6 +4,10 @@
   <testcase classname='PGW_Tests' name='TC_createSession' time='MASKED'/>
   <testcase classname='PGW_Tests' name='TC_createSession_ping4' time='MASKED'/>
   <testcase classname='PGW_Tests' name='TC_createSession_ping4_256' 
time='MASKED'/>
+  <testcase classname='PGW_Tests' name='TC_createSession_ping6' time='MASKED'/>
+  <testcase classname='PGW_Tests' name='TC_createSession_ping6_256' 
time='MASKED'/>
+  <testcase classname='PGW_Tests' name='TC_createSession_ping46' 
time='MASKED'/>
+  <testcase classname='PGW_Tests' name='TC_createSession_ping46_256' 
time='MASKED'/>
   <testcase classname='PGW_Tests' name='TC_createSession_deleteSession' 
time='MASKED'/>
   <testcase classname='PGW_Tests' name='TC_deleteSession_unknown' 
time='MASKED'/>
   <testcase classname='PGW_Tests' name='TC_gy_charging_cc_time' time='MASKED'/>
diff --git a/pgw/open5gs-smf.yaml b/pgw/open5gs-smf.yaml
index 49ec84b..34aabc3 100644
--- a/pgw/open5gs-smf.yaml
+++ b/pgw/open5gs-smf.yaml
@@ -49,8 +49,8 @@
       - subnet: 10.45.0.0/16
         gateway: 10.45.0.1
         dnn: internet
-      - subnet: cafe::/64
-        gateway: cafe::1
+      - subnet: 2001:db8:cafe::/48
+        gateway: 2001:db8:cafe::1
         dnn: internet
     dns:
       - 8.8.8.8
diff --git a/pgw/open5gs-upf.yaml b/pgw/open5gs-upf.yaml
index e65914e..39c47d5 100644
--- a/pgw/open5gs-upf.yaml
+++ b/pgw/open5gs-upf.yaml
@@ -22,8 +22,8 @@
         gateway: 10.45.0.1
         dnn: internet
         dev: ogstun46
-      - subnet: cafe::/64
-        gateway: cafe::1
+      - subnet: 2001:db8:cafe::/48
+        gateway: 2001:db8:cafe::1
         dnn: internet
         dev: ogstun46

diff --git a/pgw/testenv.sh b/pgw/testenv.sh
index 2abf999..7f155d1 100755
--- a/pgw/testenv.sh
+++ b/pgw/testenv.sh
@@ -46,6 +46,10 @@
        sudo ip link set ogstun4 up
        sudo ip link set ogstun6 up
        sudo ip link set ogstun46 up
+
+       # The IPv4 route is added automatically when setting the interface addr 
above:
+       sudo ip route add "10.45.0.0/16" dev "ogstun46" || true
+       sudo ip -6 route add "2001:db8:cafe::/48" dev "ogstun46" || true
 }

 del_tun() {

--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/42501?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: Idf009b9118db8117c547a1bb0f27afdfa3f03924
Gerrit-Change-Number: 42501
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>

Reply via email to