Changes of Revision 575

open5gs_2.7.0.57.52be.202401162026.dsc -> open5gs_2.7.0.59.6069.202401172026.dsc Changed
x
 
1
@@ -2,7 +2,7 @@
2
 Source: open5gs
3
 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
4
 Architecture: any
5
-Version: 2.7.0.57.52be.202401162026
6
+Version: 2.7.0.59.6069.202401172026
7
 Maintainer: Harald Welte <laforge@gnumonks.org>
8
 Uploaders: Sukchan Lee <acetcom@gmail.com>
9
 Homepage: https://open5gs.org
10
@@ -32,8 +32,8 @@
11
  open5gs-udr deb net optional arch=any
12
  open5gs-upf deb net optional arch=any
13
 Checksums-Sha1:
14
- d3db571edb7717440f4572c3e58e0ad88ba4b261 14467112 open5gs_2.7.0.57.52be.202401162026.tar.xz
15
+ 52206bc6d1ca933aac036557d901f2b5439a60ed 14470084 open5gs_2.7.0.59.6069.202401172026.tar.xz
16
 Checksums-Sha256:
17
- 420441ecaa4cab69449ccd5faae3c272d92f355c37127d10333b18bf819b69d7 14467112 open5gs_2.7.0.57.52be.202401162026.tar.xz
18
+ c309f70407d60b65f94ddd3bbe712475f3dc29637e6499e2571bc8a625a0f15b 14470084 open5gs_2.7.0.59.6069.202401172026.tar.xz
19
 Files:
20
- b8d34e8345cae44cfd70c2423c2499fa 14467112 open5gs_2.7.0.57.52be.202401162026.tar.xz
21
+ 842328d001ac2a84e350f13656f19a5e 14470084 open5gs_2.7.0.59.6069.202401172026.tar.xz
22
open5gs_2.7.0.57.52be.202401162026.tar.xz/.tarball-version -> open5gs_2.7.0.59.6069.202401172026.tar.xz/.tarball-version Changed
4
 
1
@@ -1 +1 @@
2
-2.7.0.57-52be.202401162026
3
+2.7.0.59-6069.202401172026
4
open5gs_2.7.0.57.52be.202401162026.tar.xz/debian/changelog -> open5gs_2.7.0.59.6069.202401172026.tar.xz/debian/changelog Changed
12
 
1
@@ -1,8 +1,8 @@
2
-open5gs (2.7.0.57.52be.202401162026) unstable; urgency=medium
3
+open5gs (2.7.0.59.6069.202401172026) unstable; urgency=medium
4
 
5
   * Automatically generated changelog entry for building the Osmocom nightly feed
6
 
7
- -- Osmocom OBS scripts <info@osmocom.org>  Tue, 16 Jan 2024 20:27:30 +0000
8
+ -- Osmocom OBS scripts <info@osmocom.org>  Wed, 17 Jan 2024 20:27:39 +0000
9
 
10
 open5gs (2.7.0) unstable; urgency=medium
11
 
12
open5gs_2.7.0.57.52be.202401162026.tar.xz/lib/core/ogs-list.h -> open5gs_2.7.0.59.6069.202401172026.tar.xz/lib/core/ogs-list.h Changed
21
 
1
@@ -206,6 +206,19 @@
2
     return i;
3
 }
4
 
5
+static ogs_inline bool ogs_list_exists(const ogs_list_t *list, void *lnode)
6
+{
7
+    ogs_list_t *node = (ogs_list_t *)lnode;
8
+    void *iter = NULL;
9
+
10
+    ogs_list_for_each(list, iter) {
11
+        if (node == (ogs_list_t *)iter)
12
+            return true;
13
+    }
14
+
15
+    return false;
16
+}
17
+
18
 #ifdef __cplusplus
19
 }
20
 #endif
21
open5gs_2.7.0.57.52be.202401162026.tar.xz/lib/gtp/xact.h -> open5gs_2.7.0.59.6069.202401172026.tar.xz/lib/gtp/xact.h Changed
9
 
1
@@ -121,6 +121,7 @@
2
 #define OGS_GTP_CREATE_IN_ATTACH_REQUEST 1
3
 #define OGS_GTP_CREATE_IN_UPLINK_NAS_TRANSPORT 2
4
 #define OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST 3
5
+#define OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE 4 /* 3GPP TS 33.401 9.1.2 */
6
     int             create_action;
7
 
8
 #define OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST 1
9
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/emm-build.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/emm-build.c Changed
20
 
1
@@ -398,6 +398,18 @@
2
     imeisv_request->type = OGS_NAS_IMEISV_TYPE;
3
     imeisv_request->value = OGS_NAS_IMEISV_REQUESTED;
4
 
5
+    if (mme_ue->nonceue) {
6
+        security_mode_command->presencemask |=
7
+            OGS_NAS_EPS_SECURITY_MODE_COMMAND_REPLAYED_NONCEUE_PRESENT;
8
+            security_mode_command->replayed_nonceue = mme_ue->nonceue;
9
+    }
10
+
11
+    if (mme_ue->noncemme) {
12
+        security_mode_command->presencemask |=
13
+            OGS_NAS_EPS_SECURITY_MODE_COMMAND_NONCEMME_PRESENT;
14
+            security_mode_command->noncemme = mme_ue->noncemme;
15
+    }
16
+
17
     /*
18
      * TS24.301
19
      * 5.4.3.2 NAS security mode control initiation by the network
20
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/emm-handler.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/emm-handler.c Changed
69
 
1
@@ -549,6 +549,36 @@
2
     return OGS_OK;
3
 }
4
 
5
+bool emm_tau_request_ue_comes_from_gb_or_iu(const ogs_nas_eps_tracking_area_update_request_t *tau_request)
6
+{
7
+    /* "When the tracking area updating procedure is initiated in EMM-IDLE mode
8
+     * to perform an inter-system change from A/Gb mode or Iu mode to S1 mode
9
+     * and the TIN is set to "P-TMSI", the UE shall include the GPRS ciphering
10
+     * key sequence number applicable for A/Gb mode or Iu mode and a nonce UE in
11
+     * the TRACKING AREA UPDATE REQUEST message."
12
+     */
13
+    if (!(tau_request->presencemask &
14
+            OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_NONCEUE_PRESENT))
15
+            return false;
16
+
17
+    if (tau_request->presencemask &
18
+        OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_OLD_GUTI_TYPE_PRESENT) {
19
+            /* 0 = Native, 1 = Mapped */
20
+            return tau_request->old_guti_type.guti_type;
21
+    } else {
22
+        /* TS 23.003 2.8.2.2.2:
23
+            * "The most significant bit of the <LAC> shall be set to zero;
24
+            * and the most significant bit of <MME group id> shall be set to
25
+            * one. Based on this definition, the most significant bit of the
26
+            * <MME group id> can be used to distinguish the node type, i.e.
27
+            * whether it is an MME or SGSN */
28
+        const ogs_nas_eps_mobile_identity_t *eps_mobile_identity = &tau_request->old_guti;
29
+        if (eps_mobile_identity->imsi.type != OGS_NAS_EPS_MOBILE_IDENTITY_GUTI)
30
+            return false;
31
+        return !(eps_mobile_identity->guti.mme_gid & 0x8000);
32
+    }
33
+}
34
+
35
 int emm_handle_tau_request(mme_ue_t *mme_ue,
36
     ogs_nas_eps_tracking_area_update_request_t *tau_request, ogs_pkbuf_t *pkbuf)
37
 {
38
@@ -660,6 +690,19 @@
39
                 sizeof(tau_request->ms_network_capability));
40
     }
41
 
42
+    if (tau_request->presencemask &
43
+            OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_NONCEUE_PRESENT) {
44
+        mme_ue->gprs_ciphering_key_sequence_number = tau_request->gprs_ciphering_key_sequence_number.key_sequence;
45
+    } else {
46
+        /* Mark as unavailable, Table 10.5.2/3GPP TS 24.008 */
47
+        mme_ue->gprs_ciphering_key_sequence_number = OGS_NAS_CIPHERING_KEY_SEQUENCE_NUMBER_NO_KEY_FROM_MS;
48
+    }
49
+
50
+    if (tau_request->presencemask &
51
+            OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_NONCEUE_PRESENT) {
52
+        mme_ue->nonceue = tau_request->nonceue;
53
+    }
54
+
55
     /* TODO:
56
      *   1) Consider if MME is changed or not.
57
      *   2) Consider if SGW is changed or not.
58
@@ -679,6 +722,10 @@
59
                 nas_guti.m_tmsi,
60
                 MME_UE_HAVE_IMSI(mme_ue)
61
                     ? mme_ue->imsi_bcd : "Unknown");
62
+
63
+        memcpy(&mme_ue->next.guti,
64
+           &nas_guti, sizeof(ogs_nas_eps_guti_t));
65
+
66
         break;
67
     default:
68
         ogs_error("Not implemented%d", eps_mobile_identity->imsi.type);
69
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/emm-handler.h -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/emm-handler.h Changed
11
 
1
@@ -50,6 +50,9 @@
2
 int emm_handle_security_mode_complete(mme_ue_t *mme_ue,
3
     ogs_nas_eps_security_mode_complete_t *security_mode_complete);
4
 
5
+bool emm_tau_request_ue_comes_from_gb_or_iu(
6
+    const ogs_nas_eps_tracking_area_update_request_t *tau_request);
7
+
8
 #ifdef __cplusplus
9
 }
10
 #endif
11
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/emm-sm.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/emm-sm.c Changed
46
 
1
@@ -20,6 +20,7 @@
2
 #include "mme-event.h"
3
 #include "mme-timer.h"
4
 #include "s1ap-handler.h"
5
+#include "mme-gn-handler.h"
6
 #include "mme-fd-path.h"
7
 #include "emm-handler.h"
8
 #include "emm-build.h"
9
@@ -286,7 +287,9 @@
10
 
11
     mme_ue_t *mme_ue = NULL;
12
     enb_ue_t *enb_ue = NULL;
13
+    mme_sgsn_t *sgsn = NULL;
14
     ogs_nas_eps_message_t *message = NULL;
15
+    ogs_nas_rai_t rai;
16
     ogs_nas_security_header_type_t h;
17
 
18
     ogs_assert(e);
19
@@ -489,6 +492,26 @@
20
                 break;
21
             }
22
 
23
+            if (emm_tau_request_ue_comes_from_gb_or_iu(&message->emm.tracking_area_update_request)) {
24
+                ogs_info("TAU request : UE comes from SGSN, attempt retrieving context");
25
+                guti_to_rai_ptmsi(&mme_ue->next.guti, &rai, NULL, NULL);
26
+                sgsn = mme_sgsn_find_by_routing_address(&rai, 0xffff);
27
+                if (!sgsn) {
28
+                    ogs_plmn_id_t plmn_id;
29
+                    ogs_nas_to_plmn_id(&plmn_id, &rai.lai.nas_plmn_id);
30
+                    ogs_warn("No SGSN route matching RAIMCC:%u MNC:%u LAC:%u RAC:%u",
31
+                             ogs_plmn_id_mcc(&plmn_id), ogs_plmn_id_mnc(&plmn_id),
32
+                             rai.lai.lac, rai.rac);
33
+                    r = nas_eps_send_tau_reject(mme_ue,
34
+                    OGS_NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
35
+                    OGS_FSM_TRAN(s, &emm_state_exception);
36
+                    break;
37
+                }
38
+                mme_gtp1_send_sgsn_context_request(sgsn, mme_ue);
39
+                /* FIXME: use a specific FSM state here to state we are waiting for resolution from Gn? */
40
+                break;
41
+            }
42
+
43
             if (!MME_UE_HAVE_IMSI(mme_ue)) {
44
                 ogs_info("TAU request : Unknown UE");
45
                 r = nas_eps_send_tau_reject(mme_ue,
46
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-context.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-context.c Changed
13
 
1
@@ -3184,6 +3184,11 @@
2
 
3
     /* Clear Next GUTI */
4
     mme_ue->next.m_tmsi = NULL;
5
+
6
+    ogs_debug("Confirm GUTIG:%d,C:%d,M_TMSI:0x%x",
7
+              mme_ue->current.guti.mme_gid,
8
+              mme_ue->current.guti.mme_code,
9
+              mme_ue->current.guti.m_tmsi);
10
 }
11
 
12
 static bool compare_ue_info(mme_sgw_t *node, enb_ue_t *enb_ue)
13
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-context.h -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-context.h Changed
10
 
1
@@ -489,6 +489,8 @@
2
     } ul_count;
3
     uint8_t         kenbOGS_SHA256_DIGEST_SIZE;
4
     uint8_t         hash_mmeOGS_HASH_MME_LEN;
5
+    uint32_t        nonceue, noncemme;
6
+    uint8_t gprs_ciphering_key_sequence_number;
7
 
8
     struct {
9
     ED2(uint8_t nhcc_spare:5;,
10
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-gn-build.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-gn-build.c Changed
201
 
1
@@ -20,11 +20,11 @@
2
 #include "mme-context.h"
3
 
4
 #include "mme-gn-build.h"
5
+#include "mme-gn-handler.h"
6
 
7
 static int sess_fill_mm_context_decoded(mme_sess_t *sess, ogs_gtp1_mm_context_decoded_t *mmctx_dec)
8
 {
9
     mme_ue_t *mme_ue = sess->mme_ue;
10
-    mme_bearer_t *bearer = NULL;
11
     *mmctx_dec = (ogs_gtp1_mm_context_decoded_t) {
12
         .gupii = 1, /* Integrity Protection not required */
13
         .ugipai = 1, /* Ignore "Used GPRS integrity protection algorithm" field" */
14
@@ -40,7 +40,6 @@
15
         .nrsrna = 0,
16
     };
17
 
18
-    //TODO: derive cK Ki from mme_ue->kasme
19
     ogs_kdf_ck_ik_idle_mobility(mme_ue->ul_count.i32, mme_ue->kasme, &mmctx_dec->ck0, &mmctx_dec->ik0);
20
 
21
     mmctx_dec->imeisv_len = sizeof(mme_ue->nas_mobile_identity_imeisv);
22
@@ -49,12 +48,6 @@
23
     mmctx_dec->ms_network_capability_len = mme_ue->ms_network_capability.length;
24
     memcpy(&mmctx_dec->ms_network_capability0, ((uint8_t*)&mme_ue->ms_network_capability)+1, sizeof(mme_ue->ms_network_capability) - 1);
25
 
26
-    ogs_list_for_each(&sess->bearer_list, bearer) {
27
-
28
-        /* FIXME: only 1 PDP Context supported in the message so far. */
29
-        break;
30
-    }
31
-
32
     return OGS_OK;
33
 }
34
 
35
@@ -177,6 +170,103 @@
36
     return OGS_OK;
37
 }
38
 
39
+/* 3GPP TS 29.060 7.5.3 SGSN Context Request */
40
+ogs_pkbuf_t *mme_gn_build_sgsn_context_request(
41
+                mme_ue_t *mme_ue)
42
+{
43
+    ogs_gtp1_message_t gtp1_message;
44
+    ogs_gtp1_sgsn_context_request_t *req = NULL;
45
+    ogs_nas_rai_t rai;
46
+    mme_p_tmsi_t ptmsi;
47
+    uint32_t ptmsi_sig;
48
+    ogs_gtp1_gsn_addr_t mme_gnc_gsnaddr, mme_gnc_alt_gsnaddr;
49
+    int gsn_len;
50
+    int rv;
51
+
52
+    ogs_debug("Gn build SGSN Context Request");
53
+
54
+    ogs_assert(mme_ue);
55
+
56
+    req = &gtp1_message.sgsn_context_request;
57
+    memset(&gtp1_message, 0, sizeof(ogs_gtp1_message_t));
58
+
59
+    guti_to_rai_ptmsi(&mme_ue->next.guti, &rai, &ptmsi, &ptmsi_sig);
60
+
61
+    req->imsi.presence = 0;
62
+
63
+    req->routeing_area_identity.presence = 1;
64
+    req->routeing_area_identity.data = &rai;
65
+    req->routeing_area_identity.len = sizeof(ogs_nas_rai_t);
66
+
67
+    req->temporary_logical_link_identifier.presence = 0;
68
+
69
+    req->packet_tmsi.presence = 1;
70
+    req->packet_tmsi.u32 = be32toh(ptmsi);
71
+
72
+    req->p_tmsi_signature.presence = 1;
73
+    req->p_tmsi_signature.u24 = ptmsi_sig;
74
+
75
+    req->ms_validated.presence = 0;
76
+
77
+    req->tunnel_endpoint_identifier_control_plane.presence = 1;
78
+    req->tunnel_endpoint_identifier_control_plane.u32 = mme_ue->gn.mme_gn_teid;
79
+
80
+    /* SGSN Address for Control Plane */
81
+    if (ogs_gtp_self()->gtpc_addr && ogs_gtp_self()->gtpc_addr6) {
82
+        rv = ogs_gtp1_sockaddr_to_gsn_addr(NULL, ogs_gtp_self()->gtpc_addr6,
83
+                &mme_gnc_gsnaddr, &gsn_len);
84
+        if (rv != OGS_OK) {
85
+            ogs_error("ogs_gtp1_sockaddr_to_gsn_addr() failed");
86
+            return NULL;
87
+        }
88
+        req->sgsn_address_for_control_plane.presence = 1;
89
+        req->sgsn_address_for_control_plane.data = &mme_gnc_gsnaddr;
90
+        req->sgsn_address_for_control_plane.len = gsn_len;
91
+
92
+        rv = ogs_gtp1_sockaddr_to_gsn_addr(ogs_gtp_self()->gtpc_addr, NULL,
93
+                &mme_gnc_alt_gsnaddr, &gsn_len);
94
+        if (rv != OGS_OK) {
95
+            ogs_error("ogs_gtp1_sockaddr_to_gsn_addr() failed");
96
+            return NULL;
97
+        }
98
+        req->sgsn_address_for_control_plane.presence = 1;
99
+        req->sgsn_address_for_control_plane.data = &mme_gnc_alt_gsnaddr;
100
+        req->sgsn_address_for_control_plane.len = gsn_len;
101
+    } else if (ogs_gtp_self()->gtpc_addr6) {
102
+        rv = ogs_gtp1_sockaddr_to_gsn_addr(NULL, ogs_gtp_self()->gtpc_addr6,
103
+                &mme_gnc_gsnaddr, &gsn_len);
104
+        if (rv != OGS_OK) {
105
+            ogs_error("ogs_gtp1_sockaddr_to_gsn_addr() failed");
106
+            return NULL;
107
+        }
108
+        req->sgsn_address_for_control_plane.presence = 1;
109
+        req->sgsn_address_for_control_plane.data = &mme_gnc_gsnaddr;
110
+        req->sgsn_address_for_control_plane.len = gsn_len;
111
+        req->alternative_sgsn_address_for_control_plane.presence = 0;
112
+    } else {
113
+        rv = ogs_gtp1_sockaddr_to_gsn_addr(ogs_gtp_self()->gtpc_addr, NULL,
114
+                &mme_gnc_gsnaddr, &gsn_len);
115
+        if (rv != OGS_OK) {
116
+            ogs_error("ogs_gtp1_sockaddr_to_gsn_addr() failed");
117
+            return NULL;
118
+        }
119
+        req->sgsn_address_for_control_plane.presence = 1;
120
+        req->sgsn_address_for_control_plane.data = &mme_gnc_gsnaddr;
121
+        req->sgsn_address_for_control_plane.len = gsn_len;
122
+        req->alternative_sgsn_address_for_control_plane.presence = 0;
123
+    }
124
+
125
+    req->sgsn_number.presence = 0;
126
+
127
+    req->rat_type.presence = 1;
128
+    req->rat_type.u8 = OGS_GTP1_RAT_TYPE_EUTRAN;
129
+
130
+    req->hop_counter.presence = 0;
131
+
132
+    gtp1_message.h.type = OGS_GTP1_SGSN_CONTEXT_REQUEST_TYPE;
133
+    return ogs_gtp1_build_msg(&gtp1_message);
134
+}
135
+
136
 /* 3GPP TS 29.060 7.5.4 SGSN Context Response */
137
 ogs_pkbuf_t *mme_gn_build_sgsn_context_response(
138
                 mme_ue_t *mme_ue, uint8_t cause)
139
@@ -276,6 +366,67 @@
140
 
141
 
142
 build_ret:
143
+    return ogs_gtp1_build_msg(&gtp1_message);
144
+}
145
+
146
+/* 3GPP TS 29.060 7.5.5 SGSN Context Acknowledge */
147
+ogs_pkbuf_t *mme_gn_build_sgsn_context_ack(
148
+                mme_ue_t *mme_ue, uint8_t cause)
149
+{
150
+    ogs_gtp1_message_t gtp1_message;
151
+    ogs_gtp1_sgsn_context_acknowledge_t *ack = NULL;
152
+    mme_sess_t *sess = NULL;
153
+    ogs_gtp1_gsn_addr_t reserved_gnc_gsnaddr;
154
+    ogs_gtp1_teidII_t teidII;
155
+
156
+    ogs_debug("Gn build SGSN Context Acknowledge");
157
+
158
+    ack = &gtp1_message.sgsn_context_acknowledge;
159
+    memset(&gtp1_message, 0, sizeof(ogs_gtp1_message_t));
160
+    gtp1_message.h.type = OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE;
161
+
162
+    /* 3GPP TS 29.060 7.7.1 Cause, Mandatory */
163
+    ack->cause.presence = 1;
164
+    ack->cause.u8 = cause;
165
+
166
+    if (cause != OGS_GTP1_CAUSE_REQUEST_ACCEPTED)
167
+        goto build_ret;
168
+
169
+    ogs_list_for_each(&mme_ue->sess_list, sess) {
170
+        mme_bearer_t *bearer = NULL;
171
+        if (!MME_HAVE_SGW_S1U_PATH(sess))
172
+            continue;
173
+        ogs_list_for_each(&sess->bearer_list, bearer) {
174
+            /* MME, acting as a new SGSN, shall send the following values in the SGSN Context
175
+             * Acknowledge message in order to discard the packets received from the old SGSN
176
+             * (because the MME and the S4-SGSN do not have user plane):
177
+             * - any reserved TEID (e.g. all 0's, or all 1's) for Tunnel Endpoint Identifier
178
+             *   Data II value;
179
+             * - any reserved (implementation dependent) IP address for SGSN Address for user
180
+                 traffic value.
181
+             */
182
+            /* 3GPP TS 29.060 7.7.15 Tunnel Endpoint Identifier Data II, Conditional */
183
+            teidII.nsapi = bearer->ebi;
184
+            teidII.teid = 0xffffffff;
185
+            ack->tunnel_endpoint_identifier_data_ii.presence = 1;
186
+            ack->tunnel_endpoint_identifier_data_ii.data = &teidII;
187
+            ack->tunnel_endpoint_identifier_data_ii.len = sizeof(teidII);
188
+
189
+            /* Use IPv4 0.0.0.0 as reserved address: */
190
+            reserved_gnc_gsnaddr.addr = 0;
191
+            ack->sgsn_address_for_user_traffic.presence = 1;
192
+            ack->sgsn_address_for_user_traffic.data = &reserved_gnc_gsnaddr;
193
+            ack->sgsn_address_for_user_traffic.len = OGS_GTP_GSN_ADDRESS_IPV4_LEN;
194
+
195
+            /* FIXME: only 1 PDP Context supported in the message so far. */
196
+            break;
197
+        }
198
+        /* FIXME: right now we only support encoding 1 context in the message. */
199
+        break;
200
+    }
201
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-gn-build.h -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-gn-build.h Changed
17
 
1
@@ -30,9 +30,15 @@
2
 }
3
 #endif
4
 
5
+ogs_pkbuf_t *mme_gn_build_sgsn_context_request(
6
+                mme_ue_t *mme_ue);
7
+
8
 ogs_pkbuf_t *mme_gn_build_sgsn_context_response(
9
                 mme_ue_t *mme_ue, uint8_t cause);
10
 
11
+ogs_pkbuf_t *mme_gn_build_sgsn_context_ack(
12
+                mme_ue_t *mme_ue, uint8_t cause);
13
+
14
 ogs_pkbuf_t *mme_gn_build_ran_information_relay(
15
                 uint8_t type, const uint8_t *buf, size_t len,
16
                 const ogs_nas_rai_t *rai, uint16_t cell_id);
17
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-gn-handler.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-gn-handler.c Changed
201
 
1
@@ -30,6 +30,7 @@
2
 #include "mme-gn-handler.h"
3
 
4
 #include "s1ap-path.h"
5
+#include "nas-path.h"
6
 
7
 void mme_gn_handle_echo_request(
8
         ogs_gtp_xact_t *xact, ogs_gtp1_echo_request_t *req)
9
@@ -68,12 +69,26 @@
10
     return OGS_OK;
11
 }
12
 
13
-/* 3GPP TS 23.003 2.8.2.2 Mapping from RAI and P-TMSI to GUT */
14
+/* 3GPP TS 23.003 2.8.2.1 Mapping from GUTI to RAI, P-TMSI and P-TMSI signature */
15
+void guti_to_rai_ptmsi(const ogs_nas_eps_guti_t *nas_guti, ogs_nas_rai_t *rai, mme_p_tmsi_t *ptmsi, uint32_t *ptmsi_sig)
16
+{
17
+    rai->lai.nas_plmn_id = nas_guti->nas_plmn_id;
18
+    rai->lai.lac = nas_guti->mme_gid;
19
+    rai->rac = nas_guti->mme_code;
20
+    if (ptmsi)
21
+        *ptmsi = 0xC0000000 |
22
+                (nas_guti->m_tmsi & 0x3f000000) |
23
+                (nas_guti->mme_code & 0x0ff) << 16 |
24
+                (nas_guti->m_tmsi & 0x0000ffff);
25
+    if (ptmsi_sig)
26
+        *ptmsi_sig = (nas_guti->m_tmsi & 0x00ff0000);
27
+}
28
+
29
+/* 3GPP TS 23.003 2.8.2.2 Mapping from RAI and P-TMSI to GUTI */
30
 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)
31
 {
32
-    uint16_t lac = be16toh(rai->lai.lac);;
33
-    nas_guti->nas_plmn_id =rai->lai.nas_plmn_id;
34
-    nas_guti->mme_gid = lac;
35
+    nas_guti->nas_plmn_id = rai->lai.nas_plmn_id;
36
+    nas_guti->mme_gid = rai->lai.lac;
37
     nas_guti->mme_code = rai->rac;
38
     nas_guti->m_tmsi = 0xC0000000 | (ptmsi & 0x3f000000) | (ptmsi_sig & 0x00ff0000) | (ptmsi & 0x0000ffff);
39
 }
40
@@ -83,7 +98,8 @@
41
         ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_request_t *req)
42
 {
43
     ogs_nas_eps_guti_t nas_guti;
44
-    ogs_nas_rai_t *rai;
45
+    ogs_plmn_id_t plmn_id;
46
+    ogs_nas_rai_t rai;
47
     mme_ue_t *mme_ue = NULL;
48
     int rv;
49
 
50
@@ -94,9 +110,10 @@
51
         mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact);
52
         return;
53
     }
54
-    if (req->routeing_area_identity.len != sizeof(*rai)) {
55
+
56
+    if (req->routeing_area_identity.len != sizeof(rai)) {
57
         ogs_warn("Gn Rx SGSN Context Request RAI wrong size %u vs exp %zu!",
58
-                 req->routeing_area_identity.len, sizeof(*rai));
59
+                 req->routeing_area_identity.len, sizeof(rai));
60
         mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT, xact);
61
         return;
62
     }
63
@@ -126,17 +143,35 @@
64
         return;
65
     }
66
 
67
-    rai = req->routeing_area_identity.data;
68
+    memcpy(&rai, req->routeing_area_identity.data, sizeof(rai));
69
+    rai.lai.lac = be16toh(rai.lai.lac);
70
+    ogs_nas_to_plmn_id(&plmn_id, &rai.lai.nas_plmn_id);
71
+    ogs_debug("    RAIMCC:%u MNC:%u LAC:%u RAC:%u",
72
+             ogs_plmn_id_mcc(&plmn_id), ogs_plmn_id_mnc(&plmn_id),
73
+             rai.lai.lac, rai.rac);
74
 
75
     if (req->imsi.presence) {
76
+        char imsi_bcdOGS_MAX_IMSI_BCD_LEN+1;
77
+        ogs_buffer_to_bcd(req->imsi.data, req->imsi.len, imsi_bcd);
78
+        ogs_debug("    IMSI%s", imsi_bcd);
79
         mme_ue = mme_ue_find_by_imsi(req->imsi.data, req->imsi.len);
80
+        if (!mme_ue)
81
+            ogs_warn("Gn Rx SGSN Context Request: Unknown UE with IMSI%s", imsi_bcd);
82
     } else if (req->packet_tmsi.presence) { /* P-TMSI */
83
         if (!req->p_tmsi_signature.presence) {
84
             ogs_warn("Gn Rx SGSN Context Request with 'P-TMSI' but no P-TMSI Signature! Assuming value 0.");
85
             req->p_tmsi_signature.u24 = 0;
86
         }
87
-        rai_ptmsi_to_guti(rai, req->packet_tmsi.u32, req->p_tmsi_signature.u24, &nas_guti);
88
+        rai_ptmsi_to_guti(&rai, req->packet_tmsi.u32, req->p_tmsi_signature.u24, &nas_guti);
89
+        ogs_debug("    PTMSI0x%08x PTMSI_SIG0x%06x -> GUTIG:%d,C:%d,M_TMSI:0x%x",
90
+                  req->packet_tmsi.u32, req->p_tmsi_signature.u24,
91
+                  nas_guti.mme_gid, nas_guti.mme_code, nas_guti.m_tmsi);
92
         mme_ue = mme_ue_find_by_guti(&nas_guti);
93
+        if (!mme_ue)
94
+            ogs_warn("Gn Rx SGSN Context Request: Unknown UE with RAIMCC:%u MNC:%u LAC:%u RAC:%u PTMSI0x%08x PTMSI_SIG0x%06x -> GUTIG:%d,C:%d,M_TMSI:0x%x",
95
+                     ogs_plmn_id_mcc(&plmn_id), ogs_plmn_id_mnc(&plmn_id), rai.lai.lac, rai.rac,
96
+                     req->packet_tmsi.u32, req->p_tmsi_signature.u24,
97
+                     nas_guti.mme_gid, nas_guti.mme_code, nas_guti.m_tmsi);
98
     } else if (req->temporary_logical_link_identifier.presence) {
99
         if (!req->p_tmsi_signature.presence) {
100
             ogs_warn("Gn Rx SGSN Context Request with 'TLLI' but no P-TMSI Signature! Assuming value 0.");
101
@@ -145,8 +180,16 @@
102
         /* 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."
103
          * A foregin TLLI is "tlli = (p_tmsi & 0x3fffffff) | 0x80000000", and since we only use 0x3fffffff
104
          * bits of P-TMSI to derive the GUTI, it's totally fine passing the TLLI as P-TMSI. */
105
-        rai_ptmsi_to_guti(rai, req->temporary_logical_link_identifier.u32, req->p_tmsi_signature.u24, &nas_guti);
106
+        rai_ptmsi_to_guti(&rai, req->temporary_logical_link_identifier.u32, req->p_tmsi_signature.u24, &nas_guti);
107
+        ogs_debug("    TLLI0x%08x PTMSI_SIG0x%06x -> GUTIG:%d,C:%d,M_TMSI:0x%x",
108
+                  req->temporary_logical_link_identifier.u32, req->p_tmsi_signature.u24,
109
+                  nas_guti.mme_gid, nas_guti.mme_code, nas_guti.m_tmsi);
110
         mme_ue = mme_ue_find_by_guti(&nas_guti);
111
+        if (!mme_ue)
112
+            ogs_warn("Gn Rx SGSN Context Request: Unknown UE with RAIMCC:%u MNC:%u LAC:%u RAC:%u TLLI0x%08x PTMSI_SIG0x%06x -> GUTIG:%d,C:%d,M_TMSI:0x%x",
113
+                     ogs_plmn_id_mcc(&plmn_id), ogs_plmn_id_mnc(&plmn_id), rai.lai.lac, rai.rac,
114
+                     req->temporary_logical_link_identifier.u32, req->p_tmsi_signature.u24,
115
+                     nas_guti.mme_gid, nas_guti.mme_code, nas_guti.m_tmsi);
116
     }
117
 
118
     if (!mme_ue) {
119
@@ -177,6 +220,223 @@
120
     mme_gtp1_send_sgsn_context_response(mme_ue, OGS_GTP1_CAUSE_REQUEST_ACCEPTED, xact);
121
 }
122
 
123
+static mme_sess_t *mme_ue_session_from_gtp1_pdp_ctx(mme_ue_t *mme_ue, const ogs_gtp1_pdp_context_decoded_t *gtp1_pdp_ctx)
124
+{
125
+    mme_sess_t *sess = NULL;
126
+    mme_bearer_t *bearer = NULL;
127
+    const ogs_gtp1_qos_profile_decoded_t *qos_pdec = &gtp1_pdp_ctx->qos_sub;
128
+    uint8_t pti = gtp1_pdp_ctx->trans_id;
129
+    uint8_t qci = 0;
130
+    ogs_session_t *ogs_sess;
131
+
132
+    ogs_sess = mme_session_find_by_apn(mme_ue, gtp1_pdp_ctx->apn);
133
+    if (!ogs_sess) {
134
+        ogs_assert(mme_ue->num_of_session < OGS_MAX_NUM_OF_SESS);
135
+        ogs_sess = &mme_ue->sessionmme_ue->num_of_session;
136
+        mme_ue->num_of_session++;
137
+        ogs_sess->name = ogs_strdup(gtp1_pdp_ctx->apn);
138
+    }
139
+    ogs_sess->smf_ip = gtp1_pdp_ctx->ggsn_address_c;
140
+    ogs_sess->context_identifier = gtp1_pdp_ctx->pdp_ctx_id;
141
+    ogs_sess->session_type = gtp1_pdp_ctx->pdp_type_num0;
142
+    ogs_sess->ue_ip = gtp1_pdp_ctx->pdp_address0;
143
+    /* TODO: sess->paa with gtp1_pdp_ctx->pdp_address0,
144
+     using/implementing ogs_gtp2_ip_to_paa ? */
145
+    ogs_ip_to_paa(&ogs_sess->ue_ip, &ogs_sess->paa);
146
+
147
+    /* 3GPP TS 23.060 section 9.2.1A: "The QoS profiles of the PDP context and EPS bearer are mapped as specified in TS 23.401"
148
+     * 3GPP TS 23.401 Annex E: "Mapping between EPS and Release 99 QoS parameters"
149
+     */
150
+    ogs_gtp1_qos_profile_to_qci(qos_pdec, &qci);
151
+    ogs_sess->qos.index = qci;
152
+    ogs_sess->qos.arp.priority_level = qos_pdec->qos_profile.arp; /* 3GPP TS 23.401 Annex E Table E.2 */
153
+    ogs_sess->qos.arp.pre_emption_capability = 0; /* ignored as per 3GPP TS 23.401 Annex E */
154
+    ogs_sess->qos.arp.pre_emption_vulnerability = 0; /* ignored as per 3GPP TS 23.401 Annex E */
155
+    if (qos_pdec->data_octet6_to_13_present) {
156
+        ogs_sess->ambr.downlink = qos_pdec->dec_mbr_kbps_dl * 1000;
157
+        ogs_sess->ambr.uplink = qos_pdec->dec_mbr_kbps_ul * 1000;
158
+    }
159
+
160
+    sess = mme_sess_find_by_pti(mme_ue, pti);
161
+    if (!sess) {
162
+        sess = mme_sess_add(mme_ue, pti);
163
+        ogs_assert(sess);
164
+    }
165
+
166
+    sess->session = ogs_sess;
167
+    sess->pgw_s5c_teid = gtp1_pdp_ctx->ul_teic;
168
+    sess->pgw_s5c_ip = gtp1_pdp_ctx->ggsn_address_c;
169
+    switch (ogs_sess->session_type) {
170
+    case OGS_PDU_SESSION_TYPE_IPV4:
171
+        sess->request_type.type = OGS_NAS_EPS_PDN_TYPE_IPV4;
172
+        break;
173
+    case OGS_PDU_SESSION_TYPE_IPV6:
174
+        sess->request_type.type = OGS_NAS_EPS_PDN_TYPE_IPV6;
175
+        break;
176
+    case OGS_PDU_SESSION_TYPE_IPV4V6:
177
+        sess->request_type.type = OGS_NAS_EPS_PDN_TYPE_IPV4V6;
178
+        break;
179
+    }
180
+    sess->request_type.value = OGS_NAS_EPS_REQUEST_TYPE_INITIAL;
181
+
182
+    bearer = mme_bearer_find_by_sess_ebi(sess, gtp1_pdp_ctx->nsapi);
183
+    if (!bearer) {
184
+        bearer = mme_default_bearer_in_sess(sess);
185
+        if (!bearer) {
186
+            bearer = mme_bearer_add(sess);
187
+            ogs_assert(bearer);
188
+        }
189
+    }
190
+    bearer->pgw_s5u_teid = gtp1_pdp_ctx->ul_teid;
191
+    bearer->pgw_s5u_ip = gtp1_pdp_ctx->ggsn_address_u;
192
+    /* Send invalid Remote Address and TEID since it makes no sense that SGW
193
+     * forwards GTPUv2 traffic to SGSN: */
194
+    bearer->enb_s1u_ip.ipv4 = 1;
195
+    bearer->enb_s1u_ip.addr = 0;
196
+    bearer->enb_s1u_teid = 0xffffffff;
197
+
198
+    return sess;
199
+}
200
+
201
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-gn-handler.h -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-gn-handler.h Changed
20
 
1
@@ -35,12 +35,18 @@
2
 void mme_gn_handle_sgsn_context_request(
3
         ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_request_t *req);
4
 
5
+int mme_gn_handle_sgsn_context_response(
6
+        ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp1_sgsn_context_response_t *resp);
7
+
8
 void mme_gn_handle_sgsn_context_acknowledge(
9
         ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, 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
+void guti_to_rai_ptmsi(const ogs_nas_eps_guti_t *nas_guti, ogs_nas_rai_t *rai,
15
+        mme_p_tmsi_t *ptmsi, uint32_t *ptmsi_sig);
16
+
17
 #ifdef __cplusplus
18
 }
19
 #endif
20
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-gtp-path.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-gtp-path.c Changed
86
 
1
@@ -758,6 +758,45 @@
2
     return rv;
3
 }
4
 
5
+/*************************
6
+ * GTPv1C (Gn interface):
7
+ *************************/
8
+
9
+int mme_gtp1_send_sgsn_context_request(
10
+        mme_sgsn_t *sgsn, mme_ue_t *mme_ue)
11
+{
12
+    int rv;
13
+    ogs_gtp1_header_t h;
14
+    ogs_pkbuf_t *pkbuf = NULL;
15
+    ogs_gtp_xact_t *xact = NULL;
16
+
17
+    ogs_assert(sgsn);
18
+
19
+    memset(&h, 0, sizeof(ogs_gtp1_header_t));
20
+    h.type = OGS_GTP1_SGSN_CONTEXT_REQUEST_TYPE;
21
+    h.teid = 0;
22
+
23
+    pkbuf = mme_gn_build_sgsn_context_request(mme_ue);
24
+    if (!pkbuf) {
25
+        ogs_error("mme_gn_build_ran_information_relay() failed");
26
+        return OGS_ERROR;
27
+    }
28
+
29
+    xact = ogs_gtp1_xact_local_create(&sgsn->gnode, &h, pkbuf, NULL, NULL);
30
+    if (!xact) {
31
+        ogs_error("ogs_gtp1_xact_local_create() failed");
32
+        return OGS_ERROR;
33
+    }
34
+    /* TS 29.060 8.2: "The SGSN Context Request message, where the Tunnel
35
+     * Endpoint Identifier shall be set to all zeroes." */
36
+    xact->local_teid = 0;
37
+
38
+    rv = ogs_gtp_xact_commit(xact);
39
+    ogs_expect(rv == OGS_OK);
40
+
41
+    return rv;
42
+}
43
+
44
 int mme_gtp1_send_sgsn_context_response(
45
         mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact)
46
 {
47
@@ -778,6 +817,38 @@
48
 
49
     rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf);
50
     if (rv != OGS_OK) {
51
+        ogs_error("ogs_gtp1_xact_update_tx() failed");
52
+        return OGS_ERROR;
53
+    }
54
+
55
+    rv = ogs_gtp_xact_commit(xact);
56
+    ogs_expect(rv == OGS_OK);
57
+
58
+    return rv;
59
+}
60
+
61
+int mme_gtp1_send_sgsn_context_ack(
62
+        mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact)
63
+{
64
+    int rv;
65
+    ogs_gtp1_header_t h;
66
+    ogs_pkbuf_t *pkbuf = NULL;
67
+
68
+    ogs_assert(mme_ue);
69
+
70
+    memset(&h, 0, sizeof(ogs_gtp1_header_t));
71
+    h.type = OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE;
72
+    h.teid = mme_ue->gn.sgsn_gn_teid;
73
+
74
+    pkbuf = mme_gn_build_sgsn_context_ack(mme_ue, cause);
75
+    if (!pkbuf) {
76
+        ogs_error("mme_gn_build_sgsn_context_response() failed");
77
+        return OGS_ERROR;
78
+    }
79
+    xact->local_teid = mme_ue->gn.mme_gn_teid;
80
+
81
+    rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf);
82
+    if (rv != OGS_OK) {
83
         ogs_error("ogs_gtp1_xact_update_tx() failed");
84
         return OGS_ERROR;
85
     }
86
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-gtp-path.h -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-gtp-path.h Changed
17
 
1
@@ -55,9 +55,15 @@
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_request(
6
+        mme_sgsn_t *sgsn, mme_ue_t *mme_ue);
7
+
8
 int mme_gtp1_send_sgsn_context_response(
9
         mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact);
10
 
11
+int mme_gtp1_send_sgsn_context_ack(
12
+        mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact);
13
+
14
 int mme_gtp1_send_ran_information_relay(
15
         mme_sgsn_t *sgsn, const uint8_t *buf, size_t len,
16
         const ogs_nas_rai_t *rai, uint16_t cell_id);
17
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-s11-build.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-s11-build.c Changed
22
 
1
@@ -219,7 +219,8 @@
2
     if (sess->request_type.value == OGS_NAS_EPS_REQUEST_TYPE_HANDOVER)
3
         indication.handover_indication = 1;
4
 
5
-    if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST)
6
+    if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST ||
7
+        create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE)
8
         indication.operation_indication = 1;
9
 
10
     session->paa.session_type = req->pdn_type.u8;
11
@@ -288,6 +289,10 @@
12
                 &enb_s1u_teidi;
13
             req->bearer_contexts_to_be_createdi.s1_u_enodeb_f_teid.len =
14
                 enb_s1u_leni;
15
+        }
16
+
17
+        if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST ||
18
+            create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
19
 
20
             /* Data Plane(DL) : PGW-S5U */
21
             memset(&pgw_s5u_teidi, 0, sizeof(ogs_gtp2_f_teid_t));
22
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-s11-handler.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-s11-handler.c Changed
35
 
1
@@ -232,6 +232,12 @@
2
                     OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
3
             ogs_expect(r == OGS_OK);
4
             ogs_assert(r != OGS_ERROR);
5
+        } else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
6
+            ogs_error("%s TAU reject Cause:%d",
7
+                    mme_ue->imsi_bcd, session_cause);
8
+            r = nas_eps_send_tau_reject(mme_ue, OGS_NAS_EMM_CAUSE_NETWORK_FAILURE);
9
+            ogs_expect(r == OGS_OK);
10
+            ogs_assert(r != OGS_ERROR);
11
         }
12
         mme_send_delete_session_or_mme_ue_context_release(mme_ue);
13
         return;
14
@@ -342,6 +348,10 @@
15
 
16
         ogs_debug("    ENB_S1U_TEID%d SGW_S1U_TEID%d PGW_S5U_TEID%d",
17
             bearer->enb_s1u_teid, bearer->sgw_s1u_teid, bearer->pgw_s5u_teid);
18
+
19
+        if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE &&
20
+            !OGS_FSM_CHECK(&bearer->sm, esm_state_active))
21
+            OGS_FSM_TRAN(&bearer->sm, esm_state_active);
22
     }
23
 
24
     /* Bearer Level QoS */
25
@@ -428,6 +438,9 @@
26
             ogs_assert(r != OGS_ERROR);
27
         }
28
 
29
+    } else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
30
+        /* 3GPP TS 23.401 D.3.6 step 13, 14: */
31
+        mme_s6a_send_ulr(mme_ue);
32
     } else if (create_action == OGS_GTP_CREATE_IN_UPLINK_NAS_TRANSPORT) {
33
         ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(session->paa.session_type));
34
         r = nas_eps_send_activate_default_bearer_context_request(
35
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/mme-sm.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/mme-sm.c Changed
19
 
1
@@ -674,6 +674,17 @@
2
         case OGS_GTP1_SGSN_CONTEXT_REQUEST_TYPE:
3
             mme_gn_handle_sgsn_context_request(xact, &gtp1_message.sgsn_context_request);
4
             break;
5
+        case OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE:
6
+            /* 3GPP TS 23.401 Figure D.3.6-1 step 5 */
7
+            rv = mme_gn_handle_sgsn_context_response(xact, mme_ue, &gtp1_message.sgsn_context_response);
8
+            if (rv == OGS_GTP1_CAUSE_ACCEPT) {
9
+                OGS_FSM_TRAN(&mme_ue->sm, &emm_state_initial_context_setup);
10
+            } else if (rv == OGS_GTP1_CAUSE_REQUEST_IMEI) {
11
+                OGS_FSM_TRAN(&mme_ue->sm, &emm_state_security_mode);
12
+            } else {
13
+                OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
14
+            }
15
+            break;
16
         case OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE:
17
             mme_gn_handle_sgsn_context_acknowledge(xact, mme_ue, &gtp1_message.sgsn_context_acknowledge);
18
             break;
19
open5gs_2.7.0.57.52be.202401162026.tar.xz/src/mme/s1ap-handler.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/src/mme/s1ap-handler.c Changed
49
 
1
@@ -1046,8 +1046,14 @@
2
                     ogs_debug("    ### ULI PRESENT ###");
3
                     uli_presence = 1;
4
                 }
5
-                ogs_list_add(&mme_ue->bearer_to_modify_list,
6
-                                &bearer->to_modify_node);
7
+                if (ogs_list_exists(
8
+                            &mme_ue->bearer_to_modify_list,
9
+                            &bearer->to_modify_node) == false)
10
+                    ogs_list_add(
11
+                            &mme_ue->bearer_to_modify_list,
12
+                            &bearer->to_modify_node);
13
+                else
14
+                    ogs_warn("Bearer %d Duplicated", (int)e_rab->e_RAB_ID);
15
             }
16
         }
17
 
18
@@ -2195,7 +2201,13 @@
19
             return;
20
         }
21
 
22
-        ogs_list_add(&mme_ue->bearer_to_modify_list, &bearer->to_modify_node);
23
+        if (ogs_list_exists(
24
+                    &mme_ue->bearer_to_modify_list,
25
+                    &bearer->to_modify_node) == false)
26
+            ogs_list_add(
27
+                    &mme_ue->bearer_to_modify_list, &bearer->to_modify_node);
28
+        else
29
+            ogs_warn("Bearer %d Duplicated", (int)e_rab->e_RAB_ID);
30
     }
31
 
32
     if (ogs_list_count(&mme_ue->bearer_to_modify_list)) {
33
@@ -2623,8 +2635,13 @@
34
             return;
35
         }
36
 
37
-        ogs_list_add(
38
-                &mme_ue->bearer_to_modify_list, &bearer->to_modify_node);
39
+        if (ogs_list_exists(
40
+                    &mme_ue->bearer_to_modify_list,
41
+                    &bearer->to_modify_node) == false)
42
+            ogs_list_add(
43
+                    &mme_ue->bearer_to_modify_list, &bearer->to_modify_node);
44
+        else
45
+            ogs_warn("Bearer %d Duplicated", (int)e_rab->e_RAB_ID);
46
     }
47
 
48
     relocation = sgw_ue_check_if_relocated(mme_ue);
49
open5gs_2.7.0.57.52be.202401162026.tar.xz/tests/handover/epc-x2-test.c -> open5gs_2.7.0.59.6069.202401172026.tar.xz/tests/handover/epc-x2-test.c Changed
201
 
1
@@ -370,11 +370,268 @@
2
     test_ue_remove(test_ue);
3
 }
4
 
5
+static void test2_func(abts_case *tc, void *data)
6
+{
7
+    int rv;
8
+    ogs_socknode_t *s1ap1, *s1ap2;
9
+    ogs_socknode_t *gtpu1, *gtpu2;
10
+    ogs_pkbuf_t *emmbuf;
11
+    ogs_pkbuf_t *esmbuf;
12
+    ogs_pkbuf_t *sendbuf;
13
+    ogs_pkbuf_t *recvbuf;
14
+    ogs_s1ap_message_t message;
15
+
16
+    ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
17
+    test_ue_t *test_ue = NULL;
18
+    test_sess_t *sess = NULL;
19
+    test_bearer_t *bearer = NULL;
20
+
21
+    bson_t *doc = NULL;
22
+
23
+    /* Setup Test UE & Session Context */
24
+    memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci));
25
+
26
+    mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI;
27
+    mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI;
28
+    mobile_identity_suci.routing_indicator1 = 0;
29
+    mobile_identity_suci.routing_indicator2 = 0xf;
30
+    mobile_identity_suci.routing_indicator3 = 0xf;
31
+    mobile_identity_suci.routing_indicator4 = 0xf;
32
+    mobile_identity_suci.protection_scheme_id = OGS_PROTECTION_SCHEME_NULL;
33
+    mobile_identity_suci.home_network_pki_value = 0;
34
+
35
+    test_ue = test_ue_add_by_suci(&mobile_identity_suci, "3746000006");
36
+    ogs_assert(test_ue);
37
+
38
+    test_ue->e_cgi.cell_id = 0x1234560;
39
+    test_ue->nas.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
40
+    test_ue->nas.value = OGS_NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTACH;
41
+
42
+    test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
43
+    test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca";
44
+
45
+    sess = test_sess_add_by_apn(test_ue, "internet", OGS_GTP2_RAT_TYPE_EUTRAN);
46
+    ogs_assert(sess);
47
+
48
+    /* Two eNB connects to MME */
49
+    s1ap1 = tests1ap_client(AF_INET);
50
+    ABTS_PTR_NOTNULL(tc, s1ap1);
51
+
52
+    s1ap2 = tests1ap_client(AF_INET);
53
+    ABTS_PTR_NOTNULL(tc, s1ap2);
54
+
55
+    /* Two eNB connects to SGW */
56
+    gtpu1 = test_gtpu_server(1, AF_INET);
57
+    ABTS_PTR_NOTNULL(tc, gtpu1);
58
+
59
+    gtpu2 = test_gtpu_server(2, AF_INET);
60
+    ABTS_PTR_NOTNULL(tc, gtpu2);
61
+
62
+    /* S1-Setup Reqeust/Response for Source eNB */
63
+    sendbuf = test_s1ap_build_s1_setup_request(
64
+            S1AP_ENB_ID_PR_macroENB_ID, 0x54f64);
65
+    ABTS_PTR_NOTNULL(tc, sendbuf);
66
+    rv = testenb_s1ap_send(s1ap1, sendbuf);
67
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
68
+
69
+    recvbuf = testenb_s1ap_read(s1ap1);
70
+    ABTS_PTR_NOTNULL(tc, recvbuf);
71
+    tests1ap_recv(NULL, recvbuf);
72
+
73
+    /* S1-Setup Reqeust/Response for Target eNB */
74
+    sendbuf = test_s1ap_build_s1_setup_request(
75
+            S1AP_ENB_ID_PR_macroENB_ID, 0x54f65);
76
+    ABTS_PTR_NOTNULL(tc, sendbuf);
77
+    rv = testenb_s1ap_send(s1ap2, sendbuf);
78
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
79
+
80
+    recvbuf = testenb_s1ap_read(s1ap2);
81
+    ABTS_PTR_NOTNULL(tc, recvbuf);
82
+    tests1ap_recv(NULL, recvbuf);
83
+
84
+    /********** Insert Subscriber in Database */
85
+    doc = test_db_new_qos_flow(test_ue);
86
+    ABTS_PTR_NOTNULL(tc, doc);
87
+    ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc));
88
+
89
+    /* Send Attach Request */
90
+    memset(&sess->pdn_connectivity_param,
91
+            0, sizeof(sess->pdn_connectivity_param));
92
+    sess->pdn_connectivity_param.eit = 1;
93
+    sess->pdn_connectivity_param.pco = 1;
94
+    sess->pdn_connectivity_param.request_type =
95
+        OGS_NAS_EPS_REQUEST_TYPE_INITIAL;
96
+    esmbuf = testesm_build_pdn_connectivity_request(sess, false);
97
+    ABTS_PTR_NOTNULL(tc, esmbuf);
98
+
99
+    memset(&test_ue->attach_request_param,
100
+            0, sizeof(test_ue->attach_request_param));
101
+    test_ue->attach_request_param.drx_parameter = 1;
102
+    test_ue->attach_request_param.tmsi_status = 1;
103
+    test_ue->attach_request_param.mobile_station_classmark_2 = 1;
104
+    test_ue->attach_request_param.additional_update_type = 1;
105
+    test_ue->attach_request_param.ue_usage_setting = 1;
106
+    emmbuf = testemm_build_attach_request(test_ue, esmbuf, false, false);
107
+    ABTS_PTR_NOTNULL(tc, emmbuf);
108
+
109
+    memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param));
110
+    sendbuf = test_s1ap_build_initial_ue_message(
111
+            test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false);
112
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
113
+    rv = testenb_s1ap_send(s1ap1, sendbuf);
114
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
115
+
116
+    /* Receive Authentication Request */
117
+    recvbuf = testenb_s1ap_read(s1ap1);
118
+    ABTS_PTR_NOTNULL(tc, recvbuf);
119
+    tests1ap_recv(test_ue, recvbuf);
120
+
121
+    /* Send Authentication response */
122
+    emmbuf = testemm_build_authentication_response(test_ue);
123
+    ABTS_PTR_NOTNULL(tc, emmbuf);
124
+    sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
125
+    ABTS_PTR_NOTNULL(tc, sendbuf);
126
+    rv = testenb_s1ap_send(s1ap1, sendbuf);
127
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
128
+
129
+    /* Receive Security mode Command */
130
+    recvbuf = testenb_s1ap_read(s1ap1);
131
+    ABTS_PTR_NOTNULL(tc, recvbuf);
132
+    tests1ap_recv(test_ue, recvbuf);
133
+
134
+    /* Send Security mode complete */
135
+    test_ue->mobile_identity_imeisv_presence = true;
136
+    emmbuf = testemm_build_security_mode_complete(test_ue);
137
+    ABTS_PTR_NOTNULL(tc, emmbuf);
138
+    sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
139
+    ABTS_PTR_NOTNULL(tc, sendbuf);
140
+    rv = testenb_s1ap_send(s1ap1, sendbuf);
141
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
142
+
143
+    /* Receive ESM Information Request */
144
+    recvbuf = testenb_s1ap_read(s1ap1);
145
+    ABTS_PTR_NOTNULL(tc, recvbuf);
146
+    tests1ap_recv(test_ue, recvbuf);
147
+
148
+    /* Send ESM Information Response */
149
+    esmbuf = testesm_build_esm_information_response(sess);
150
+    ABTS_PTR_NOTNULL(tc, esmbuf);
151
+    sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
152
+    ABTS_PTR_NOTNULL(tc, sendbuf);
153
+    rv = testenb_s1ap_send(s1ap1, sendbuf);
154
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
155
+
156
+    /* Receive Initial Context Setup Request +
157
+     * Attach Accept +
158
+     * Activate Default Bearer Context Request */
159
+    recvbuf = testenb_s1ap_read(s1ap1);
160
+    ABTS_PTR_NOTNULL(tc, recvbuf);
161
+    tests1ap_recv(test_ue, recvbuf);
162
+
163
+    /* Send UE Capability Info Indication */
164
+    sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue);
165
+    ABTS_PTR_NOTNULL(tc, sendbuf);
166
+    rv = testenb_s1ap_send(s1ap1, sendbuf);
167
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
168
+
169
+    /* Send Initial Context Setup Response */
170
+    sendbuf = test_s1ap_build_initial_context_setup_response(test_ue);
171
+    ABTS_PTR_NOTNULL(tc, sendbuf);
172
+    rv = testenb_s1ap_send(s1ap1, sendbuf);
173
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
174
+
175
+    /* Send Attach Complete + Activate default EPS bearer cotext accept */
176
+    test_ue->nr_cgi.cell_id = 0x1234502;
177
+    bearer = test_bearer_find_by_ue_ebi(test_ue, 5);
178
+    ogs_assert(bearer);
179
+    esmbuf = testesm_build_activate_default_eps_bearer_context_accept(
180
+            bearer, false);
181
+    ABTS_PTR_NOTNULL(tc, esmbuf);
182
+    emmbuf = testemm_build_attach_complete(test_ue, esmbuf);
183
+    ABTS_PTR_NOTNULL(tc, emmbuf);
184
+    sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
185
+    ABTS_PTR_NOTNULL(tc, sendbuf);
186
+    rv = testenb_s1ap_send(s1ap1, sendbuf);
187
+    ABTS_INT_EQUAL(tc, OGS_OK, rv);
188
+
189
+    /* Receive EMM information */
190
+    recvbuf = testenb_s1ap_read(s1ap1);
191
+    ABTS_PTR_NOTNULL(tc, recvbuf);
192
+    tests1ap_recv(test_ue, recvbuf);
193
+
194
+    /* Receive E-RAB Setup Request +
195
+     * Activate dedicated EPS bearer context request */
196
+    recvbuf = testenb_s1ap_read(s1ap1);
197
+    ABTS_PTR_NOTNULL(tc, recvbuf);
198
+    tests1ap_recv(test_ue, recvbuf);
199
+
200
+    /* Send E-RAB Setup Response */
201