Compare commits

...

14 Commits

Author SHA1 Message Date
Sukchan Lee f960047ccb [SMF/UPF] Follow-up on Pull #3137 (Issues #2975) 2024-04-14 09:19:07 +09:00
Sukchan Lee a6830b30a0 [SMF/UPF] Changes subnet configuration (#2975)
The way subnet is set up has changed as shown below.

```
<OLD Format>
smf:
  session:
    - subnet: 10.45.0.1/16

<NEW Format>
smf:
  session:
    - subnet: 10.45.0.0/16
      gateway: 10.45.0.1
```

For more information, please refer to Pull Request #2975.
2024-04-13 19:31:19 +09:00
Sukchan Lee 2b6369e9d9 [SMF] crash when malformed NAS message (#3132)
A malformed PDU Session Modification Request is sent from UE
after Registration Complete.

```
Crash 1:
04/12 15:00:44.031: [amf] INFO: [imsi-999700000000001:1:11][0:0:NULL] /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify (../src/amf/nsmf-handler.c:837)
04/12 15:00:46.569: [nas] FATAL: ogs_nas_parse_qos_flow_descriptions: Assertion `descriptions->length' failed. (../lib/nas/5gs/types.c:486)
04/12 15:00:46.569: [core] FATAL: backtrace() returned 11 addresses (../lib/core/ogs-abort.c:37)
../src/smf/../../lib/nas/5gs/libogsnas-5gs.so.2(ogs_nas_parse_qos_flow_descriptions+0x162) [0x7e6e7a5a4e5d]
../src/smf/open5gs-smfd(+0x8c6ec) [0x5dd6c333d6ec]
../src/smf/open5gs-smfd(+0x2d69b) [0x5dd6c32de69b]
../src/smf/../../lib/core/libogscore.so.2(ogs_fsm_dispatch+0x119) [0x7e6e7b216c0c]
../src/smf/open5gs-smfd(+0x288b3) [0x5dd6c32d98b3]
../src/smf/../../lib/core/libogscore.so.2(ogs_fsm_dispatch+0x119) [0x7e6e7b216c0c]
../src/smf/open5gs-smfd(+0xf2d8) [0x5dd6c32c02d8]
../src/smf/../../lib/core/libogscore.so.2(+0x1197a) [0x7e6e7b20797a]
/lib/x86_64-linux-gnu/libc.so.6(+0x94ac3) [0x7e6e7a094ac3]
/lib/x86_64-linux-gnu/libc.so.6(+0x126850) [0x7e6e7a126850]
04/12 15:00:46.613: [app] ERROR: Signal-NUM[17] received (Child status change) (../src/main.c:81)
04/12 15:00:46.613: [sbi] WARNING: [92] HTTP/2 stream 19 was not closed cleanly before end of the underlying stream (../lib/sbi/client.c:626)
04/12 15:00:46.613: [scp] WARNING: response_handler() failed [-1] (../src/scp/sbi-path.c:539)
04/12 15:00:46.613: [amf] ERROR: [1:0] No SmContextUpdateError [500] (../src/amf/nsmf-handler.c:866)
04/12 15:00:46.613: [amf] ERROR: AMF_SESS_CLEAR (../src/amf/amf-sm.c:484)
04/12 15:00:46.613: [amf] INFO: [Removed] Number of AMF-Sessions is now 0 (../src/amf/context.c:2551)
04/12 15:00:50.596: [nrf] WARNING: [c466ec64-f8fe-41ee-a888-194dc4363612] No heartbeat (../src/nrf/nrf-sm.c:260)
04/12 15:00:50.596: [nrf] INFO: [c466ec64-f8fe-41ee-a888-194dc4363612] NF de-registered (../src/nrf/nf-sm.c:205)
04/12 15:00:50.596: [sbi] INFO: [c466ec64-f8fe-41ee-a888-194dc4363612:1] NF removed (../lib/sbi/nnrf-handler.c:750)
04/12 15:00:50.596: [sbi] INFO: [c466ec64-f8fe-41ee-a888-194dc4363612:1] NF removed (../lib/sbi/nnrf-handler.c:750)
04/12 15:00:55.094: [pfcp] WARNING: [10] LOCAL  No Reponse. Give up! for step 1 type 1 peer [127.0.0.4]:8805 (../lib/pfcp/xact.c:599)
04/12 15:00:55.094: [upf] WARNING: No Heartbeat from SMF [127.0.0.4]:8805 (../src/upf/pfcp-sm.c:329)
04/12 15:00:55.094: [upf] INFO: PFCP de-associated [127.0.0.4]:8805 (../src/upf/pfcp-sm.c:199)
04/12 15:01:02.599: [pfcp] WARNING: [11] LOCAL  No Reponse. Give up! for step 1 type 5 peer [127.0.0.4]:8805 (../lib/pfcp/xact.c:599)
04/12 15:01:06.098: [upf] WARNING: Retry to association with peer [127.0.0.4]:8805 failed (../src/upf/pfcp-sm.c:107)

Crash 2:
04/12 15:16:39.748: [amf] INFO: [imsi-999700000000001:1:11][0:0:NULL] /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify (../src/amf/nsmf-handler.c:837)
04/12 15:16:42.155: [nas] FATAL: ogs_nas_parse_qos_rules: Assertion `size+sizeof(rule->flow.flags) <= length' failed. (../lib/nas/5gs/types.c:961)
04/12 15:16:42.155: [core] FATAL: backtrace() returned 11 addresses (../lib/core/ogs-abort.c:37)
../src/smf/../../lib/nas/5gs/libogsnas-5gs.so.2(ogs_nas_parse_qos_rules+0x12d1) [0x7d1affbd2d72]
../src/smf/open5gs-smfd(+0x8b446) [0x629a57861446]
../src/smf/open5gs-smfd(+0x2d69b) [0x629a5780369b]
../src/smf/../../lib/core/libogscore.so.2(ogs_fsm_dispatch+0x119) [0x7d1affd05c0c]
../src/smf/open5gs-smfd(+0x288b3) [0x629a577fe8b3]
../src/smf/../../lib/core/libogscore.so.2(ogs_fsm_dispatch+0x119) [0x7d1affd05c0c]
../src/smf/open5gs-smfd(+0xf2d8) [0x629a577e52d8]
../src/smf/../../lib/core/libogscore.so.2(+0x1197a) [0x7d1affcf697a]
/lib/x86_64-linux-gnu/libc.so.6(+0x94ac3) [0x7d1afea94ac3]
/lib/x86_64-linux-gnu/libc.so.6(+0x126850) [0x7d1afeb26850]
04/12 15:16:42.199: [sbi] WARNING: [92] HTTP/2 stream 13 was not closed cleanly before end of the underlying stream (../lib/sbi/client.c:626)
04/12 15:16:42.199: [scp] WARNING: response_handler() failed [-1] (../src/scp/sbi-path.c:539)
04/12 15:16:42.199: [app] ERROR: Signal-NUM[17] received (Child status change) (../src/main.c:81)
04/12 15:16:42.200: [amf] ERROR: [1:0] No SmContextUpdateError [500] (../src/amf/nsmf-handler.c:866)
04/12 15:16:42.200: [amf] ERROR: AMF_SESS_CLEAR (../src/amf/amf-sm.c:484)
04/12 15:16:42.200: [amf] INFO: [Removed] Number of AMF-Sessions is now 0 (../src/amf/context.c:2551)
04/12 15:16:49.858: [nrf] WARNING: [23f1aee2-f901-41ee-a488-85a58e1e3420] No heartbeat (../src/nrf/nrf-sm.c:260)
04/12 15:16:49.858: [nrf] INFO: [23f1aee2-f901-41ee-a488-85a58e1e3420] NF de-registered (../src/nrf/nf-sm.c:205)
04/12 15:16:49.859: [sbi] INFO: [23f1aee2-f901-41ee-a488-85a58e1e3420:1] NF removed (../lib/sbi/nnrf-handler.c:750)
04/12 15:16:49.859: [sbi] INFO: [23f1aee2-f901-41ee-a488-85a58e1e3420:1] NF removed (../lib/sbi/nnrf-handler.c:750)
04/12 15:16:59.364: [pfcp] WARNING: [5] LOCAL  No Reponse. Give up! for step 1 type 1 peer [127.0.0.4]:8805 (../lib/pfcp/xact.c:599)
04/12 15:16:59.364: [upf] WARNING: No Heartbeat from SMF [127.0.0.4]:8805 (../src/upf/pfcp-sm.c:329)
04/12 15:16:59.364: [upf] INFO: PFCP de-associated [127.0.0.4]:8805 (../src/upf/pfcp-sm.c:199)
```

So, I've fixed it.
2024-04-13 15:03:09 +09:00
Sukchan Lee 3cfa8ba301 [AMF/MME] NAS message in an invaild state (#3131)
In InitialUEMessage, send a NAS message with a message type
other than Registration Request, Deregistration Request, or Service Request,
the following messages from UE will not be accepted.

We found this issue in not only the initial state but multiple states.
We believe if an attacker has the ability to inject a NAS message to the core,
it can perform a DoS attack on the victim UE.

So, I've fixed that The MME/AMF deletes MME_UE_S1AP_ID/AMF_UE_NGAP_ID,
and will not accept any following messages from the UE.
2024-04-13 13:25:09 +09:00
Sukchan Lee cd76dc641d [SEC] Crash and Protocol Violations
The AMF will crash on the following locations when it receives a sequence
of NAS messages from a UE.

- ogs_nas_encrypt: Assertion `pkbuf->len' failed. (../lib/nas/common/security.c:86)
- gmm_state_authentication: Assertion `r != OGS_ERROR' failed. (../src/amf/gmm-sm.c:1561)

Besides the crashes found above, an incorrect protocol transition
is identified in Open5GS. Without any Registration/Attach Request message,
when the Identity Response message sent, the Core Network responds
with an Authentication Request message. According to the standard,
only the Registration/Attach Request message can start a state transition
from the 5GMM/EMM-DEREGISTERED state to the 5GMM/EMM-COMMON-PROCEDURE-INITIATED.

So I've modified the relevant code to address these issues.
2024-04-09 16:23:49 +09:00
Sukchan Lee 09410eba08 Revert "udpate it"
This reverts commit 6814de5c57.
2024-04-09 11:20:16 +09:00
Sukchan Lee 6814de5c57 udpate it 2024-04-09 11:18:57 +09:00
Pau Espin 34b930b4e5 RFC: [HSS] Initial global metrics 2024-04-09 08:35:46 +09:00
Sukchan Lee 3b820b1dbe Revert "RFC: [HSS] Initial global metrics"
This reverts commit 253b09f589.
2024-04-09 08:35:15 +09:00
Sukchan Lee 01ef8ea6f2 Revert "[HSS] Initial Diameter S6a and Cx metrics"
This reverts commit d3a779e715.
2024-04-09 08:35:09 +09:00
Pau Espin d3a779e715 [HSS] Initial Diameter S6a and Cx metrics 2024-04-09 07:14:49 +09:00
Pau Espin 253b09f589 RFC: [HSS] Initial global metrics 2024-04-09 07:14:49 +09:00
Pau Espin cfd4f28f8a cosmetic: Fix trailing whitespace 2024-04-09 07:13:51 +09:00
Pau Espin b30604b289 [SMF] Initial implementation of Final-Unit-Indication
Only "Terminate" action is implemented so far, and it will be used
regardless of the action provided by the OCS.
2024-04-09 07:13:33 +09:00
59 changed files with 1050 additions and 224 deletions

View File

@ -109,8 +109,10 @@ smf:
server:
- address: 127.0.0.4
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -189,8 +191,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -142,8 +142,10 @@ smf:
server:
- address: 127.0.0.4
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -219,8 +221,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -112,8 +112,10 @@ smf:
- address: 127.0.1.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -207,8 +209,10 @@ upf:
server:
- address: 127.0.1.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.1.7

View File

@ -112,8 +112,10 @@ smf:
- address: 127.0.2.4
port: 9090
session:
- subnet: 10.46.0.1/16
- subnet: 2001:db8:babe::1/48
- subnet: 10.46.0.0/16
gateway: 10.46.0.1
- subnet: 2001:db8:babe::/48
gateway: 2001:db8:babe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -207,9 +209,11 @@ upf:
server:
- address: 127.0.2.7
session:
- subnet: 10.46.0.1/16
- subnet: 10.46.0.0/16
gateway: 10.46.0.1
dev: ogstun2
- subnet: 2001:db8:babe::1/48
- subnet: 2001:db8:babe::/48
gateway: 2001:db8:babe::1
dev: ogstun2
metrics:
server:

View File

@ -112,8 +112,10 @@ smf:
- address: 127.0.3.4
port: 9090
session:
- subnet: 10.47.0.1/16
- subnet: 2001:db8:face::1/48
- subnet: 10.47.0.0/16
gateway: 10.47.0.1
- subnet: 2001:db8:face::/48
gateway: 2001:db8:face::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -207,9 +209,11 @@ upf:
server:
- address: 127.0.3.7
session:
- subnet: 10.47.0.1/16
- subnet: 10.47.0.0/16
gateway: 10.47.0.1
dev: ogstun3
- subnet: 2001:db8:face::1/48
- subnet: 2001:db8:face::/48
gateway: 2001:db8:face::1
dev: ogstun3
metrics:
server:

View File

@ -113,8 +113,10 @@ smf:
- address: 127.0.1.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -208,8 +210,10 @@ upf:
server:
- address: 127.0.1.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.1.7

View File

@ -113,8 +113,10 @@ smf:
- address: 127.0.2.4
port: 9090
session:
- subnet: 10.46.0.1/16
- subnet: 2001:db8:babe::1/48
- subnet: 10.46.0.0/16
gateway: 10.46.0.1
- subnet: 2001:db8:babe::/48
gateway: 2001:db8:babe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -208,9 +210,11 @@ upf:
server:
- address: 127.0.2.7
session:
- subnet: 10.46.0.1/16
- subnet: 10.46.0.0/16
gateway: 10.46.0.1
dev: ogstun2
- subnet: 2001:db8:babe::1/48
- subnet: 2001:db8:babe::/48
gateway: 2001:db8:babe::1
dev: ogstun2
metrics:
server:

View File

@ -113,8 +113,10 @@ smf:
- address: 127.0.3.4
port: 9090
session:
- subnet: 10.47.0.1/16
- subnet: 2001:db8:face::1/48
- subnet: 10.47.0.0/16
gateway: 10.47.0.1
- subnet: 2001:db8:face::/48
gateway: 2001:db8:face::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -208,9 +210,11 @@ upf:
server:
- address: 127.0.3.7
session:
- subnet: 10.47.0.1/16
- subnet: 10.47.0.0/16
gateway: 10.47.0.1
dev: ogstun3
- subnet: 2001:db8:face::1/48
- subnet: 2001:db8:face::/48
gateway: 2001:db8:face::1
dev: ogstun3
metrics:
server:

View File

@ -118,8 +118,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -203,8 +205,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -118,8 +118,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -203,8 +205,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -116,8 +116,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -198,8 +200,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -118,8 +118,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -203,8 +205,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -116,8 +116,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -198,8 +200,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -118,8 +118,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -203,8 +205,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -118,8 +118,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -203,8 +205,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -118,8 +118,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -203,8 +205,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -116,8 +116,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -198,8 +200,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -110,8 +110,10 @@ smf:
server:
- address: 127.0.0.4
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -192,8 +194,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -34,8 +34,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -327,23 +329,26 @@ smf:
# o Specific DNN/APN(e.g 'ims') uses 10.46.0.1/16, 2001:db8:babe::1/48
# (If the UE has unknown DNN/APN(not internet/ims), SMF/UPF will crash.)
# session:
# - subnet: 10.45.0.1/16
# - subnet: 10.45.0.0/16
# gateway: 10.45.0.1
# dnn: internet
# - subnet: 2001:db8:cafe::1/48
# - subnet: 2001:db8:cafe::/48
# dnn: internet
# - subnet: 10.46.0.1/16
# - subnet: 10.46.0.0/16
# gateway: 10.46.0.1
# dnn: ims
# - subnet: 2001:db8:babe::1/48
# - subnet: 2001:db8:babe::/48
# dnn: ims
#
# o Pool Range
# session:
# - subnet: 10.45.0.1/16
# - subnet: 10.45.0.0/16
# gateway: 10.45.0.1
# range:
# - 10.45.0.100-10.45.0.200
# - 10.45.1.100-
# - -10.45.0.200
# - subnet: 2001:db8:cafe::1/48
# - subnet: 2001:db8:cafe::/48
# range:
# - 2001:db8:cafe:a0::0-2001:db8:cafe:b0::0
# - 2001:db8:cafe:c0::0-2001:db8:cafe:d0::0

View File

@ -18,8 +18,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7
@ -70,14 +72,16 @@ upf:
# $ sudo ip addr add 2001:db8:babe::1/48 dev ogstun3
#
# session:
# - subnet: 10.45.0.1/16
# - subnet: 10.45.0.0/16
# gateway: 10.45.0.1
# dnn: internet
# - subnet: 2001:db8:cafe::1/48
# - subnet: 2001:db8:cafe::/48
# dnn: internet
# dev: ogstun2
# - subnet: 10.46.0.1/16
# - subnet: 10.46.0.0/16
# gateway: 10.46.0.1
# dnn: ims
# dev: ogstun3
# - subnet: 2001:db8:babe::1/48
# - subnet: 2001:db8:babe::/48
# dnn: ims
# dev: ogstun3

View File

@ -118,8 +118,10 @@ smf:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -203,8 +205,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -110,8 +110,10 @@ smf:
server:
- address: 127.0.0.4
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -194,8 +196,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -107,8 +107,10 @@ smf:
server:
- address: 127.0.0.4
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -184,8 +186,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -107,8 +107,10 @@ smf:
server:
- address: 127.0.0.4
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
@ -187,8 +189,10 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7

View File

@ -110,8 +110,9 @@ smf:
server:
- address: 127.0.0.4
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
dns:
- 8.8.8.8
- 8.8.4.4
@ -193,8 +194,9 @@ upf:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.1/16
- subnet: 2001:db8:cafe::1/48
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
metrics:
server:
- address: 127.0.0.7

View File

@ -27,8 +27,8 @@ static pthread_t fd_stats_th = (pthread_t)NULL;
static ogs_diam_logger_user_handler user_handler = NULL;
static void ogs_diam_logger_cb(enum fd_hook_type type, struct msg * msg,
struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd,
static void ogs_diam_logger_cb(enum fd_hook_type type, struct msg * msg,
struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd,
void * regdata);
static void * diam_stats_worker(void * arg);
@ -41,7 +41,7 @@ int ogs_diam_logger_init(int mode)
self.mode = mode;
self.duration = 60; /* 60 seconds */
CHECK_FCT( fd_hook_register(
CHECK_FCT( fd_hook_register(
mask_peers, ogs_diam_logger_cb, NULL, NULL, &logger_hdl) );
CHECK_POSIX( pthread_mutex_init(&self.stats_lock, NULL) );
@ -81,8 +81,8 @@ void ogs_diam_logger_unregister(void)
}
/* The callback called when messages are received and sent */
static void ogs_diam_logger_cb(enum fd_hook_type type, struct msg * msg,
struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd,
static void ogs_diam_logger_cb(enum fd_hook_type type, struct msg * msg,
struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd,
void * regdata)
{
const char * peer_name = peer ? peer->info.pi_diamid : "<unknown peer>";
@ -117,7 +117,7 @@ static void ogs_diam_logger_cb(enum fd_hook_type type, struct msg * msg,
}
/* Function to display statistics periodically */
static void * diam_stats_worker(void * arg)
static void * diam_stats_worker(void * arg)
{
struct timespec start, now;
struct fd_stats copy;
@ -146,7 +146,7 @@ static void * diam_stats_worker(void * arg)
(int)(now.tv_sec - start.tv_sec),
(long)(now.tv_nsec - start.tv_nsec) / 1000);
}
else
else
{
ogs_trace(" Executing for: %d.%06ld sec",
(int)(now.tv_sec - 1 - start.tv_sec),
@ -154,7 +154,7 @@ static void * diam_stats_worker(void * arg)
}
if (self.mode & FD_MODE_SERVER) {
ogs_trace(" Server: %llu message(s) echoed",
ogs_trace(" Server: %llu message(s) echoed",
copy.nb_echoed);
}
if (self.mode & FD_MODE_CLIENT) {
@ -162,11 +162,11 @@ static void * diam_stats_worker(void * arg)
ogs_trace(" %llu message(s) sent", copy.nb_sent);
ogs_trace(" %llu error(s) received", copy.nb_errs);
ogs_trace(" %llu answer(s) received", copy.nb_recv);
ogs_trace(" fastest: %ld.%06ld sec.",
ogs_trace(" fastest: %ld.%06ld sec.",
copy.shortest / 1000000, copy.shortest % 1000000);
ogs_trace(" slowest: %ld.%06ld sec.",
ogs_trace(" slowest: %ld.%06ld sec.",
copy.longest / 1000000, copy.longest % 1000000);
ogs_trace(" Average: %ld.%06ld sec.",
ogs_trace(" Average: %ld.%06ld sec.",
copy.avg / 1000000, copy.avg % 1000000);
}
ogs_trace("-------------------------------------");

View File

@ -33,7 +33,7 @@ struct ogs_diam_logger_t {
#define FD_MODE_SERVER 0x1
#define FD_MODE_CLIENT 0x2
int mode; /* default FD_MODE_SERVER | FD_MODE_CLIENT */
int duration; /* default 10 */
struct fd_stats {
unsigned long long nb_echoed; /* server */
@ -56,7 +56,7 @@ struct ogs_diam_logger_t* ogs_diam_logger_self(void);
int ogs_diam_logger_stats_start(void);
typedef void (*ogs_diam_logger_user_handler)(
enum fd_hook_type type, struct msg *msg, struct peer_hdr *peer,
enum fd_hook_type type, struct msg *msg, struct peer_hdr *peer,
void *other, struct fd_hook_permsgdata *pmd, void *regdata);
void ogs_diam_logger_register(ogs_diam_logger_user_handler instance);

View File

@ -40,8 +40,10 @@ extern "C" {
#define OGS_DIAM_GY_AVP_CODE_CC_REQUEST_TYPE (416)
#define OGS_DIAM_GY_AVP_CODE_CC_TIME (420)
#define OGS_DIAM_GY_AVP_CODE_CC_TOTAL_OCTETS (421)
#define OGS_DIAM_GY_AVP_CODE_FINAL_UNIT_INDICATION (430)
#define OGS_DIAM_GY_AVP_CODE_GRANTED_SERVICE_UNIT (431)
#define OGS_DIAM_GY_AVP_CODE_VALIDITY_TIME (448)
#define OGS_DIAM_GY_AVP_CODE_FINAL_UNIT_ACTION (449)
#define OGS_DIAM_GY_AVP_CODE_MULTIPLE_SERVICES_CREDIT_CONTROL (456)
#define OGS_DIAM_GY_AVP_CODE_SUPPORTED_FEATURES (628)
#define OGS_DIAM_GY_AVP_CODE_TIME_QUOTA_THRESHOLD (868)
@ -155,6 +157,14 @@ typedef struct ogs_diam_gy_service_unit_s {
uint64_t cc_output_octets;
} ogs_diam_gy_service_unit_t;
typedef struct gs_diam_gy_final_unit_s {
bool cc_final_action_present;
#define OGS_DIAM_GY_FINAL_UNIT_ACTION_TERMINATE 0
#define OGS_DIAM_GY_FINAL_UNIT_ACTION_REDIRECT 1
#define OGS_DIAM_GY_FINAL_UNIT_ACTION_REDIRECT_ACCESS 2
int32_t cc_final_action;
} ogs_diam_gy_final_unit_t;
typedef struct ogs_diam_gy_message_s {
#define OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL 272
#define OGS_DIAM_GY_CMD_RE_AUTH 258
@ -187,6 +197,7 @@ typedef struct ogs_diam_gy_message_s {
uint32_t time_threshold;
uint32_t volume_threshold;
ogs_diam_gy_service_unit_t granted;
ogs_diam_gy_final_unit_t final;
uint32_t result_code;
uint32_t *err;
} cca;

View File

@ -483,35 +483,59 @@ int ogs_nas_parse_qos_flow_descriptions(
ogs_assert(description);
ogs_assert(descriptions);
ogs_assert(descriptions->length);
if (descriptions->length == 0) {
ogs_error("Length is 0");
goto cleanup;
}
if (descriptions->buffer == NULL) {
ogs_error("Buffer is NULL");
goto cleanup;
}
length = descriptions->length;
ogs_assert(descriptions->buffer);
buffer = descriptions->buffer;
size = 0;
while (size < length) {
memset(description, 0, sizeof(*description));
ogs_assert(size+3 <= length);
if (size+3 > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(description, buffer+size, 3);
size += 3;
for (i = 0; i < description->num_of_parameter &&
i < OGS_NAS_MAX_NUM_OF_QOS_FLOW_PARAMETER; i++) {
ogs_assert(size+sizeof(description->param[i].identifier) <= length);
if (size+sizeof(description->param[i].identifier) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&description->param[i].identifier, buffer+size,
sizeof(description->param[i].identifier));
size += sizeof(description->param[i].identifier);
ogs_assert(size+sizeof(description->param[i].len) <= length);
if (size+sizeof(description->param[i].len) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&description->param[i].len, buffer+size,
sizeof(description->param[i].len));
size += sizeof(description->param[i].len);
switch(description->param[i].identifier) {
case OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI:
ogs_assert(description->param[i].len == 1);
ogs_assert(size+description->param[i].len <= length);
if (description->param[i].len != 1) {
ogs_error("Invalid len[%d]", description->param[i].len);
goto cleanup;
}
if (size+description->param[i].len > length) {
ogs_error("Overflow: len[%d] length[%d]",
description->param[i].len, length);
goto cleanup;
}
memcpy(&description->param[i].qos_index,
buffer+size, description->param[i].len);
size += description->param[i].len;
@ -521,8 +545,15 @@ int ogs_nas_parse_qos_flow_descriptions(
case OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_DOWNLINK:
case OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_UPLINK:
case OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_DOWNLINK:
ogs_assert(description->param[i].len == 3);
ogs_assert(size+description->param[i].len <= length);
if (description->param[i].len != 3) {
ogs_error("Invalid len[%d]", description->param[i].len);
goto cleanup;
}
if (size+description->param[i].len > length) {
ogs_error("Overflow: len[%d] length[%d]",
description->param[i].len, length);
goto cleanup;
}
memcpy(&description->param[i].br,
buffer+size, description->param[i].len);
description->param[i].br.value =
@ -530,15 +561,17 @@ int ogs_nas_parse_qos_flow_descriptions(
size += description->param[i].len;
break;
default:
ogs_fatal("Unknown qos_flow parameter identifier [%d]",
ogs_error("Unknown qos_flow parameter identifier [%d]",
description->param[i].identifier);
ogs_assert_if_reached();
goto cleanup;
}
}
description++;
}
cleanup:
return (int)(description-first);
}
@ -777,28 +810,50 @@ int ogs_nas_parse_qos_rules(
ogs_assert(rule);
ogs_assert(rules);
ogs_assert(rules->length);
if (rules->length == 0) {
ogs_error("Length is 0");
goto cleanup;
}
if (rules->buffer == NULL) {
ogs_error("Buffer is NULL");
goto cleanup;
}
length = rules->length;
ogs_assert(rules->buffer);
buffer = rules->buffer;
size = 0;
while (size < length) {
memset(rule, 0, sizeof(*rule));
ogs_assert(size+sizeof(rule->identifier) <= length);
if (size+sizeof(rule->identifier) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&rule->identifier, buffer+size, sizeof(rule->identifier));
size += sizeof(rule->identifier);
ogs_assert(size+sizeof(rule->length) <= length);
if (size+sizeof(rule->length) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&rule->length, buffer+size, sizeof(rule->length));
rule->length = be16toh(rule->length);
size += sizeof(rule->length);
ogs_assert(size+sizeof(rule->flags) <= length);
if (size+sizeof(rule->flags) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&rule->flags, buffer+size, sizeof(rule->flags));
size += sizeof(rule->flags);
if (rule->code == 0 || rule->code == 7) { /* Reserved */
ogs_error("Reserved Rule Code [%d]", rule->code);
goto cleanup;
}
if (rule->code == OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE ||
rule->code == OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS) {
if (rule->num_of_packet_filter != 0) {
@ -806,12 +861,16 @@ int ogs_nas_parse_qos_rules(
"and number of packet filter[%d]",
rule->code, rule->num_of_packet_filter);
rule->num_of_packet_filter = 0;
goto cleanup;
}
}
for (i = 0; i < rule->num_of_packet_filter &&
i < OGS_MAX_NUM_OF_FLOW_IN_GTP; i++) {
ogs_assert(size+sizeof(rule->pf[i].flags) <= length);
if (size+sizeof(rule->pf[i].flags) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&rule->pf[i].flags, buffer+size, sizeof(rule->pf[i].flags));
size += sizeof(rule->pf[i].flags);
@ -819,24 +878,35 @@ int ogs_nas_parse_qos_rules(
OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS)
continue;
ogs_assert(size+sizeof(rule->pf[i].content.length) <= length);
if (size+sizeof(rule->pf[i].content.length) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.length, buffer+size,
sizeof(rule->pf[i].content.length));
size += sizeof(rule->pf[i].content.length);
j = 0; len = 0;
while(len < rule->pf[i].content.length) {
ogs_assert(size+len+
sizeof(rule->pf[i].content.component[j].type) <= length);
if (size+len+
sizeof(rule->pf[i].content.component[j].type) > length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].type,
buffer+size+len,
sizeof(rule->pf[i].content.component[j].type));
len += sizeof(rule->pf[i].content.component[j].type);
switch(rule->pf[i].content.component[j].type) {
case OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE:
ogs_assert(size+len+
sizeof(rule->pf[i].content.component[j].proto) <=
length);
if (size+len+
sizeof(rule->pf[i].content.component[j].proto) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].proto,
buffer+size+len,
sizeof(rule->pf[i].content.component[j].proto));
@ -844,17 +914,25 @@ int ogs_nas_parse_qos_rules(
break;
case OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE:
case OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE:
ogs_assert(size+len+
sizeof(rule->pf[i].content.component[j].ipv4.addr) <=
length);
if (size+len+
sizeof(rule->pf[i].content.component[j].ipv4.addr) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].ipv4.addr,
buffer+size+len,
sizeof(rule->pf[i].content.component[j].ipv4.addr));
len += sizeof(rule->pf[i].content.component[j].ipv4.addr);
ogs_assert(size+len+
sizeof(rule->pf[i].content.component[j].ipv4.mask) <=
length);
if (size+len+
sizeof(rule->pf[i].content.component[j].ipv4.mask) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].ipv4.mask,
buffer+size+len,
sizeof(rule->pf[i].content.component[j].ipv4.mask));
@ -862,18 +940,26 @@ int ogs_nas_parse_qos_rules(
break;
case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE:
case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE:
ogs_assert(size+len+
sizeof(rule->pf[i].content.component[j].ipv6.addr) <=
length);
if (size+len+
sizeof(rule->pf[i].content.component[j].ipv6.addr) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].ipv6.addr,
buffer+size+len,
sizeof(rule->pf[i].content.component[j].ipv6.addr));
len += sizeof(rule->pf[i].content.component[j].ipv6.addr);
ogs_assert(size+len+
if (size+len+
sizeof(
rule->pf[i].content.component[j].ipv6.prefixlen) <=
length);
rule->pf[i].content.component[j].ipv6.prefixlen) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].ipv6.prefixlen,
buffer+size+len,
sizeof(
@ -883,10 +969,14 @@ int ogs_nas_parse_qos_rules(
break;
case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE:
case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE:
ogs_assert(size+len+
if (size+len+
sizeof(
rule->pf[i].content.component[j].ipv6_mask.addr) <=
length);
rule->pf[i].content.component[j].ipv6_mask.addr) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].ipv6_mask.addr,
buffer+size+len,
sizeof(
@ -894,10 +984,14 @@ int ogs_nas_parse_qos_rules(
len += sizeof(
rule->pf[i].content.component[j].ipv6_mask.addr);
ogs_assert(size+len+
if (size+len+
sizeof(
rule->pf[i].content.component[j].ipv6_mask.mask) <=
length);
rule->pf[i].content.component[j].ipv6_mask.mask) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].ipv6_mask.mask,
buffer+size+len,
sizeof(
@ -907,9 +1001,13 @@ int ogs_nas_parse_qos_rules(
break;
case OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE:
case OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE:
ogs_assert(size+len+
sizeof(rule->pf[i].content.component[j].port.low) <=
length);
if (size+len+
sizeof(rule->pf[i].content.component[j].port.low) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].port.low,
buffer+size+len,
sizeof(rule->pf[i].content.component[j].port.low));
@ -919,9 +1017,13 @@ int ogs_nas_parse_qos_rules(
break;
case OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE:
case OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE:
ogs_assert(size+len+
sizeof(rule->pf[i].content.component[j].port.low) <=
length);
if (size+len+
sizeof(rule->pf[i].content.component[j].port.low) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].port.low,
buffer+size+len,
sizeof(rule->pf[i].content.component[j].port.low));
@ -929,9 +1031,13 @@ int ogs_nas_parse_qos_rules(
be16toh(rule->pf[i].content.component[j].port.low);
len += sizeof(rule->pf[i].content.component[j].port.low);
ogs_assert(size+len+
sizeof(rule->pf[i].content.component[j].port.high) <=
length);
if (size+len+
sizeof(rule->pf[i].content.component[j].port.high) >
length) {
ogs_error("Overflow : size[%d] len[%d] length[%d]",
size, len, length);
goto cleanup;
}
memcpy(&rule->pf[i].content.component[j].port.high,
buffer+size+len,
sizeof(rule->pf[i].content.component[j].port.high));
@ -942,7 +1048,7 @@ int ogs_nas_parse_qos_rules(
default:
ogs_error("Unknown Packet Filter Type(%d)",
rule->pf[i].content.component[j].type);
return -1;
goto cleanup;
}
j++;
}
@ -954,11 +1060,17 @@ int ogs_nas_parse_qos_rules(
rule->code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS &&
rule->code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS) {
ogs_assert(size+sizeof(rule->precedence) <= length);
if (size+sizeof(rule->precedence) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&rule->precedence, buffer+size, sizeof(rule->precedence));
size += sizeof(rule->precedence);
ogs_assert(size+sizeof(rule->flow.flags) <= length);
if (size+sizeof(rule->flow.flags) > length) {
ogs_error("Overflow : size[%d] length[%d]", size, length);
goto cleanup;
}
memcpy(&rule->flow.flags, buffer+size, sizeof(rule->flow.flags));
size += sizeof(rule->flow.flags);
}
@ -966,6 +1078,8 @@ int ogs_nas_parse_qos_rules(
rule++;
}
cleanup:
return (int)(rule-first);
}

View File

@ -743,6 +743,7 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
do {
ogs_pfcp_subnet_t *subnet = NULL;
const char *ipstr = NULL;
const char *gateway = NULL;
const char *mask_or_numbits = NULL;
const char *dnn = NULL;
const char *dev = self.tun_ifname;
@ -781,6 +782,8 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
mask_or_numbits = (const char *)v;
}
}
} else if (!strcmp(subnet_key, "gateway")) {
gateway = ogs_yaml_iter_value(&subnet_iter);
} else if (!strcmp(subnet_key, "apn") ||
!strcmp(subnet_key, "dnn")) {
dnn = ogs_yaml_iter_value(&subnet_iter);
@ -825,7 +828,7 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
}
subnet = ogs_pfcp_subnet_add(
ipstr, mask_or_numbits, dnn, dev);
ipstr, mask_or_numbits, gateway, dnn, dev);
ogs_assert(subnet);
subnet->num_of_range = num;
@ -2150,7 +2153,7 @@ ogs_pfcp_dev_t *ogs_pfcp_dev_find_by_ifname(const char *ifname)
ogs_pfcp_subnet_t *ogs_pfcp_subnet_add(
const char *ipstr, const char *mask_or_numbits,
const char *dnn, const char *ifname)
const char *gateway, const char *dnn, const char *ifname)
{
int rv;
ogs_pfcp_dev_t *dev = NULL;
@ -2179,6 +2182,41 @@ ogs_pfcp_subnet_t *ogs_pfcp_subnet_add(
subnet->family = subnet->gw.family;
subnet->prefixlen = atoi(mask_or_numbits);
if (memcmp(subnet->gw.sub, subnet->sub.sub,
sizeof(subnet->gw.sub)) != 0) {
char *subnet_string = NULL;
if (subnet->family == AF_INET) {
subnet_string = ogs_ipv4_to_string(subnet->sub.sub[0]);
ogs_assert(subnet_string);
} else if (subnet->family == AF_INET6) {
subnet_string = ogs_ipv6addr_to_string(
(uint8_t*)&subnet->sub.sub[0]);
ogs_assert(subnet_string);
}
ogs_warn("Please change the configuration files of "
"smf.yaml and upf.yaml as below.");
ogs_log_print(OGS_LOG_WARN, "\n<OLD Format>\n");
ogs_log_print(OGS_LOG_WARN, "smf:\n");
ogs_log_print(OGS_LOG_WARN, " session:\n");
ogs_log_print(OGS_LOG_WARN, " - subnet: %s/%s\n",
ipstr, mask_or_numbits);
ogs_log_print(OGS_LOG_WARN, "\n<NEW Format>\n");
ogs_log_print(OGS_LOG_WARN, "smf:\n");
ogs_log_print(OGS_LOG_WARN, " session:\n");
ogs_log_print(OGS_LOG_WARN, " - subnet: %s/%s\n",
subnet_string ? subnet_string : "Unknown", mask_or_numbits);
ogs_log_print(OGS_LOG_WARN, " gateway: %s\n\n\n", ipstr);
ogs_free(subnet_string);
}
}
if (gateway) {
rv = ogs_ipsubnet(&subnet->gw, gateway, NULL);
ogs_assert(rv == OGS_OK);
}
if (dnn)

View File

@ -491,7 +491,7 @@ ogs_pfcp_dev_t *ogs_pfcp_dev_find_by_ifname(const char *ifname);
ogs_pfcp_subnet_t *ogs_pfcp_subnet_add(
const char *ipstr, const char *mask_or_numbits,
const char *dnn, const char *ifname);
const char *gateway, const char *dnn, const char *ifname);
ogs_pfcp_subnet_t *ogs_pfcp_subnet_next(ogs_pfcp_subnet_t *subnet);
void ogs_pfcp_subnet_remove(ogs_pfcp_subnet_t *subnet);
void ogs_pfcp_subnet_remove_all(void);

View File

@ -2852,7 +2852,7 @@ bool amf_update_allowed_nssai(amf_ue_t *amf_ue)
s_nssai[amf_ue->rejected_nssai.num_of_s_nssai];
bool ta_supported = false;
ogs_assert(amf_ue->num_of_slice);
slice = ogs_slice_find_by_s_nssai(
amf_ue->slice, amf_ue->num_of_slice,
(ogs_s_nssai_t *)requested);

View File

@ -1475,6 +1475,18 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
break;
case OGS_NAS_5GS_IDENTITY_RESPONSE:
if (amf_ue->nas.message_type == 0) {
ogs_warn("No Received NAS message");
r = ngap_send_error_indication2(
ran_ue,
NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
OGS_FSM_TRAN(s, gmm_state_exception);
break;
}
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
ogs_info("Identity response");
@ -1484,17 +1496,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
ogs_error("gmm_handle_identity_response() "
"failed [%d] in type [%d]",
gmm_cause, amf_ue->nas.message_type);
if (amf_ue->nas.message_type ==
OGS_NAS_5GS_REGISTRATION_REQUEST ||
amf_ue->nas.message_type ==
OGS_NAS_5GS_SERVICE_REQUEST)
r = nas_5gs_send_gmm_reject(ran_ue, amf_ue, gmm_cause);
else
r = ngap_send_error_indication2(
ran_ue,
NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error);
r = nas_5gs_send_gmm_reject(ran_ue, amf_ue, gmm_cause);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
OGS_FSM_TRAN(s, gmm_state_exception);

View File

@ -178,6 +178,10 @@ int nas_5gs_security_decode(amf_ue_t *amf_ue,
if (security_header_type.ciphered) {
/* decrypt NAS message */
if (pkbuf->len == 0) {
ogs_error("Cannot decrypt Malformed NAS Message");
return OGS_ERROR;
}
ogs_nas_encrypt(amf_ue->selected_enc_algorithm,
amf_ue->knas_enc, amf_ue->ul_count.i32,
amf_ue->nas.access_type,

View File

@ -200,6 +200,7 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
default:
ogs_error("Not implemented(security header type:0x%x)",
sh->security_header_type);
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
@ -207,12 +208,39 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
if (nas_5gs_security_decode(ran_ue->amf_ue,
security_header_type, nasbuf) != OGS_OK) {
ogs_error("nas_eps_security_decode failed()");
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
}
h = (ogs_nas_5gmm_header_t *)nasbuf->data;
ogs_assert(h);
if (procedureCode == NGAP_ProcedureCode_id_InitialUEMessage) {
if (h->extended_protocol_discriminator !=
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM) {
ogs_error("Invalid extended_protocol_discriminator [%d]",
h->extended_protocol_discriminator);
ogs_pkbuf_free(nasbuf);
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
if (h->message_type != OGS_NAS_5GS_REGISTRATION_REQUEST &&
h->message_type != OGS_NAS_5GS_SERVICE_REQUEST &&
h->message_type != OGS_NAS_5GS_DEREGISTRATION_REQUEST_FROM_UE) {
ogs_error("Invalid 5GMM message type [%d]", h->message_type);
ogs_pkbuf_free(nasbuf);
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
}
if (h->extended_protocol_discriminator ==
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM) {
e = amf_event_new(AMF_EVENT_5GMM_MESSAGE);
@ -247,7 +275,10 @@ int ngap_send_to_nas(ran_ue_t *ran_ue,
} else {
ogs_error("Unknown NAS Protocol discriminator 0x%02x",
h->extended_protocol_discriminator);
ogs_pkbuf_free(nasbuf);
ran_ue_remove(ran_ue);
return OGS_ERROR;
}
}

View File

@ -199,6 +199,7 @@ int amf_nudm_sdm_handle_provisioned(
continue;
}
ogs_assert(amf_ue->num_of_slice);
slice = ogs_slice_find_by_s_nssai(
amf_ue->slice, amf_ue->num_of_slice,
&s_nssai);

View File

@ -337,6 +337,8 @@ int hss_context_parse_config(void)
#else
self.use_mongodb_change_stream = false;
#endif
} else if (!strcmp(hss_key, "metrics")) {
/* handle config in metrics library */
} else
ogs_warn("unknown key `%s`", hss_key);
}
@ -519,6 +521,7 @@ static hss_imsi_t *imsi_add(char *id)
ogs_hash_set(self.imsi_hash, imsi->id, strlen(imsi->id), imsi);
ogs_list_add(&self.imsi_list, imsi);
hss_metrics_inst_global_inc(HSS_METR_GLOB_GAUGE_IMSI);
return imsi;
}
@ -528,6 +531,7 @@ static void imsi_remove(hss_imsi_t *imsi)
ogs_assert(imsi);
ogs_list_remove(&self.imsi_list, imsi);
hss_metrics_inst_global_dec(HSS_METR_GLOB_GAUGE_IMSI);
ogs_assert(imsi->id);
ogs_hash_set(self.imsi_hash, imsi->id, strlen(imsi->id), NULL);
@ -569,6 +573,7 @@ static hss_impi_t *impi_add(char *id)
ogs_hash_set(self.impi_hash, impi->id, strlen(impi->id), impi);
ogs_list_add(&self.impi_list, impi);
hss_metrics_inst_global_inc(HSS_METR_GLOB_GAUGE_IMPI);
return impi;
}
@ -578,6 +583,7 @@ static void impi_remove(hss_impi_t *impi)
ogs_assert(impi);
ogs_list_remove(&self.impi_list, impi);
hss_metrics_inst_global_dec(HSS_METR_GLOB_GAUGE_IMPI);
impu_remove_all(impi);
@ -633,7 +639,9 @@ static hss_impu_t *impu_add(hss_impi_t *impi, char *id)
ogs_hash_set(self.impu_hash, impu->id, strlen(impu->id), impu);
impu->impi = impi;
ogs_list_add(&impi->impu_list, impu);
hss_metrics_inst_global_inc(HSS_METR_GLOB_GAUGE_IMPU);
return impu;
}
@ -647,6 +655,7 @@ static void impu_remove(hss_impu_t *impu)
ogs_assert(impi);
ogs_list_remove(&impi->impu_list, impu);
hss_metrics_inst_global_dec(HSS_METR_GLOB_GAUGE_IMPU);
ogs_assert(impu->id);
ogs_hash_set(self.impu_hash, impu->id, strlen(impu->id), NULL);

View File

@ -25,6 +25,7 @@
#include "ogs-diameter-swx.h"
#include "ogs-dbi.h"
#include "ogs-app.h"
#include "metrics.h"
#ifdef __cplusplus
extern "C" {

View File

@ -34,7 +34,7 @@ static struct disp_hdl *hdl_cx_sar = NULL;
static struct disp_hdl *hdl_cx_lir = NULL;
/* Default callback for the application. */
static int hss_ogs_diam_cx_fb_cb(struct msg **msg, struct avp *avp,
static int hss_ogs_diam_cx_fb_cb(struct msg **msg, struct avp *avp,
struct session *session, void *opaque, enum disp_action *act)
{
/* This CB should never be called */
@ -44,7 +44,7 @@ static int hss_ogs_diam_cx_fb_cb(struct msg **msg, struct avp *avp,
}
/* Callback for incoming User-Authorization-Request messages */
static int hss_ogs_diam_cx_uar_cb( struct msg **msg, struct avp *avp,
static int hss_ogs_diam_cx_uar_cb( struct msg **msg, struct avp *avp,
struct session *session, void *opaque, enum disp_action *act)
{
int rv, ret;

View File

@ -20,6 +20,7 @@
#include "hss-context.h"
#include "hss-fd-path.h"
#include "hss-sm.h"
#include "metrics.h"
static ogs_thread_t *thread;
@ -35,9 +36,14 @@ int hss_initialize(void)
rv = ogs_app_parse_local_conf(APP_NAME);
if (rv != OGS_OK) return rv;
hss_metrics_init();
hss_context_init();
hss_event_init();
rv = ogs_metrics_context_parse_config(APP_NAME);
if (rv != OGS_OK) return rv;
rv = hss_context_parse_config();
if (rv != OGS_OK) return rv;
@ -45,6 +51,8 @@ int hss_initialize(void)
ogs_app()->logger.domain, ogs_app()->logger.level);
if (rv != OGS_OK) return rv;
ogs_metrics_context_open(ogs_metrics_self());
rv = ogs_dbi_init(ogs_app()->db_uri);
if (rv != OGS_OK) return rv;
@ -65,12 +73,14 @@ void hss_terminate(void)
hss_event_term();
ogs_thread_destroy(thread);
ogs_metrics_context_close(ogs_metrics_self());
hss_fd_final();
ogs_dbi_final();
hss_context_final();
hss_event_final();
hss_metrics_final();
return;
}

View File

@ -22,6 +22,7 @@ libhss_sources = files('''
hss-event.h
hss-timer.h
hss-sm.h
metrics.h
hss-init.c
hss-context.c
@ -34,11 +35,14 @@ libhss_sources = files('''
hss-swx-path.c
hss-fd-path.c
metrics.c
'''.split())
libhss = static_library('hss',
sources : libhss_sources,
dependencies : [libapp_dep,
dependencies : [libmetrics_dep,
libapp_dep,
libcrypt_dep,
libdbi_dep,
libdiameter_s6a_dep,
@ -48,7 +52,8 @@ libhss = static_library('hss',
libhss_dep = declare_dependency(
link_with : libhss,
dependencies : [libapp_dep,
dependencies : [libmetrics_dep,
libapp_dep,
libcrypt_dep,
libdbi_dep,
libdiameter_s6a_dep,

93
src/hss/metrics.c Normal file
View File

@ -0,0 +1,93 @@
#include "ogs-app.h"
#include "hss-context.h"
#include "metrics.h"
typedef struct hss_metrics_spec_def_s {
unsigned int type;
const char *name;
const char *description;
int initial_val;
unsigned int num_labels;
const char **labels;
} hss_metrics_spec_def_t;
/* Helper generic functions: */
static int hss_metrics_init_inst(ogs_metrics_inst_t **inst, ogs_metrics_spec_t **specs,
unsigned int len, unsigned int num_labels, const char **labels)
{
unsigned int i;
for (i = 0; i < len; i++)
inst[i] = ogs_metrics_inst_new(specs[i], num_labels, labels);
return OGS_OK;
}
static int hss_metrics_free_inst(ogs_metrics_inst_t **inst,
unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
ogs_metrics_inst_free(inst[i]);
memset(inst, 0, sizeof(inst[0]) * len);
return OGS_OK;
}
static int hss_metrics_init_spec(ogs_metrics_context_t *ctx,
ogs_metrics_spec_t **dst, hss_metrics_spec_def_t *src, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++) {
dst[i] = ogs_metrics_spec_new(ctx, src[i].type,
src[i].name, src[i].description,
src[i].initial_val, src[i].num_labels, src[i].labels,
NULL);
}
return OGS_OK;
}
/* GLOBAL */
ogs_metrics_spec_t *hss_metrics_spec_global[_HSS_METR_GLOB_MAX];
ogs_metrics_inst_t *hss_metrics_inst_global[_HSS_METR_GLOB_MAX];
hss_metrics_spec_def_t hss_metrics_spec_def_global[_HSS_METR_GLOB_MAX] = {
/* Global Gauges: */
[HSS_METR_GLOB_GAUGE_IMSI] = {
.type = OGS_METRICS_METRIC_TYPE_GAUGE,
.name = "hss_imsi",
.description = "Number of IMSIs attached to HSS",
},
[HSS_METR_GLOB_GAUGE_IMPI] = {
.type = OGS_METRICS_METRIC_TYPE_GAUGE,
.name = "hss_impi",
.description = "Number of IMPIs attached to HSS",
},
[HSS_METR_GLOB_GAUGE_IMPU] = {
.type = OGS_METRICS_METRIC_TYPE_GAUGE,
.name = "hss_impu",
.description = "Number of IMPUs attached to HSS",
},
};
int hss_metrics_init_inst_global(void)
{
return hss_metrics_init_inst(hss_metrics_inst_global, hss_metrics_spec_global,
_HSS_METR_GLOB_MAX, 0, NULL);
}
int hss_metrics_free_inst_global(void)
{
return hss_metrics_free_inst(hss_metrics_inst_global, _HSS_METR_GLOB_MAX);
}
void hss_metrics_init(void)
{
ogs_metrics_context_t *ctx = ogs_metrics_self();
ogs_metrics_context_init();
hss_metrics_init_spec(ctx, hss_metrics_spec_global, hss_metrics_spec_def_global,
_HSS_METR_GLOB_MAX);
hss_metrics_init_inst_global();
}
void hss_metrics_final(void)
{
ogs_metrics_context_final();
}

38
src/hss/metrics.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef HSS_METRICS_H
#define HSS_METRICS_H
#include "ogs-metrics.h"
#ifdef __cplusplus
extern "C" {
#endif
/* GLOBAL */
typedef enum hss_metric_type_global_s {
HSS_METR_GLOB_GAUGE_IMSI,
HSS_METR_GLOB_GAUGE_IMPI,
HSS_METR_GLOB_GAUGE_IMPU,
_HSS_METR_GLOB_MAX,
} hss_metric_type_global_t;
extern ogs_metrics_inst_t *hss_metrics_inst_global[_HSS_METR_GLOB_MAX];
int hss_metrics_init_inst_global(void);
int hss_metrics_free_inst_global(void);
static inline void hss_metrics_inst_global_set(hss_metric_type_global_t t, int val)
{ ogs_metrics_inst_set(hss_metrics_inst_global[t], val); }
static inline void hss_metrics_inst_global_add(hss_metric_type_global_t t, int val)
{ ogs_metrics_inst_add(hss_metrics_inst_global[t], val); }
static inline void hss_metrics_inst_global_inc(hss_metric_type_global_t t)
{ ogs_metrics_inst_inc(hss_metrics_inst_global[t]); }
static inline void hss_metrics_inst_global_dec(hss_metric_type_global_t t)
{ ogs_metrics_inst_dec(hss_metrics_inst_global[t]); }
void hss_metrics_init(void);
void hss_metrics_final(void);
#ifdef __cplusplus
}
#endif
#endif /* HSS_METRICS_H */

View File

@ -390,6 +390,16 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e,
switch (message->emm.h.message_type) {
case OGS_NAS_EPS_IDENTITY_RESPONSE:
if (mme_ue->nas_eps.type == 0) {
ogs_warn("No Received NAS message");
r = s1ap_send_error_indication2(mme_ue,
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
OGS_FSM_TRAN(s, emm_state_exception);
break;
}
ogs_info("Identity response");
CLEAR_MME_UE_TIMER(mme_ue->t3470);

View File

@ -223,6 +223,10 @@ int nas_eps_security_decode(mme_ue_t *mme_ue,
if (security_header_type.ciphered) {
/* decrypt NAS message */
if (pkbuf->len == 0) {
ogs_error("Cannot decrypt Malformed NAS Message");
return OGS_ERROR;
}
ogs_nas_encrypt(mme_ue->selected_enc_algorithm,
mme_ue->knas_enc, mme_ue->ul_count.i32, NAS_SECURITY_BEARER,
OGS_NAS_SECURITY_UPLINK_DIRECTION, pkbuf);

View File

@ -586,10 +586,8 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message)
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id,
enb_ue->saved.tai.tac, enb_ue->saved.e_cgi.cell_id);
r = s1ap_send_to_nas(enb_ue,
S1AP_ProcedureCode_id_initialUEMessage, NAS_PDU);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
ogs_expect(OGS_OK == s1ap_send_to_nas(
enb_ue, S1AP_ProcedureCode_id_initialUEMessage, NAS_PDU));
}
void s1ap_handle_uplink_nas_transport(
@ -777,10 +775,8 @@ void s1ap_handle_uplink_nas_transport(
ogs_error("No UE Context in UplinkNASTransport");
}
r = s1ap_send_to_nas(enb_ue,
S1AP_ProcedureCode_id_uplinkNASTransport, NAS_PDU);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
ogs_expect(OGS_OK == s1ap_send_to_nas(
enb_ue, S1AP_ProcedureCode_id_uplinkNASTransport, NAS_PDU));
}
void s1ap_handle_ue_capability_info_indication(

View File

@ -207,6 +207,7 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
default:
ogs_error("Not implemented(security header type:0x%x)",
sh->security_header_type);
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
@ -214,12 +215,42 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
if (nas_eps_security_decode(enb_ue->mme_ue,
security_header_type, nasbuf) != OGS_OK) {
ogs_error("nas_eps_security_decode failed()");
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
}
h = (ogs_nas_emm_header_t *)nasbuf->data;
ogs_assert(h);
if (procedureCode == S1AP_ProcedureCode_id_initialUEMessage) {
if (h->protocol_discriminator != OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM) {
ogs_error("Invalid protocol_discriminator [%d]",
h->protocol_discriminator);
ogs_pkbuf_free(nasbuf);
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
if (h->security_header_type !=
OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE &&
h->message_type != OGS_NAS_EPS_ATTACH_REQUEST &&
h->message_type != OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST &&
h->message_type != OGS_NAS_EPS_EXTENDED_SERVICE_REQUEST &&
h->message_type != OGS_NAS_EPS_DETACH_REQUEST) {
ogs_error("Invalid EMM message type [%d]", h->message_type);
ogs_pkbuf_free(nasbuf);
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
}
if (h->protocol_discriminator == OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM) {
int rv;
e = mme_event_new(MME_EVENT_EMM_MESSAGE);
@ -255,7 +286,10 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
} else {
ogs_error("Unknown/Unimplemented NAS Protocol discriminator 0x%02x",
h->protocol_discriminator);
ogs_pkbuf_free(nasbuf);
enb_ue_remove(enb_ue);
return OGS_ERROR;
}
}

View File

@ -357,6 +357,9 @@ typedef struct smf_sess_s {
uint64_t dl_octets;
ogs_time_t duration;
uint32_t reporting_reason; /* OGS_DIAM_GY_REPORTING_REASON_* */
/* Whether Gy Final-Unit-Indication was received.
* Triggers session release upon Rx of next PFCP Report Req */
bool final_unit;
/* Snapshot of measurement when last report was sent: */
struct {
uint64_t ul_octets;

View File

@ -229,7 +229,11 @@ int gsm_handle_pdu_session_modification_request(
int num_of_rule = 0;
num_of_rule = ogs_nas_parse_qos_rules(qos_rule, requested_qos_rules);
ogs_assert(num_of_rule > 0);
if (!num_of_rule) {
ogs_error("[%s:%d] Invalid modification request",
smf_ue->supi, sess->psi);
goto cleanup;
}
for (i = 0; i < num_of_rule; i++) {
qos_flow = smf_qos_flow_find_by_qfi(
@ -430,7 +434,11 @@ int gsm_handle_pdu_session_modification_request(
num_of_description = ogs_nas_parse_qos_flow_descriptions(
qos_flow_description, requested_qos_flow_descriptions);
ogs_assert(num_of_description > 0);
if (!num_of_description) {
ogs_error("[%s:%d] Invalid modification request",
smf_ue->supi, sess->psi);
goto cleanup;
}
for (i = 0; i < num_of_description; i++) {
qos_flow = smf_qos_flow_find_by_qfi(
@ -478,16 +486,7 @@ int gsm_handle_pdu_session_modification_request(
ogs_error("[%s:%d] Invalid modification request [modify:%d]",
smf_ue->supi, sess->psi,
ogs_list_count(&sess->qos_flow_to_modify_list));
n1smbuf = gsm_build_pdu_session_modification_reject(sess,
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
ogs_assert(n1smbuf);
smf_sbi_send_sm_context_update_error_n1_n2_message(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
n1smbuf, OpenAPI_n2_sm_info_type_NULL, NULL);
return OGS_ERROR;
goto cleanup;
}
if (pfcp_flags & OGS_PFCP_MODIFY_REMOVE) {
@ -522,4 +521,15 @@ int gsm_handle_pdu_session_modification_request(
OGS_PFCP_MODIFY_UE_REQUESTED|pfcp_flags, 0));
return OGS_OK;
cleanup:
n1smbuf = gsm_build_pdu_session_modification_reject(sess,
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
ogs_assert(n1smbuf);
smf_sbi_send_sm_context_update_error_n1_n2_message(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
n1smbuf, OpenAPI_n2_sm_info_type_NULL, NULL);
return OGS_ERROR;
}

View File

@ -727,6 +727,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_pfcp_xact_t *pfcp_xact = NULL;
ogs_pfcp_message_t *pfcp_message = NULL;
uint8_t pfcp_cause;
ogs_diam_gy_message_t *gy_message = NULL;
uint32_t diam_err;
@ -838,6 +839,14 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
OGS_FSM_TRAN(s, smf_gsm_state_epc_session_will_release);
break;
case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE:
pfcp_cause = smf_n4_handle_session_report_request(sess, pfcp_xact,
&pfcp_message->pfcp_session_report_request);
if (pfcp_cause != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_deletion);
}
break;
default:
ogs_error("cannot handle PFCP message type[%d]",
pfcp_message->h.type);

View File

@ -164,6 +164,7 @@ uint32_t smf_gy_handle_cca_initial_request(
/* Configure based on what we received from OCS: */
urr_update_time(sess, bearer->urr, gy_message);
urr_update_volume(sess, bearer->urr, gy_message);
sess->gy.final_unit = gy_message->cca.final.cc_final_action_present;
/* Associate acconting URR each direction PDR: */
ogs_pfcp_pdr_associate_urr(bearer->ul_pdr, bearer->urr);
@ -221,6 +222,7 @@ uint32_t smf_gy_handle_cca_update_request(
urr_update_time(sess, urr, gy_message);
urr_update_volume(sess, urr, gy_message);
sess->gy.final_unit = gy_message->cca.final.cc_final_action_present;
/* Associate accounting URR each direction PDR: */
ogs_pfcp_pdr_associate_urr(bearer->ul_pdr, urr);
ogs_pfcp_pdr_associate_urr(bearer->dl_pdr, urr);

View File

@ -48,6 +48,8 @@ static ogs_thread_mutex_t sess_state_mutex;
static int decode_granted_service_unit(
ogs_diam_gy_service_unit_t *su, struct avp *avpch1, int *perror);
static int decode_final_unit_indication(
ogs_diam_gy_final_unit_t *fu, struct avp *avpch1, int *perror);
static void smf_gy_cca_cb(void *data, struct msg **msg);
static __inline__ struct sess_state *new_state(os0_t sid)
@ -1149,6 +1151,11 @@ static void smf_gy_cca_cb(void *data, struct msg **msg)
case OGS_DIAM_GY_AVP_CODE_VOLUME_QUOTA_THRESHOLD:
gy_message->cca.volume_threshold = hdr->avp_value->u32;
break;
case OGS_DIAM_GY_AVP_CODE_FINAL_UNIT_INDICATION:
rv = decode_final_unit_indication(
&gy_message->cca.final, avpch1, &error);
ogs_assert(rv == OGS_OK);
break;
default:
ogs_warn("Not supported(%d)", hdr->avp_code);
break;
@ -1464,3 +1471,42 @@ static int decode_granted_service_unit(
return OGS_OK;
}
static int decode_final_unit_indication(
ogs_diam_gy_final_unit_t *fu, struct avp *avpch1, int *perror)
{
int ret = 0, error = 0;
struct avp *avpch2;
struct avp_hdr *hdr;
ogs_assert(fu);
ogs_assert(avpch1);
memset(fu, 0, sizeof(*fu));
ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL);
ogs_assert(ret == 0);
while (avpch2) {
ret = fd_msg_avp_hdr(avpch2, &hdr);
ogs_assert(ret == 0);
switch (hdr->avp_code) {
case OGS_DIAM_GY_AVP_CODE_FINAL_UNIT_ACTION:
fu->cc_final_action_present = true;
fu->cc_final_action = hdr->avp_value->i32;
break;
/* TODO:
case OGS_DIAM_GY_AVP_CODE_REDIRECT_SERVER:
case OGS_DIAM_GY_AVP_CODE_FILTER_ID:
case OGS_DIAM_GY_AVP_CODE_RESTRICTION_FILTER_RULE:
*/
default:
ogs_error("Not implemented(%d)", hdr->avp_code);
break;
}
fd_msg_browse(avpch2, MSG_BRW_NEXT, &avpch2, NULL);
}
if (perror)
*perror = error;
return OGS_OK;
}

View File

@ -1147,7 +1147,9 @@ uint8_t smf_epc_n4_handle_session_deletion_response(
return OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
}
void smf_n4_handle_session_report_request(
/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success,
* other cause value on failure */
uint8_t smf_n4_handle_session_report_request(
smf_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
ogs_pfcp_session_report_request_t *pfcp_req)
{
@ -1185,7 +1187,7 @@ void smf_n4_handle_session_report_request(
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
cause_value, 0);
return;
return cause_value;
}
ogs_assert(sess);
@ -1225,7 +1227,7 @@ void smf_n4_handle_session_report_request(
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED, 0);
return;
return OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED;
}
if (qfi) {
@ -1235,7 +1237,7 @@ void smf_n4_handle_session_report_request(
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
return;
return OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
}
}
} else {
@ -1260,7 +1262,7 @@ void smf_n4_handle_session_report_request(
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
return;
return OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
}
switch (sess->up_cnx_state) {
@ -1332,14 +1334,21 @@ void smf_n4_handle_session_report_request(
sess->gy.reporting_reason =
smf_pfcp_urr_usage_report_trigger2diam_gy_reporting_reason(&rep_trig);
}
switch(smf_use_gy_iface()) {
switch (smf_use_gy_iface()) {
case 1:
smf_gy_send_ccr(sess, pfcp_xact,
OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST);
if (!sess->gy.final_unit) {
smf_gy_send_ccr(sess, pfcp_xact,
OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST);
} else {
ogs_debug("[%s:%s] Rx PFCP report after Gy Final Unit Indication",
smf_ue->imsi_bcd, sess->session.name);
/* This effectively triggers session release: */
cause_value = OGS_PFCP_CAUSE_NO_RESOURCES_AVAILABLE;
}
break;
case -1:
ogs_error("No Gy Diameter Peer");
/* TODO: terminate connection */
cause_value = OGS_PFCP_CAUSE_NO_RESOURCES_AVAILABLE;
break;
/* default: continue below */
}
@ -1379,4 +1388,5 @@ void smf_n4_handle_session_report_request(
0));
}
}
return cause_value;
}

View File

@ -47,7 +47,7 @@ uint8_t smf_epc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_response_t *rsp);
void smf_n4_handle_session_report_request(
uint8_t smf_n4_handle_session_report_request(
smf_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
ogs_pfcp_session_report_request_t *pfcp_req);

View File

@ -370,8 +370,14 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE:
if (!message->h.seid_presence) ogs_error("No SEID");
smf_n4_handle_session_report_request(
sess, xact, &message->pfcp_session_report_request);
if (!sess) {
ogs_error("No Session");
ogs_pfcp_send_error_message(xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
break;
}
ogs_fsm_dispatch(&sess->sm, e);
break;
default:

View File

@ -727,6 +727,7 @@ bool udr_nudr_dr_handle_subscription_provisioned(
goto cleanup;
};
ogs_assert(subscription_data.num_of_slice);
slice_data = ogs_slice_find_by_s_nssai(
subscription_data.slice, subscription_data.num_of_slice,
&recvmsg->param.s_nssai);
@ -1136,6 +1137,7 @@ bool udr_nudr_dr_handle_policy_data(
goto cleanup;
}
ogs_assert(subscription_data.num_of_slice);
slice_data = ogs_slice_find_by_s_nssai(
subscription_data.slice, subscription_data.num_of_slice,
&recvmsg->param.s_nssai);

View File

@ -1862,6 +1862,120 @@ static void issues_2287_v264_func(abts_case *tc, void *data)
test_ue_remove_all();
}
#if 0 /* Deprecated to resolve issue #3131 */
static void pull_3122_v270_func(abts_case *tc, void *data)
{
int rv;
ogs_socknode_t *s1ap;
ogs_socknode_t *gtpu;
ogs_pkbuf_t *emmbuf;
ogs_pkbuf_t *esmbuf;
ogs_pkbuf_t *sendbuf;
ogs_pkbuf_t *recvbuf;
ogs_s1ap_message_t message;
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
test_ue_t *test_ue = NULL;
test_sess_t *sess = NULL;
test_bearer_t *bearer = NULL;
uint32_t enb_ue_s1ap_id;
uint64_t mme_ue_s1ap_id;
bson_t *doc = NULL;
/* Setup Test UE & Session Context */
memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci));
mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI;
mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI;
mobile_identity_suci.routing_indicator1 = 0;
mobile_identity_suci.routing_indicator2 = 0xf;
mobile_identity_suci.routing_indicator3 = 0xf;
mobile_identity_suci.routing_indicator4 = 0xf;
mobile_identity_suci.protection_scheme_id = OGS_PROTECTION_SCHEME_NULL;
mobile_identity_suci.home_network_pki_value = 0;
test_ue = test_ue_add_by_suci(&mobile_identity_suci, "3746000006");
ogs_assert(test_ue);
test_ue->e_cgi.cell_id = 0x1079baf0;
test_ue->nas.ksi = 0;
test_ue->nas.value = OGS_NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTACH;
test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca";
sess = test_sess_add_by_apn(test_ue, "internet", OGS_GTP2_RAT_TYPE_EUTRAN);
ogs_assert(sess);
/* eNB connects to MME */
s1ap = tests1ap_client(AF_INET);
ABTS_PTR_NOTNULL(tc, s1ap);
/* eNB connects to SGW */
gtpu = test_gtpu_server(1, AF_INET);
ABTS_PTR_NOTNULL(tc, gtpu);
/* Send S1-Setup Reqeust */
sendbuf = test_s1ap_build_s1_setup_request(
S1AP_ENB_ID_PR_macroENB_ID, 0x54f64);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive S1-Setup Response */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(NULL, recvbuf);
/********** Insert Subscriber in Database */
doc = test_db_new_simple(test_ue);
ABTS_PTR_NOTNULL(tc, doc);
ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc));
/* Send Attach Request */
emmbuf = testemm_build_identity_response(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param));
sendbuf = test_s1ap_build_initial_ue_message(
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive ErrorIndication */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Receive UEContextReleaseCommand */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send UEContextReleaseComplete */
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(300);
/********** Remove Subscriber in Database */
ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue));
/* eNB disonncect from MME */
testenb_s1ap_close(s1ap);
/* eNB disonncect from SGW */
test_gtpu_close(gtpu);
test_ue_remove(test_ue);
}
#endif
abts_suite *test_issues(abts_suite *suite)
{
suite = ADD_SUITE(suite)
@ -1869,6 +1983,9 @@ abts_suite *test_issues(abts_suite *suite)
abts_run_test(suite, issues_1431_func, NULL);
abts_run_test(suite, issues_2287_v263_func, NULL);
abts_run_test(suite, issues_2287_v264_func, NULL);
#if 0 /* Deprecated to resolve issue #3131 */
abts_run_test(suite, pull_3122_v270_func, NULL);
#endif
return suite;
}

View File

@ -2669,7 +2669,7 @@ ogs_pkbuf_t *test_ngap_build_malformed_initial_ue_message(int i)
"000f007300000700 5500034002000026 001d1c0602940a5f 7f5f7e105c000209"
"00007fff00000000 004c4c585f4e5f00 79000f405f7a8a1f 58755ff001940078"
"954e005a40012800 0340025fc0007040 010000ab4021205f 5f5f5f4f3d7fff10"
"de5f5f765f000000 0000000000000000 00000000000000"
"de5f5f765f000000 0000000000000000 00000000000000",
"",
"",

View File

@ -354,11 +354,132 @@ static void test1_func(abts_case *tc, void *data)
test_ue_remove(test_ue);
}
#if 0 /* Deprecated to resolve issue #3131 */
static void pull_3122_v270_func(abts_case *tc, void *data)
{
int rv;
ogs_socknode_t *ngap;
ogs_socknode_t *gtpu;
ogs_pkbuf_t *gmmbuf;
ogs_pkbuf_t *gsmbuf;
ogs_pkbuf_t *nasbuf;
ogs_pkbuf_t *sendbuf;
ogs_pkbuf_t *recvbuf;
ogs_ngap_message_t message;
int i;
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
test_ue_t *test_ue = NULL;
test_sess_t *sess = NULL;
test_bearer_t *qos_flow = NULL;
bson_t *doc = NULL;
/* Setup Test UE & Session Context */
memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci));
mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI;
mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI;
mobile_identity_suci.routing_indicator1 = 0;
mobile_identity_suci.routing_indicator2 = 0xf;
mobile_identity_suci.routing_indicator3 = 0xf;
mobile_identity_suci.routing_indicator4 = 0xf;
mobile_identity_suci.protection_scheme_id = OGS_PROTECTION_SCHEME_NULL;
mobile_identity_suci.home_network_pki_value = 0;
test_ue = test_ue_add_by_suci(&mobile_identity_suci, "0000203190");
ogs_assert(test_ue);
test_ue->nr_cgi.cell_id = 0x40001;
test_ue->nas.registration.tsc = 0;
test_ue->nas.registration.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
test_ue->nas.registration.follow_on_request = 1;
test_ue->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL;
test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca";
/* gNB connects to AMF */
ngap = testngap_client(AF_INET);
ABTS_PTR_NOTNULL(tc, ngap);
/* gNB connects to UPF */
gtpu = test_gtpu_server(1, AF_INET);
ABTS_PTR_NOTNULL(tc, gtpu);
/* Send NG-Setup Reqeust */
sendbuf = testngap_build_ng_setup_request(0x4000, 29);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive NG-Setup Response */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/********** Insert Subscriber in Database */
doc = test_db_new_simple(test_ue);
ABTS_PTR_NOTNULL(tc, doc);
ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc));
/* Send Identity response */
test_ue->ran_ue_ngap_id = 1;
gmmbuf = testgmm_build_identity_response(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf,
NGAP_RRCEstablishmentCause_mo_Signalling, false, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive ErrorIndication */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_ErrorIndication,
test_ue->ngap_procedure_code);
/* Receive UEContextReleaseCommand */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_UEContextRelease,
test_ue->ngap_procedure_code);
/* Send UEContextReleaseComplete */
sendbuf = testngap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(300);
/********** Remove Subscriber in Database */
ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue));
/* gNB disonncect from UPF */
testgnb_gtpu_close(gtpu);
/* gNB disonncect from AMF */
testgnb_ngap_close(ngap);
/* Clear Test UE Context */
test_ue_remove(test_ue);
}
#endif
abts_suite *test_identity(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test1_func, NULL);
#if 0 /* Deprecated to resolve issue #3131 */
abts_run_test(suite, pull_3122_v270_func, NULL);
#endif
return suite;
}