Changes of Revision 548

open5gs_2.7.0.16.77281.202312202026.dsc Deleted
x
 
1
@@ -1,39 +0,0 @@
2
-Format: 3.0 (native)
3
-Source: open5gs
4
-Binary: open5gs-common, open5gs-mme, open5gs-sgwc, open5gs-smf, open5gs-amf, open5gs-sgwu, open5gs-upf, open5gs-hss, open5gs-pcrf, open5gs-nrf, open5gs-scp, open5gs-sepp, open5gs-ausf, open5gs-udm, open5gs-pcf, open5gs-nssf, open5gs-bsf, open5gs-udr, open5gs, open5gs-dbg
5
-Architecture: any
6
-Version: 2.7.0.16.77281.202312202026
7
-Maintainer: Harald Welte <laforge@gnumonks.org>
8
-Uploaders: Sukchan Lee <acetcom@gmail.com>
9
-Homepage: https://open5gs.org
10
-Standards-Version: 4.3.0
11
-Vcs-Browser: https://github.com/open5gs/open5gs
12
-Vcs-Git: git://github.com/open5gs/open5gs
13
-Build-Depends: debhelper (>= 11), git, pkg-config, meson (>= 0.43.0), cmake, flex, bison, libgnutls28-dev, libgcrypt-dev, libssl-dev, libidn11-dev, libmongoc-dev, libbson-dev, libsctp-dev, libyaml-dev, libmicrohttpd-dev, libcurl4-gnutls-dev, libnghttp2-dev, libtins-dev, libtalloc-dev
14
-Package-List:
15
- open5gs deb net optional arch=any
16
- open5gs-amf deb net optional arch=any
17
- open5gs-ausf deb net optional arch=any
18
- open5gs-bsf deb net optional arch=any
19
- open5gs-common deb net optional arch=any
20
- open5gs-dbg deb net optional arch=any
21
- open5gs-hss deb net optional arch=any
22
- open5gs-mme deb net optional arch=any
23
- open5gs-nrf deb net optional arch=any
24
- open5gs-nssf deb net optional arch=any
25
- open5gs-pcf deb net optional arch=any
26
- open5gs-pcrf deb net optional arch=any
27
- open5gs-scp deb net optional arch=any
28
- open5gs-sepp deb net optional arch=any
29
- open5gs-sgwc deb net optional arch=any
30
- open5gs-sgwu deb net optional arch=any
31
- open5gs-smf deb net optional arch=any
32
- open5gs-udm deb net optional arch=any
33
- open5gs-udr deb net optional arch=any
34
- open5gs-upf deb net optional arch=any
35
-Checksums-Sha1:
36
- 99c344244c959c487aae0c759e260cef2840c43b 14460392 open5gs_2.7.0.16.77281.202312202026.tar.xz
37
-Checksums-Sha256:
38
- 5fa02f42e8a97e2e59d549ec855db6b7af812edc65f3d1c345ae56952863bc42 14460392 open5gs_2.7.0.16.77281.202312202026.tar.xz
39
-Files:
40
- 94312605329ab14326e404a727b58c76 14460392 open5gs_2.7.0.16.77281.202312202026.tar.xz
41
open5gs_2.7.0.20.2390a.202312212026.dsc Added
41
 
1
@@ -0,0 +1,39 @@
2
+Format: 3.0 (native)
3
+Source: open5gs
4
+Binary: open5gs-common, open5gs-mme, open5gs-sgwc, open5gs-smf, open5gs-amf, open5gs-sgwu, open5gs-upf, open5gs-hss, open5gs-pcrf, open5gs-nrf, open5gs-scp, open5gs-sepp, open5gs-ausf, open5gs-udm, open5gs-pcf, open5gs-nssf, open5gs-bsf, open5gs-udr, open5gs, open5gs-dbg
5
+Architecture: any
6
+Version: 2.7.0.20.2390a.202312212026
7
+Maintainer: Harald Welte <laforge@gnumonks.org>
8
+Uploaders: Sukchan Lee <acetcom@gmail.com>
9
+Homepage: https://open5gs.org
10
+Standards-Version: 4.3.0
11
+Vcs-Browser: https://github.com/open5gs/open5gs
12
+Vcs-Git: git://github.com/open5gs/open5gs
13
+Build-Depends: debhelper (>= 11), git, pkg-config, meson (>= 0.43.0), cmake, flex, bison, libgnutls28-dev, libgcrypt-dev, libssl-dev, libidn11-dev, libmongoc-dev, libbson-dev, libsctp-dev, libyaml-dev, libmicrohttpd-dev, libcurl4-gnutls-dev, libnghttp2-dev, libtins-dev, libtalloc-dev
14
+Package-List:
15
+ open5gs deb net optional arch=any
16
+ open5gs-amf deb net optional arch=any
17
+ open5gs-ausf deb net optional arch=any
18
+ open5gs-bsf deb net optional arch=any
19
+ open5gs-common deb net optional arch=any
20
+ open5gs-dbg deb net optional arch=any
21
+ open5gs-hss deb net optional arch=any
22
+ open5gs-mme deb net optional arch=any
23
+ open5gs-nrf deb net optional arch=any
24
+ open5gs-nssf deb net optional arch=any
25
+ open5gs-pcf deb net optional arch=any
26
+ open5gs-pcrf deb net optional arch=any
27
+ open5gs-scp deb net optional arch=any
28
+ open5gs-sepp deb net optional arch=any
29
+ open5gs-sgwc deb net optional arch=any
30
+ open5gs-sgwu deb net optional arch=any
31
+ open5gs-smf deb net optional arch=any
32
+ open5gs-udm deb net optional arch=any
33
+ open5gs-udr deb net optional arch=any
34
+ open5gs-upf deb net optional arch=any
35
+Checksums-Sha1:
36
+ c4385e9312d96b20db57e9b433fb5ae457d52697 14464488 open5gs_2.7.0.20.2390a.202312212026.tar.xz
37
+Checksums-Sha256:
38
+ fabfa4e0ca163aeb18b92a1930de1733c03924f7e54bc00b5a0f67414b9a50d8 14464488 open5gs_2.7.0.20.2390a.202312212026.tar.xz
39
+Files:
40
+ 1d2aac6900a3811f49cdfcd765f8da95 14464488 open5gs_2.7.0.20.2390a.202312212026.tar.xz
41
open5gs_2.7.0.16.77281.202312202026.tar.xz/.tarball-version -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/.tarball-version Changed
4
 
1
@@ -1 +1 @@
2
-2.7.0.16-77281.202312202026
3
+2.7.0.20-2390a.202312212026
4
open5gs_2.7.0.16.77281.202312202026.tar.xz/debian/changelog -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/debian/changelog Changed
12
 
1
@@ -1,8 +1,8 @@
2
-open5gs (2.7.0.16.77281.202312202026) unstable; urgency=medium
3
+open5gs (2.7.0.20.2390a.202312212026) unstable; urgency=medium
4
 
5
   * Automatically generated changelog entry for building the Osmocom nightly feed
6
 
7
- -- Osmocom OBS scripts <info@osmocom.org>  Wed, 20 Dec 2023 20:27:33 +0000
8
+ -- Osmocom OBS scripts <info@osmocom.org>  Thu, 21 Dec 2023 20:27:34 +0000
9
 
10
 open5gs (2.7.0) unstable; urgency=medium
11
 
12
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/app/ogs-init.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/app/ogs-init.c Changed
19
 
1
@@ -197,7 +197,7 @@
2
             break;
3
         case YAML_SCANNER_ERROR:
4
             if (parser.context)
5
-                ogs_error("Scanner error - %s at line %zu, column %zu"
6
+                ogs_error("Scanner error - %s at line %zu, column %zu "
7
                         "%s at line %zu, column %zu", parser.context,
8
                         parser.context_mark.line+1,
9
                         parser.context_mark.column+1,
10
@@ -210,7 +210,7 @@
11
             break;
12
         case YAML_PARSER_ERROR:
13
             if (parser.context)
14
-                ogs_error("Parser error - %s at line %zu, column %zu"
15
+                ogs_error("Parser error - %s at line %zu, column %zu "
16
                         "%s at line %zu, column %zu", parser.context,
17
                         parser.context_mark.line+1,
18
                         parser.context_mark.column+1,
19
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/crypt/ogs-kdf.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/crypt/ogs-kdf.c Changed
68
 
1
@@ -34,6 +34,9 @@
2
 #define FC_FOR_KENB_DERIVATION                  0x11
3
 #define FC_FOR_NH_ENB_DERIVATION                0x12
4
 #define FC_FOR_EPS_ALGORITHM_KEY_DERIVATION     0x15
5
+#define FC_FOR_CK_IK_DERIVATION_HANDOVER        0x16
6
+#define FC_FOR_NAS_TOKEN_DERIVATION             0x17
7
+#define FC_FOR_CK_IK_DERIVATION_IDLE_MOBILITY   0x1B
8
 
9
 typedef struct kdf_param_s {
10
     const uint8_t *buf;
11
@@ -379,6 +382,56 @@
12
     memcpy(knas, output+16, 16);
13
 }
14
 
15
+/* TS33.401 Annex A.8: KASME to CK', IK' derivation at handover */
16
+void ogs_kdf_ck_ik_handover(
17
+    uint32_t dl_count, const uint8_t *kasme, uint8_t *ck, uint8_t *ik)
18
+{
19
+    kdf_param_t param;
20
+    uint8_t outputOGS_SHA256_DIGEST_SIZE;
21
+
22
+    memset(param, 0, sizeof(param));
23
+    param0.buf = (uint8_t *)&dl_count;
24
+    param0.len = 4;
25
+
26
+    ogs_kdf_common(kasme, OGS_SHA256_DIGEST_SIZE,
27
+            FC_FOR_CK_IK_DERIVATION_HANDOVER, param, output);
28
+    memcpy(ck, output, 16);
29
+    memcpy(ik, output+16, 16);
30
+}
31
+
32
+/* TS33.401 Annex A.9: NAS token derivation for inter-RAT mobility */
33
+void ogs_kdf_nas_token(
34
+    uint32_t ul_count, const uint8_t *kasme, uint8_t *nas_token)
35
+{
36
+    kdf_param_t param;
37
+    uint8_t outputOGS_SHA256_DIGEST_SIZE;
38
+
39
+    memset(param, 0, sizeof(param));
40
+    param0.buf = (uint8_t *)&ul_count;
41
+    param0.len = 4;
42
+
43
+    ogs_kdf_common(kasme, OGS_SHA256_DIGEST_SIZE,
44
+            FC_FOR_NAS_TOKEN_DERIVATION, param, output);
45
+    memcpy(nas_token, output, 2);
46
+}
47
+
48
+/* TS33.401 Annex A.13: KASME to CK', IK' derivation at idle mobility */
49
+void ogs_kdf_ck_ik_idle_mobility(
50
+    uint32_t ul_count, const uint8_t *kasme, uint8_t *ck, uint8_t *ik)
51
+{
52
+    kdf_param_t param;
53
+    uint8_t outputOGS_SHA256_DIGEST_SIZE;
54
+
55
+    memset(param, 0, sizeof(param));
56
+    param0.buf = (uint8_t *)&ul_count;
57
+    param0.len = 4;
58
+
59
+    ogs_kdf_common(kasme, OGS_SHA256_DIGEST_SIZE,
60
+            FC_FOR_CK_IK_DERIVATION_IDLE_MOBILITY, param, output);
61
+    memcpy(ck, output, 16);
62
+    memcpy(ik, output+16, 16);
63
+}
64
+
65
 /*
66
  * TS33.401 Annex I Hash Functions
67
  * Use the KDF given in TS33.220
68
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/crypt/ogs-kdf.h -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/crypt/ogs-kdf.h Changed
20
 
1
@@ -101,6 +101,18 @@
2
 void ogs_kdf_nas_eps(uint8_t algorithm_type_distinguishers,
3
     uint8_t algorithm_identity, const uint8_t *kasme, uint8_t *knas);
4
 
5
+/* TS33.401 Annex A.8: KASME to CK', IK' derivation at handover */
6
+void ogs_kdf_ck_ik_handover(
7
+    uint32_t dl_count, const uint8_t *kasme, uint8_t *ck, uint8_t *ik);
8
+
9
+/* TS33.401 Annex A.9: NAS token derivation for inter-RAT mobility */
10
+void ogs_kdf_nas_token(
11
+    uint32_t ul_count, const uint8_t *kasme, uint8_t *nas_token);
12
+
13
+/* TS33.401 Annex A.13: KASME to CK', IK' derivation at idle mobility */
14
+void ogs_kdf_ck_ik_idle_mobility(
15
+    uint32_t ul_count, const uint8_t *kasme, uint8_t *ck, uint8_t *ik);
16
+
17
 /*
18
  * TS33.401 Annex I Hash Functions
19
  * Use the KDF given in TS33.220
20
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/gtp/v1/conv.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/gtp/v1/conv.c Changed
36
 
1
@@ -104,6 +104,34 @@
2
     return OGS_OK;
3
 }
4
 
5
+int ogs_gtp1_pdu_session_type_to_eua_ietf_type(uint8_t session_type)
6
+{
7
+    switch (session_type) {
8
+    case OGS_PDU_SESSION_TYPE_IPV4:
9
+        return OGS_PDP_EUA_IETF_IPV4;
10
+    case OGS_PDU_SESSION_TYPE_IPV6:
11
+        return OGS_PDP_EUA_IETF_IPV6;
12
+    case OGS_PDU_SESSION_TYPE_IPV4V6:
13
+        return OGS_PDP_EUA_IETF_IPV4V6;
14
+    default:
15
+        return OGS_ERROR;
16
+    }
17
+}
18
+
19
+int ogs_gtp1_eua_ietf_type_to_pdu_session_type(uint8_t eua_ietf_type)
20
+{
21
+    switch (eua_ietf_type) {
22
+    case OGS_PDP_EUA_IETF_IPV4:
23
+        return OGS_PDU_SESSION_TYPE_IPV4;
24
+    case OGS_PDP_EUA_IETF_IPV6:
25
+        return OGS_PDU_SESSION_TYPE_IPV6;
26
+    case OGS_PDP_EUA_IETF_IPV4V6:
27
+        return OGS_PDU_SESSION_TYPE_IPV4V6;
28
+    default:
29
+        return OGS_ERROR;
30
+    }
31
+}
32
+
33
 int ogs_gtp1_eua_to_ip(const ogs_eua_t *eua, uint16_t eua_len, ogs_ip_t *ip,
34
         uint8_t *pdu_session_type)
35
 {
36
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/gtp/v1/conv.h -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/gtp/v1/conv.h Changed
11
 
1
@@ -35,6 +35,9 @@
2
 int ogs_gtp1_gsn_addr_to_ip(const ogs_gtp1_gsn_addr_t *gsnaddr, uint16_t gsnaddr_len,
3
         ogs_ip_t *ip);
4
 
5
+int ogs_gtp1_pdu_session_type_to_eua_ietf_type(uint8_t session_type);
6
+int ogs_gtp1_eua_ietf_type_to_pdu_session_type(uint8_t eua_ietf_type);
7
+
8
 int ogs_gtp1_eua_to_ip(const ogs_eua_t *eua, uint16_t eua_len, ogs_ip_t *ip,
9
         uint8_t *pdu_session_type);
10
 
11
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/gtp/v1/types.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/gtp/v1/types.c Changed
201
 
1
@@ -398,3 +398,318 @@
2
         octet->len = 6;
3
     return octet->len;
4
 }
5
+
6
+/* 7.7.28 MM Context */
7
+/* TODO: UMTS support, see Figure 41 and Figure 42. */
8
+int ogs_gtp1_build_mm_context(ogs_gtp1_tlv_mm_context_t *octet,
9
+    const ogs_gtp1_mm_context_decoded_t *decoded, uint8_t *data, int data_len)
10
+{
11
+    uint8_t *ptr = data;
12
+    unsigned int i;
13
+    uint16_t *len_ptr;
14
+    uint16_t val16;
15
+
16
+    ogs_assert(octet);
17
+    ogs_assert(data);
18
+    ogs_assert((size_t)data_len >= 1);
19
+
20
+    octet->data = data;
21
+
22
+#define CHECK_SPACE_ERR(bytes) \
23
+    if ((ptr - data) + (bytes) > data_len) \
24
+        return OGS_ERROR
25
+    CHECK_SPACE_ERR(1);
26
+    *ptr++ = (decoded->gupii & 0x01) << 7 |
27
+             (decoded->ugipai & 0x01) << 6 |
28
+             (decoded->used_gprs_protection_algo & 0x07) << 3 |
29
+             (decoded->ksi & 0x07);
30
+
31
+    CHECK_SPACE_ERR(1);
32
+    *ptr++ = (decoded->sec_mode & 0x03) << 6 |
33
+             (decoded->num_vectors & 0x07) << 3 |
34
+             (decoded->sec_mode == OGS_GTP1_SEC_MODE_USED_CIPHER_VALUE_UMTS_KEY_AND_QUINTUPLETS ?
35
+                decoded->used_cipher & 0x07 : 0x07);
36
+
37
+    CHECK_SPACE_ERR(sizeof(decoded->ck));
38
+    memcpy(ptr, &decoded->ck0, sizeof(decoded->ck));
39
+    ptr += sizeof(decoded->ck);
40
+
41
+    CHECK_SPACE_ERR(sizeof(decoded->ik));
42
+    memcpy(ptr, &decoded->ik0, sizeof(decoded->ik));
43
+    ptr += sizeof(decoded->ik);
44
+
45
+    /* Quintuplet Length */
46
+    CHECK_SPACE_ERR(2);
47
+    len_ptr = (uint16_t *)ptr; /* will be filled later */
48
+    ptr += 2;
49
+
50
+    for (i = 0; i < decoded->num_vectors; i++) {
51
+        CHECK_SPACE_ERR(sizeof(decoded->auth_quintuplets0));
52
+
53
+        memcpy(ptr, &decoded->auth_quintupletsi.rand, sizeof(decoded->auth_quintupletsi.rand));
54
+        ptr += sizeof(decoded->auth_quintupletsi.rand);
55
+
56
+        *ptr++ = decoded->auth_quintupletsi.xres_len;
57
+        memcpy(ptr, &decoded->auth_quintupletsi.xres0, decoded->auth_quintupletsi.xres_len);
58
+        ptr += decoded->auth_quintupletsi.xres_len;
59
+
60
+        memcpy(ptr, &decoded->auth_quintupletsi.ck, sizeof(decoded->auth_quintupletsi.ck));
61
+        ptr += sizeof(decoded->auth_quintupletsi.ck);
62
+        memcpy(ptr, &decoded->auth_quintupletsi.ik, sizeof(decoded->auth_quintupletsi.ik));
63
+        ptr += sizeof(decoded->auth_quintupletsi.ik);
64
+
65
+        *ptr++ = decoded->auth_quintupletsi.autn_len;
66
+        memcpy(ptr, &decoded->auth_quintupletsi.autn0, decoded->auth_quintupletsi.autn_len);
67
+        ptr += decoded->auth_quintupletsi.autn_len;
68
+    }
69
+
70
+    *len_ptr = htobe16(ptr - (((uint8_t *)len_ptr) + 2));
71
+
72
+    CHECK_SPACE_ERR(sizeof(decoded->drx_param));
73
+    memcpy(ptr, &decoded->drx_param, sizeof(decoded->drx_param));
74
+    ptr += sizeof(decoded->drx_param);
75
+
76
+    if (decoded->ms_network_capability_len != 0) {
77
+        /* MS Network Capability Length */
78
+        CHECK_SPACE_ERR(1 + decoded->ms_network_capability_len);
79
+        *ptr++ = decoded->ms_network_capability_len;
80
+        memcpy(ptr, &decoded->ms_network_capability, decoded->ms_network_capability_len);
81
+        ptr += decoded->ms_network_capability_len;
82
+    } else {
83
+        CHECK_SPACE_ERR(1);
84
+        *ptr++ = 0;
85
+    }
86
+
87
+    if (decoded->imeisv_len != 0) {
88
+        /* Container Len */
89
+        CHECK_SPACE_ERR(2);
90
+        val16 = htobe16(2 + decoded->imeisv_len);
91
+        memcpy(ptr, &val16, 2);
92
+        ptr += 2;
93
+
94
+        /* Container (Mobile Identity IMEISV), TS 29.060 Table 47A */
95
+        CHECK_SPACE_ERR(2 + decoded->imeisv_len);
96
+        *ptr++ = 0x23;
97
+        *ptr++ = decoded->imeisv_len; /* Length of mobile identity contents */
98
+        memcpy(ptr, &decoded->imeisv0, decoded->imeisv_len);
99
+        ptr += decoded->imeisv_len;
100
+    } else {
101
+        /* Container Len */
102
+        CHECK_SPACE_ERR(2);
103
+        *ptr++ = 0;
104
+        *ptr++ = 0;
105
+    }
106
+
107
+    if (decoded->nrsrna) {
108
+        CHECK_SPACE_ERR(2);
109
+        *ptr++ = 1;
110
+        *ptr++ = 0x01;
111
+    }
112
+
113
+    octet->len = (ptr - data);
114
+    return OGS_OK;
115
+#undef CHECK_SPACE_ERR
116
+}
117
+
118
+/* The format of EUA in PDP Context is not exactly the same for the entire EUA,
119
+ * hence a separate function is required to encode the value part of the address,
120
+ * instead of using regular ogs_gtp1_ip_to_eua(). */
121
+static int enc_pdp_ctx_as_eua(uint8_t pdu_session_type, const ogs_ip_t *ip,
122
+                              uint8_t *data, int data_len)
123
+{
124
+    switch (pdu_session_type)
125
+    {
126
+    case OGS_PDU_SESSION_TYPE_IPV4:
127
+        if (!ip->ipv4) {
128
+            ogs_error("EUA type IPv4 but no IPv4 address available");
129
+            return OGS_ERROR;
130
+        }
131
+        if (data_len < OGS_IPV4_LEN)
132
+            return OGS_ERROR;
133
+        memcpy(data, &ip->addr, OGS_IPV4_LEN);
134
+        return OGS_IPV4_LEN;
135
+    case OGS_PDU_SESSION_TYPE_IPV6:
136
+        if (!ip->ipv6) {
137
+            ogs_error("EUA type IPv4 but no IPv6 address available");
138
+            return OGS_ERROR;
139
+        }
140
+        if (data_len < OGS_IPV6_LEN)
141
+            return OGS_ERROR;
142
+        memcpy(data, ip->addr6, OGS_IPV6_LEN);
143
+        return OGS_IPV6_LEN;
144
+    case OGS_PDU_SESSION_TYPE_IPV4V6:
145
+        if (ip->ipv4 && ip->ipv6) {
146
+            if (data_len < OGS_IPV4_LEN + OGS_IPV6_LEN)
147
+                return OGS_ERROR;
148
+            memcpy(data, &ip->addr, OGS_IPV4_LEN);
149
+            memcpy(data + OGS_IPV4_LEN, ip->addr6, OGS_IPV6_LEN);
150
+            return OGS_IPV4_LEN + OGS_IPV6_LEN;
151
+        } else if (ip->ipv4) {
152
+            if (data_len < OGS_IPV4_LEN)
153
+                return OGS_ERROR;
154
+            memcpy(data, &ip->addr, OGS_IPV4_LEN);
155
+            return OGS_IPV4_LEN;
156
+        } else if (ip->ipv6) {
157
+            if (data_len < OGS_IPV6_LEN)
158
+                return OGS_ERROR;
159
+            memcpy(data, ip->addr6, OGS_IPV6_LEN);
160
+            return OGS_IPV6_LEN;
161
+        } else {
162
+            ogs_error("EUA type IPv4 but no IPv4 nor IPv6 address available");
163
+            return OGS_ERROR;
164
+        }
165
+        break;
166
+    default:
167
+        ogs_error("Unexpected session type");
168
+        return OGS_ERROR;
169
+    }
170
+    return OGS_OK;
171
+}
172
+
173
+/* TS 29.060 7.7.29 PDP Context */
174
+int ogs_gtp1_build_pdp_context(ogs_tlv_octet_t *octet,
175
+    const ogs_gtp1_pdp_context_decoded_t *decoded, uint8_t *data, int data_len)
176
+{
177
+    uint8_t *ptr = data;
178
+    uint16_t val16;
179
+    uint32_t val32;
180
+    int rv;
181
+    ogs_tlv_octet_t qos_sub_tlv_unused;
182
+
183
+    ogs_assert(octet);
184
+    ogs_assert(data);
185
+    ogs_assert((size_t)data_len >= 1);
186
+
187
+    octet->data = data;
188
+
189
+#define CHECK_SPACE_ERR(bytes) \
190
+    if ((ptr - data) + (bytes) > data_len) \
191
+        return OGS_ERROR
192
+
193
+    CHECK_SPACE_ERR(1);
194
+    *ptr++ = (decoded->ea << 7) | (decoded->vaa << 6) |
195
+             (decoded->asi << 5)| (decoded->order << 4) |
196
+             (decoded->nsapi & 0x0f);
197
+
198
+    CHECK_SPACE_ERR(1);
199
+    *ptr++ = (decoded->sapi & 0x0f);
200
+
201
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/gtp/v1/types.h -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/gtp/v1/types.h Changed
114
 
1
@@ -300,4 +300,112 @@
2
 int16_t ogs_gtp1_build_qos_profile(ogs_tlv_octet_t *octet,
3
     const ogs_gtp1_qos_profile_decoded_t *decoded, void *data, int data_len);
4
 
5
+/* 7.7.7 Authentication Triplet. FIXME: Not used in MME Gn scenario? */
6
+# if 0
7
+struct ogs_gtp1_auth_triplet_s {
8
+    uint8_t rand16;
9
+    uint8_t sres4;
10
+    uint8_t kc8;
11
+} __attribute__ ((packed)) ogs_gtp1_auth_triplet_t;
12
+#endif
13
+
14
+/* 7.7.35 Authentication Quintuplet */
15
+typedef struct ogs_gtp1_auth_quintuplet_s {
16
+    uint8_t randOGS_RAND_LEN;
17
+    uint8_t xres_len;
18
+    uint8_t xresOGS_MAX_RES_LEN;
19
+    uint8_t ck128/8;
20
+    uint8_t ik128/8;
21
+    uint8_t autn_len;
22
+    uint8_t autnOGS_AUTN_LEN;
23
+} ogs_gtp1_auth_quintuplet_t;
24
+
25
+/* TS 24.008 10.5.5.6 DRX parameter (value part only) */
26
+typedef struct ogs_gtp1_drx_param_val_s {
27
+    uint8_t split_pg_cycle_code; /* 0 = equivalent to no DRX */
28
+    ED3(uint8_t cn_drx_cycle_len_coeff:4;,
29
+    uint8_t split_on_ccch:1;,
30
+    uint8_t non_drx_timer:3;)
31
+} __attribute__ ((packed)) ogs_gtp1_drx_param_val_t;
32
+
33
+
34
+
35
+/* 7.7.28 MM Context (Figure 41) */
36
+/* Table 47: Security Mode Values */
37
+#define OGS_GTP1_SEC_MODE_GSM_KEY_AND_TRIPLETS 1
38
+#define OGS_GTP1_SEC_MODE_GSM_KEY_AND_QUINTUPLETS 3
39
+#define OGS_GTP1_SEC_MODE_UMTS_KEY_AND_QUINTUPLETS 2
40
+#define OGS_GTP1_SEC_MODE_USED_CIPHER_VALUE_UMTS_KEY_AND_QUINTUPLETS 0
41
+/* Table 47B: Used GPRS integrity protection algorithm Values */
42
+#define OGS_GTP1_USED_GPRS_IP_NO_IP 0
43
+#define OGS_GTP1_USED_GPRS_IP_GIA4 4
44
+#define OGS_GTP1_USED_GPRS_IP_GIA5 5
45
+typedef struct ogs_gtp1_mm_context_decoded_s {
46
+    uint8_t gupii:1;
47
+    uint8_t ugipai:1;
48
+    uint8_t used_gprs_protection_algo:3; /* OGS_GTP1_USED_GPRS_IP */
49
+    uint8_t ksi:3;
50
+    uint8_t sec_mode:2; /* OGS_GTP1_SEC_MODE_* */
51
+    uint8_t num_vectors:3;
52
+    uint8_t used_cipher:3; /* 0..7 -> GEA/... */
53
+    uint8_t ckOGS_SHA256_DIGEST_SIZE/2;
54
+    uint8_t ikOGS_SHA256_DIGEST_SIZE/2;
55
+    ogs_gtp1_auth_quintuplet_t auth_quintuplets5;
56
+    ogs_gtp1_drx_param_val_t drx_param;
57
+    uint8_t ms_network_capability_len;
58
+    uint8_t ms_network_capability6; /* ogs_nas_ms_network_capability_t */
59
+    uint8_t imeisv_len;
60
+    uint8_t imeisv10; /* ogs_nas_mobile_identity_imeisv_t */
61
+    uint8_t nrsrna;
62
+} ogs_gtp1_mm_context_decoded_t;
63
+
64
+int ogs_gtp1_build_mm_context(ogs_gtp1_tlv_mm_context_t *octet,
65
+    const ogs_gtp1_mm_context_decoded_t *decoded, uint8_t *data, int data_len);
66
+
67
+/* Extended End User Address. Not explicitly defined in a table: */
68
+#define OGS_GTP1_PDPCTX_EXT_EUA_NO 0
69
+#define OGS_GTP1_PDPCTX_EXT_EUA_YES 1
70
+
71
+/* 7.7.29 Table 48 Reordering Required Values */
72
+#define OGS_GTP1_PDPCTX_REORDERING_REQUIRED_NO 0
73
+#define OGS_GTP1_PDPCTX_REORDERING_REQUIRED_YES 1
74
+
75
+/* 7.7.29 Table 49 VPLMN Address Allowed Values */
76
+#define OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_NO 0
77
+#define OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_YES 1
78
+
79
+/* 7.7.29 Table 49A Activity Status Indicator Value */
80
+#define OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_YES 0
81
+#define OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_NO 1
82
+
83
+/* 7.7.29 PDP Context */
84
+typedef struct ogs_gtp1_pdp_context_decoded_s {
85
+    uint8_t ea:1; /* OGS_GTP1_PDPCTX_EXT_EUA_* */
86
+    uint8_t vaa:1; /* OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_* */
87
+    uint8_t asi:1; /* OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_* */
88
+    uint8_t order:1; /* OGS_GTP1_PDPCTX_REORDERING_REQUIRED_* */
89
+    uint8_t nsapi:4;
90
+    uint8_t sapi:4;
91
+    ogs_gtp1_qos_profile_decoded_t qos_sub;
92
+    ogs_gtp1_qos_profile_decoded_t qos_req;
93
+    ogs_gtp1_qos_profile_decoded_t qos_neg;
94
+    uint16_t snd;
95
+    uint16_t snu;
96
+    uint8_t send_npdu_nr;
97
+    uint8_t receive_npdu_nr;
98
+    uint32_t ul_teic;
99
+    uint32_t ul_teid;
100
+    uint8_t pdp_ctx_id;
101
+    uint8_t pdp_type_org;
102
+    uint8_t pdp_type_num2;
103
+    ogs_ip_t pdp_address2;
104
+    ogs_ip_t ggsn_address_c;
105
+    ogs_ip_t ggsn_address_u;
106
+    char apnOGS_MAX_APN_LEN+1;
107
+    uint16_t trans_id:12;
108
+} ogs_gtp1_pdp_context_decoded_t;
109
+
110
+int ogs_gtp1_build_pdp_context(ogs_gtp1_tlv_pdp_context_t *octet,
111
+    const ogs_gtp1_pdp_context_decoded_t *decoded, uint8_t *data, int data_len);
112
+
113
 #endif /* OGS_GTP1_TYPES_H */
114
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/gtp/xact.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/gtp/xact.c Changed
42
 
1
@@ -859,11 +859,11 @@
2
         }
3
     }
4
 
5
-    ogs_debug("%d Cannot find xact type %u from GTPv1 peer %s:%d",
6
-            xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
7
-
8
-    if (!new)
9
+    if (!new) {
10
+        ogs_debug("%d Cannot find xact type %u from GTPv1 peer %s:%d",
11
+                  xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
12
         new = ogs_gtp_xact_remote_create(gnode, 1, sqn);
13
+    }
14
     ogs_assert(new);
15
 
16
     ogs_debug("%d %s Receive peer %s:%d",
17
@@ -947,12 +947,11 @@
18
         }
19
     }
20
 
21
-    ogs_debug("%d Cannot find xact type %u from GTPv2 peer %s:%d",
22
-            xid, type,
23
-            OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
24
-
25
-    if (!new)
26
+    if (!new) {
27
+        ogs_debug("%d Cannot find xact type %u from GTPv2 peer %s:%d",
28
+                  xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
29
         new = ogs_gtp_xact_remote_create(gnode, 2, sqn);
30
+    }
31
     ogs_assert(new);
32
 
33
     ogs_debug("%d %s Receive peer %s:%d",
34
@@ -1013,6 +1012,7 @@
35
     case OGS_GTP1_NOTE_MS_GPRS_PRESENT_RESPONSE_TYPE:
36
     case OGS_GTP1_IDENTIFICATION_RESPONSE_TYPE:
37
     case OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE:
38
+    case OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE:
39
     case OGS_GTP1_FORWARD_RELOCATION_RESPONSE_TYPE:
40
     case OGS_GTP1_RELOCATION_CANCEL_RESPONSE_TYPE:
41
     case OGS_GTP1_UE_REGISTRATION_QUERY_RESPONSE_TYPE:
42
open5gs_2.7.0.16.77281.202312202026.tar.xz/lib/pfcp/xact.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/lib/pfcp/xact.c Changed
17
 
1
@@ -717,11 +717,11 @@
2
         }
3
     }
4
 
5
-    ogs_debug("%d Cannot find new type %u from PFCP peer %s:%d",
6
-            xid, type, OGS_ADDR(&node->addr, buf), OGS_PORT(&node->addr));
7
-
8
-    if (!new)
9
+    if (!new) {
10
+        ogs_debug("%d Cannot find new type %u from PFCP peer %s:%d",
11
+                  xid, type, OGS_ADDR(&node->addr, buf), OGS_PORT(&node->addr));
12
         new = ogs_pfcp_xact_remote_create(node, sqn);
13
+    }
14
     ogs_assert(new);
15
 
16
     ogs_debug("%d %s Receive peer %s:%d",
17
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-context.h -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-context.h Changed
13
 
1
@@ -421,6 +421,11 @@
2
     char            a_msisdn_bcdOGS_MAX_MSISDN_BCD_LEN+1;
3
 
4
     mme_p_tmsi_t    p_tmsi;
5
+    struct {
6
+        uint32_t        sgsn_gn_teid;
7
+        ogs_ip_t        sgsn_gn_ip;
8
+        ogs_ip_t        sgsn_gn_ip_alt;
9
+    } gn;
10
 
11
     struct {
12
         mme_m_tmsi_t *m_tmsi;
13
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-gn-build.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-gn-build.c Changed
201
 
1
@@ -21,6 +21,262 @@
2
 
3
 #include "mme-gn-build.h"
4
 
5
+static int sess_fill_mm_context_decoded(mme_sess_t *sess, ogs_gtp1_mm_context_decoded_t *mmctx_dec)
6
+{
7
+    mme_ue_t *mme_ue = sess->mme_ue;
8
+    mme_bearer_t *bearer = NULL;
9
+    *mmctx_dec = (ogs_gtp1_mm_context_decoded_t) {
10
+        .gupii = 1, /* Integrity Protection not required */
11
+        .ugipai = 1, /* Ignore "Used GPRS integrity protection algorithm" field" */
12
+        .ksi = mme_ue->nas_eps.ksi,
13
+        .sec_mode = OGS_GTP1_SEC_MODE_UMTS_KEY_AND_QUINTUPLETS,
14
+        .num_vectors = 0, /* TODO: figure out how to fill the quintuplets */
15
+        .drx_param = {
16
+            .split_pg_cycle_code = 0, /* equivalent to no DRX */
17
+            .cn_drx_cycle_len_coeff = 0,
18
+            .split_on_ccch = 0,
19
+            .non_drx_timer = 0,
20
+        },
21
+        .nrsrna = 0,
22
+    };
23
+
24
+    //TODO: derive cK Ki from mme_ue->kasme
25
+    ogs_kdf_ck_ik_idle_mobility(mme_ue->ul_count.i32, mme_ue->kasme, &mmctx_dec->ck0, &mmctx_dec->ik0);
26
+
27
+    mmctx_dec->imeisv_len = sizeof(mme_ue->nas_mobile_identity_imeisv);
28
+    memcpy(&mmctx_dec->imeisv0, &mme_ue->nas_mobile_identity_imeisv, sizeof(mme_ue->nas_mobile_identity_imeisv));
29
+
30
+    mmctx_dec->ms_network_capability_len = mme_ue->ms_network_capability.length;
31
+    memcpy(&mmctx_dec->ms_network_capability0, ((uint8_t*)&mme_ue->ms_network_capability)+1, sizeof(mme_ue->ms_network_capability) - 1);
32
+
33
+    ogs_list_for_each(&sess->bearer_list, bearer) {
34
+
35
+        /* FIXME: only 1 PDP Context supported in the message so far. */
36
+        break;
37
+    }
38
+
39
+    return OGS_OK;
40
+}
41
+
42
+/* 3GPP TS 23.401 Annex E */
43
+static void build_qos_profile_from_session(ogs_gtp1_qos_profile_decoded_t *qos_pdec,
44
+        const mme_sess_t *sess, const mme_bearer_t *bearer)
45
+{
46
+    const mme_ue_t *mme_ue = sess->mme_ue;
47
+    const ogs_session_t *session = sess->session;
48
+    /* FIXME: Initialize with defaults: */
49
+    memset(qos_pdec, 0, sizeof(*qos_pdec));
50
+
51
+    qos_pdec->qos_profile.arp = session->qos.arp.priority_level;
52
+
53
+     /* 3GPP TS 23.401 Annex E table Table E.3 */
54
+    /* Also take into account table 7 in 3GPP TS 23.107 9.1.2.2 */
55
+    switch (session->qos.index) { /* QCI */
56
+    case 1:
57
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_CONVERSATIONAL;
58
+        qos_pdec->qos_profile.data.source_statistics_descriptor = OGS_GTP1_QOS_SRC_STATS_DESC_SPEECH;
59
+        qos_pdec->dec_transfer_delay = 150;
60
+        qos_pdec->qos_profile.data.delay_class = 1;
61
+        break;
62
+    case 2:
63
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_CONVERSATIONAL;
64
+        qos_pdec->qos_profile.data.source_statistics_descriptor = OGS_GTP1_QOS_SRC_STATS_DESC_UNKNOWN;
65
+        qos_pdec->dec_transfer_delay = 150;
66
+        qos_pdec->qos_profile.data.delay_class = 1;
67
+        break;
68
+    case 3:
69
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_CONVERSATIONAL;
70
+        qos_pdec->qos_profile.data.source_statistics_descriptor = OGS_GTP1_QOS_SRC_STATS_DESC_UNKNOWN;
71
+        qos_pdec->dec_transfer_delay = 80;
72
+        qos_pdec->qos_profile.data.delay_class = 1;
73
+        break;
74
+    case 4:
75
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_STREAMING;
76
+        qos_pdec->qos_profile.data.source_statistics_descriptor = OGS_GTP1_QOS_SRC_STATS_DESC_UNKNOWN;
77
+        qos_pdec->qos_profile.data.sdu_error_ratio = 5; /* 10^-5*/
78
+        qos_pdec->qos_profile.data.delay_class = 1;
79
+        break;
80
+    case 5:
81
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_INTERACTIVE;
82
+        qos_pdec->qos_profile.data.traffic_handling_priority = 1;
83
+        qos_pdec->qos_profile.data.signalling_indication = 1;
84
+        qos_pdec->qos_profile.data.delay_class = qos_pdec->qos_profile.data.traffic_handling_priority;
85
+        break;
86
+    case 6:
87
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_INTERACTIVE;
88
+        qos_pdec->qos_profile.data.traffic_handling_priority = 1;
89
+        qos_pdec->qos_profile.data.delay_class = qos_pdec->qos_profile.data.traffic_handling_priority;
90
+        break;
91
+    case 7:
92
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_INTERACTIVE;
93
+        qos_pdec->qos_profile.data.traffic_handling_priority = 2;
94
+        qos_pdec->qos_profile.data.delay_class = qos_pdec->qos_profile.data.traffic_handling_priority;
95
+        break;
96
+    case 8:
97
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_INTERACTIVE;
98
+        qos_pdec->qos_profile.data.traffic_handling_priority = 3;
99
+        qos_pdec->qos_profile.data.delay_class = qos_pdec->qos_profile.data.traffic_handling_priority;
100
+        break;
101
+    case 9:
102
+    default:
103
+        qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_BACKGROUND;
104
+        qos_pdec->qos_profile.data.delay_class = 4;
105
+        break;
106
+    }
107
+
108
+    qos_pdec->data_octet6_to_13_present = true;
109
+    qos_pdec->data_octet14_present = true;
110
+    qos_pdec->dec_mbr_kbps_dl = mme_ue->ambr.downlink / 1000;
111
+    qos_pdec->dec_mbr_kbps_ul = mme_ue->ambr.uplink / 1000;
112
+    qos_pdec->dec_gbr_kbps_dl = bearer->qos.gbr.downlink / 1000;
113
+    qos_pdec->dec_gbr_kbps_ul = bearer->qos.gbr.uplink / 1000;
114
+}
115
+
116
+static int sess_fill_pdp_context_decoded(mme_sess_t *sess, ogs_gtp1_pdp_context_decoded_t *pdpctx_dec)
117
+{
118
+    mme_bearer_t *bearer = NULL;
119
+
120
+    *pdpctx_dec = (ogs_gtp1_pdp_context_decoded_t){
121
+        .ea = OGS_GTP1_PDPCTX_EXT_EUA_NO,
122
+        .vaa = OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_YES,
123
+        .asi = OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_NO,
124
+        .order = OGS_GTP1_PDPCTX_REORDERING_REQUIRED_NO,
125
+        .ul_teic = sess->pgw_s5c_teid,
126
+    };
127
+
128
+    pdpctx_dec->ggsn_address_c = sess->pgw_s5c_ip;
129
+    pdpctx_dec->pdp_type_org = OGS_PDP_EUA_ORG_IETF;
130
+    pdpctx_dec->pdp_type_num0 = sess->session->session_type;
131
+    pdpctx_dec->pdp_address0 = sess->session->ue_ip;
132
+    ogs_cpystrn(pdpctx_dec->apn, sess->session->name, sizeof(pdpctx_dec->apn));
133
+    pdpctx_dec->trans_id = sess->pti;
134
+
135
+    ogs_list_for_each(&sess->bearer_list, bearer) {
136
+        pdpctx_dec->nsapi  = bearer->ebi;
137
+        pdpctx_dec->sapi = 3; /* FIXME. Using 3 = default for now. Maybe use 0 = UNASSIGNED ?*/
138
+        build_qos_profile_from_session(&pdpctx_dec->qos_sub, sess, bearer);
139
+        //FIXME: sort out where to get each one:
140
+        memcpy(&pdpctx_dec->qos_req, &pdpctx_dec->qos_sub, sizeof(pdpctx_dec->qos_sub));
141
+        memcpy(&pdpctx_dec->qos_neg, &pdpctx_dec->qos_sub, sizeof(pdpctx_dec->qos_sub));
142
+        pdpctx_dec->snd = 0; /* FIXME. */
143
+        pdpctx_dec->snu = 0; /* FIXME. */
144
+        pdpctx_dec->send_npdu_nr = 0; /* FIXME. */
145
+        pdpctx_dec->receive_npdu_nr = 0; /* FIXME. */
146
+        pdpctx_dec->ul_teid = bearer->pgw_s5u_teid;
147
+        pdpctx_dec->pdp_ctx_id = 0; /* FIXME. */
148
+        pdpctx_dec->ggsn_address_u = bearer->pgw_s5u_ip;
149
+        /* TODO: session->qos and bearer->qos to fill something in pdpctx_dec. */
150
+
151
+        /* FIXME: only 1 PDP Context supported in the message so far. */
152
+        break;
153
+    }
154
+
155
+    return OGS_OK;
156
+}
157
+
158
+/* 3GPP TS 29.060 7.5.4 SGSN Context Response */
159
+ogs_pkbuf_t *mme_gn_build_sgsn_context_response(
160
+                mme_ue_t *mme_ue, uint8_t cause)
161
+{
162
+    ogs_gtp1_message_t gtp1_message;
163
+    ogs_gtp1_sgsn_context_response_t *rsp = NULL;
164
+    mme_sess_t *sess = NULL;
165
+    ogs_gtp1_gsn_addr_t mme_gnc_gsnaddr;
166
+    int gsn_len;
167
+    int rv;
168
+    ogs_gtp1_mm_context_decoded_t mmctx_dec;
169
+    uint8_t mmctx_dec_buf512;
170
+    ogs_gtp1_pdp_context_decoded_t pdpctx_dec;
171
+    uint8_t pdpctx_dec_buf1024;
172
+
173
+    ogs_debug("Gn build SGSN Context Response");
174
+
175
+    rsp = &gtp1_message.sgsn_context_response;
176
+    memset(&gtp1_message, 0, sizeof(ogs_gtp1_message_t));
177
+    gtp1_message.h.type = OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE;
178
+
179
+    /* 3GPP TS 29.060 7.7.1 Cause, Mandatory */
180
+    rsp->cause.presence = 1;
181
+    rsp->cause.u8 = cause;
182
+
183
+    /* 3GPP TS 29.060 7.7.2 IMSI, Conditional */
184
+    rsp->imsi.presence = !!mme_ue;
185
+    if (rsp->imsi.presence) {
186
+        rsp->imsi.data = mme_ue->imsi;
187
+        rsp->imsi.len = mme_ue->imsi_len;
188
+    }
189
+
190
+    if (cause != OGS_GTP1_CAUSE_REQUEST_ACCEPTED)
191
+        goto build_ret;
192
+
193
+    ogs_assert(mme_ue);
194
+
195
+    /* FIXME: Reuse S11 TEID as local Gn interface for now */
196
+    rsp->tunnel_endpoint_identifier_control_plane.presence = 1;
197
+    rsp->tunnel_endpoint_identifier_control_plane.u32 = mme_ue->mme_s11_teid;
198
+
199
+    ogs_list_for_each(&mme_ue->sess_list, sess) {
200
+        if (!MME_HAVE_SGW_S1U_PATH(sess))
201
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-gn-build.h -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-gn-build.h Changed
11
 
1
@@ -30,6 +30,9 @@
2
 }
3
 #endif
4
 
5
+ogs_pkbuf_t *mme_gn_build_sgsn_context_response(
6
+                mme_ue_t *mme_ue, uint8_t cause);
7
+
8
 ogs_pkbuf_t *mme_gn_build_ran_information_relay(
9
                 uint8_t type, const uint8_t *buf, size_t len,
10
                 const ogs_nas_rai_t *rai, uint16_t cell_id);
11
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-gn-handler.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-gn-handler.c Changed
119
 
1
@@ -68,6 +68,117 @@
2
     return OGS_OK;
3
 }
4
 
5
+/* 3GPP TS 23.003 2.8.2.2 Mapping from RAI and P-TMSI to GUT */
6
+static void rai_ptmsi_to_guti(const ogs_nas_rai_t *rai, mme_p_tmsi_t ptmsi, uint32_t ptmsi_sig, ogs_nas_eps_guti_t *nas_guti)
7
+{
8
+    uint16_t lac = be16toh(rai->lai.lac);;
9
+    nas_guti->nas_plmn_id =rai->lai.nas_plmn_id;
10
+    nas_guti->mme_gid = lac;
11
+    nas_guti->mme_code = rai->rac;
12
+    nas_guti->m_tmsi = 0xC0000000 | (ptmsi & 0x3f000000) | (ptmsi_sig & 0x00ff0000) | (ptmsi & 0x0000ffff);
13
+}
14
+
15
+/* TS 29.060 7.5.3 SGSN Context Request */
16
+void mme_gn_handle_sgsn_context_request(
17
+        ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_request_t *req)
18
+{
19
+    ogs_nas_eps_guti_t nas_guti;
20
+    ogs_nas_rai_t *rai;
21
+    mme_ue_t *mme_ue = NULL;
22
+    int rv;
23
+
24
+    ogs_debug("Gn Rx SGSN Context Request");
25
+
26
+    if (!req->routeing_area_identity.presence) {
27
+        ogs_warn("Gn Rx SGSN Context Request with no RAI!");
28
+        mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact);
29
+        return;
30
+    }
31
+    if (req->routeing_area_identity.len != sizeof(*rai)) {
32
+        ogs_warn("Gn Rx SGSN Context Request RAI wrong size %u vs exp %zu!",
33
+                 req->routeing_area_identity.len, sizeof(*rai));
34
+        mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT, xact);
35
+        return;
36
+    }
37
+    if (!req->tunnel_endpoint_identifier_control_plane.presence) {
38
+        ogs_warn("Gn Rx SGSN Context Request with no Tunnel Endpoint Identifier Control Plane!");
39
+        mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact);
40
+        return;
41
+    }
42
+    if (!req->sgsn_address_for_control_plane.presence) {
43
+        ogs_warn("Gn Rx SGSN Context Request with no SGSN Address for Control Plane!");
44
+        mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact);
45
+        return;
46
+    }
47
+    if (!req->imsi.presence &&
48
+        !req->temporary_logical_link_identifier.presence &&
49
+        !req->packet_tmsi.presence) {
50
+        ogs_warn("Gn Rx SGSN Context Request with no IMSI/TLLI/P-TMSI!");
51
+        mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact);
52
+        return;
53
+    }
54
+
55
+    if (req->ms_validated.presence &&
56
+        (req->ms_validated.u8 & 0x01) /* 1=> "Yes" */
57
+        && !req->imsi.presence) {
58
+        ogs_warn("Gn Rx SGSN Context Request with 'MS Validated' but no IMSI!");
59
+        mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact);
60
+        return;
61
+    }
62
+
63
+    rai = req->routeing_area_identity.data;
64
+
65
+    if (req->imsi.presence) {
66
+        mme_ue = mme_ue_find_by_imsi(req->imsi.data, req->imsi.len);
67
+    } else if (req->packet_tmsi.presence) { /* P-TMSI */
68
+        if (!req->p_tmsi_signature.presence) {
69
+            ogs_warn("Gn Rx SGSN Context Request with 'P-TMSI' but no P-TMSI Signature! Assuming value 0.");
70
+            req->p_tmsi_signature.u24 = 0;
71
+        }
72
+        rai_ptmsi_to_guti(rai, req->packet_tmsi.u32, req->p_tmsi_signature.u24, &nas_guti);
73
+        mme_ue = mme_ue_find_by_guti(&nas_guti);
74
+    } else if (req->temporary_logical_link_identifier.presence) {
75
+        if (!req->p_tmsi_signature.presence) {
76
+            ogs_warn("Gn Rx SGSN Context Request with 'TLLI' but no P-TMSI Signature! Assuming value 0.");
77
+            req->p_tmsi_signature.u24 = 0;
78
+        }
79
+        /* TS 29.060 7.5.3 "The TLLI/P-TMSI and RAI is a foreign TLLI/P-TMSI and an RAI in the old SGSN."
80
+         * A foregin TLLI is "tlli = (p_tmsi & 0x3fffffff) | 0x80000000", and since we only use 0x3fffffff
81
+         * bits of P-TMSI to derive the GUTI, it's totally fine passing the TLLI as P-TMSI. */
82
+        rai_ptmsi_to_guti(rai, req->temporary_logical_link_identifier.u32, req->p_tmsi_signature.u24, &nas_guti);
83
+        mme_ue = mme_ue_find_by_guti(&nas_guti);
84
+    }
85
+
86
+    if (!mme_ue) {
87
+        mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_IMSI_IMEI_NOT_KNOWN, xact);
88
+        return;
89
+    }
90
+
91
+    mme_ue->gn.sgsn_gn_teid = req->tunnel_endpoint_identifier_control_plane.u32;
92
+
93
+    rv = ogs_gtp1_gsn_addr_to_ip(req->sgsn_address_for_control_plane.data,
94
+                                 req->sgsn_address_for_control_plane.len,
95
+                                 &mme_ue->gn.sgsn_gn_ip);
96
+    ogs_assert(rv == OGS_OK);
97
+
98
+   if (req->alternative_sgsn_address_for_control_plane.presence) {
99
+        rv = ogs_gtp1_gsn_addr_to_ip(req->alternative_sgsn_address_for_control_plane.data,
100
+                                     req->alternative_sgsn_address_for_control_plane.len,
101
+                                    &mme_ue->gn.sgsn_gn_ip_alt);
102
+        ogs_assert(rv == OGS_OK);
103
+   }
104
+
105
+   mme_gtp1_send_sgsn_context_response(mme_ue, OGS_GTP1_CAUSE_REQUEST_ACCEPTED, xact);
106
+}
107
+
108
+/* TS 29.060 7.5.5 SGSN Context Acknowledge */
109
+void mme_gn_handle_sgsn_context_acknowledge(
110
+        ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_acknowledge_t *req)
111
+{
112
+    /* FIXME: find out what to do here, 3GPP TS 23.401 D.3.5
113
+     * Probably release the Session on the SGW (without releasing in the PGW) */
114
+}
115
+
116
 /* TS 29.060 7.5.14.1 */
117
 void mme_gn_handle_ran_information_relay(
118
         ogs_gtp_xact_t *xact, ogs_gtp1_ran_information_relay_t *req)
119
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-gn-handler.h -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-gn-handler.h Changed
14
 
1
@@ -32,6 +32,12 @@
2
 void mme_gn_handle_echo_response(
3
         ogs_gtp_xact_t *xact, ogs_gtp1_echo_response_t *req);
4
 
5
+void mme_gn_handle_sgsn_context_request(
6
+        ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_request_t *req);
7
+
8
+void mme_gn_handle_sgsn_context_acknowledge(
9
+        ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_acknowledge_t *req);
10
+
11
 void mme_gn_handle_ran_information_relay(
12
         ogs_gtp_xact_t *xact, ogs_gtp1_ran_information_relay_t *req);
13
 
14
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-gtp-path.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-gtp-path.c Changed
38
 
1
@@ -758,6 +758,36 @@
2
     return rv;
3
 }
4
 
5
+int mme_gtp1_send_sgsn_context_response(
6
+        mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact)
7
+{
8
+    int rv;
9
+    ogs_gtp1_header_t h;
10
+    ogs_pkbuf_t *pkbuf = NULL;
11
+
12
+    memset(&h, 0, sizeof(ogs_gtp1_header_t));
13
+    h.type = OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE;
14
+    h.teid = mme_ue ? mme_ue->gn.sgsn_gn_teid : 0;
15
+
16
+    pkbuf = mme_gn_build_sgsn_context_response(mme_ue, cause);
17
+    if (!pkbuf) {
18
+        ogs_error("mme_gn_build_sgsn_context_response() failed");
19
+        return OGS_ERROR;
20
+    }
21
+    /* FIXME: Reuse S11 TEID as local Gn interface for now */
22
+    xact->local_teid = mme_ue ? mme_ue->mme_s11_teid : 0;
23
+
24
+    rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf);
25
+    if (rv != OGS_OK) {
26
+        ogs_error("ogs_gtp1_xact_update_tx() failed");
27
+        return OGS_ERROR;
28
+    }
29
+
30
+    rv = ogs_gtp_xact_commit(xact);
31
+    ogs_expect(rv == OGS_OK);
32
+
33
+    return rv;
34
+}
35
 
36
 int mme_gtp1_send_ran_information_relay(
37
         mme_sgsn_t *sgsn, const uint8_t *buf, size_t len,
38
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-gtp-path.h -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-gtp-path.h Changed
11
 
1
@@ -55,6 +55,9 @@
2
 int mme_gtp_send_bearer_resource_command(
3
         mme_bearer_t *bearer, ogs_nas_eps_message_t *nas_message);
4
 
5
+int mme_gtp1_send_sgsn_context_response(
6
+        mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact);
7
+
8
 int mme_gtp1_send_ran_information_relay(
9
         mme_sgsn_t *sgsn, const uint8_t *buf, size_t len,
10
         const ogs_nas_rai_t *rai, uint16_t cell_id);
11
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-s6a-handler.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-s6a-handler.c Changed
19
 
1
@@ -33,7 +33,7 @@
2
 static uint8_t emm_cause_from_diameter(
3
                 const uint32_t *dia_err, const uint32_t *dia_exp_err);
4
 
5
-static uint8_t mme_ue_session_from_slice_data(mme_ue_t *mme_ue, 
6
+static uint8_t mme_ue_session_from_slice_data(mme_ue_t *mme_ue,
7
     ogs_slice_data_t *slice_data);
8
 
9
 uint8_t mme_s6a_handle_aia(
10
@@ -299,7 +299,7 @@
11
     }
12
 }
13
 
14
-static uint8_t mme_ue_session_from_slice_data(mme_ue_t *mme_ue, 
15
+static uint8_t mme_ue_session_from_slice_data(mme_ue_t *mme_ue,
16
     ogs_slice_data_t *slice_data)
17
 {
18
     int i;
19
open5gs_2.7.0.16.77281.202312202026.tar.xz/src/mme/mme-sm.c -> open5gs_2.7.0.20.2390a.202312212026.tar.xz/src/mme/mme-sm.c Changed
14
 
1
@@ -662,6 +662,12 @@
2
         case OGS_GTP1_ECHO_RESPONSE_TYPE:
3
             mme_gn_handle_echo_response(xact, &gtp1_message.echo_response);
4
             break;
5
+        case OGS_GTP1_SGSN_CONTEXT_REQUEST_TYPE:
6
+            mme_gn_handle_sgsn_context_request(xact, &gtp1_message.sgsn_context_request);
7
+            break;
8
+        case OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE:
9
+            mme_gn_handle_sgsn_context_acknowledge(xact, &gtp1_message.sgsn_context_acknowledge);
10
+            break;
11
         case OGS_GTP1_RAN_INFORMATION_RELAY_TYPE:
12
             mme_gn_handle_ran_information_relay(xact, &gtp1_message.ran_information_relay);
13
             break;
14